/**
 * -------------------------------------------------------------------------------------------
 * Copyright (c) Microsoft Corporation.  All Rights Reserved.  Licensed under the MIT License.
 * See License in the project root for license information.
 * -------------------------------------------------------------------------------------------
 */ import { AuthenticationProviderOptions } from '@microsoft/microsoft-graph-client/lib/es/IAuthenticationProviderOptions' ; import { AuthenticationParameters , Configuration , UserAgentApplication } from 'msal' ; import { TeamsHelper } from '@microsoft/mgt-element' ; import { LoginType , ProviderState } from '@microsoft/mgt-element' ; import { MsalProvider } from '@microsoft/mgt-msal-provider' ; declare global { interface Window { nativeInterface : any ; } } interface interface AuthParams { type { string } memberof clientId ? : string ; type { string } memberof scopes ? : string ; type { string } memberof loginHint ? : string ; type { Configuration } memberof options ? : Configuration ; } export interface export interface TeamsConfig { type { string } memberof clientId : string ; type { string } memberof authPopupUrl : string ; type { string [ ] } memberof scopes ? : string [ ] ; type { Configuration } memberof msalOptions ? : Configuration ; } export class extends MsalProvider export class TeamsProvider extends MsalProvider { readonly static memberof public static get isAvailable ( ) : boolean { return TeamsHelper . isAvailable ; } static memberof public static get microsoftTeamsLib ( ) : any { return TeamsHelper . microsoftTeamsLib ; } public static set microsoftTeamsLib ( value ) { TeamsHelper . microsoftTeamsLib = value ; } readonly memberof public get name ( ) { return 'MgtTeamsProvider' ; } static returns memberof public static async handleAuth ( ) { const teams = TeamsHelper . microsoftTeamsLib ; if ( ! teams ) { console . error ( 'Make sure you have referenced the Microsoft Teams sdk before using the TeamsProvider' ) ; return ; } teams . initialize ( ) ; if ( sessionStorage . getItem ( this . _sessionStorageLogoutInProgress ) ) { teams . authentication . notifySuccess ( ) ; } const url = new URL ( window . location . href ) ; const isSignOut = url . searchParams . get ( 'signout' ) ; const paramsString = localStorage . getItem ( this . _localStorageParametersKey ) ; let authParams ; if ( paramsString ) { authParams = JSON . parse ( paramsString ) ; } else { authParams = { } ; } if ( ! authParams . clientId ) { teams . authentication . notifyFailure ( 'no clientId provided' ) ; return ; } const scopes = authParams . scopes ? authParams . scopes . split ( ',' ) : null ; const options = authParams . options || { auth : { clientId : authParams . clientId } } ; options . system = options . system || { } ; options . system . loadFrameTimeout = 10000 ; const provider = new MsalProvider ( { clientId : authParams . clientId , options , scopes } ) ; if ( provider . userAgentApplication . urlContainsHash ( window . location . hash ) ) { return ; } const handleProviderState = async ( ) => { if ( provider . state === ProviderState . SignedOut ) { if ( isSignOut ) { teams . authentication . notifySuccess ( ) ; return ; } if ( ! sessionStorage . getItem ( this . _sessionStorageLoginInProgress ) ) { sessionStorage . setItem ( this . _sessionStorageLoginInProgress , 'true' ) ; provider . login ( { loginHint : authParams . loginHint , scopes : scopes || provider . scopes } ) ; } } else if ( provider . state === ProviderState . SignedIn ) { if ( isSignOut ) { sessionStorage . setItem ( this . _sessionStorageLogoutInProgress , 'true' ) ; await provider . logout ( ) ; return ; } try { const accessToken = await provider . getAccessTokenForScopes ( ... provider . scopes ) ; teams . authentication . notifySuccess ( accessToken ) ; } catch ( e ) { teams . authentication . notifyFailure ( e ) ; } } } ; provider . onStateChanged ( handleProviderState ) ; handleProviderState ( ) ; } private static _localStorageParametersKey = 'msg-teamsprovider-auth-parameters' ; private static _sessionStorageLoginInProgress = 'msg-teamsprovider-login-in-progress' ; private static _sessionStorageLogoutInProgress = 'msg-teamsprovider-logout-in-progress' ; private teamsContext ; private _authPopupUrl : string ; private _msalOptions : Configuration ; constructor ( config ) { super ( { clientId : config . clientId , loginType : LoginType . Redirect , options : config . msalOptions , scopes : config . scopes } ) ; this . _msalOptions = config . msalOptions ; this . _authPopupUrl = config . authPopupUrl ; const teams = TeamsHelper . microsoftTeamsLib ; teams . initialize ( ) ; } returns { Promise < void > } memberof public async login ( ) { this . setState ( ProviderState . Loading ) ; const teams = TeamsHelper . microsoftTeamsLib ; return new Promise ( ( resolve , reject ) => { teams . getContext ( context => { this . teamsContext = context ; const authParams = { clientId : this . clientId , loginHint : context . loginHint , options : this . _msalOptions , scopes : this . scopes . join ( ',' ) } ; localStorage . setItem ( TeamsProvider . _localStorageParametersKey , JSON . stringify ( authParams ) ) ; const url = new URL ( this . _authPopupUrl , new URL ( window . location . href ) ) ; teams . authentication . authenticate ( { failureCallback : reason => { this . setState ( ProviderState . SignedOut ) ; reject ( ) ; } , successCallback : result => { this . trySilentSignIn ( ) ; resolve ( ) ; } , url : url . href } ) ; } ) ; } ) ; } returns { Promise < void > } memberof public async logout ( ) { const teams = TeamsHelper . microsoftTeamsLib ; return new Promise ( ( resolve , reject ) => { teams . getContext ( context => { this . teamsContext = context ; const url = new URL ( this . _authPopupUrl , new URL ( window . location . href ) ) ; url . searchParams . append ( 'signout' , 'true' ) ; teams . authentication . authenticate ( { failureCallback : reason => { this . trySilentSignIn ( ) ; reject ( ) ; } , successCallback : result => { this . trySilentSignIn ( ) ; resolve ( ) ; } , url : url . href } ) ; } ) ; } ) ; } param { AuthenticationProviderOptions } options returns { Promise < string > } memberof public async getAccessToken ( options ) { if ( ! this . teamsContext && TeamsHelper . microsoftTeamsLib ) { const teams = TeamsHelper . microsoftTeamsLib ; teams . initialize ( ) ; this . teamsContext = await teams . getContext ( ) ; } const scopes = options ? options . scopes || this . scopes : this . scopes ; const accessTokenRequest = { scopes } ; if ( this . teamsContext && this . teamsContext . loginHint ) { accessTokenRequest . loginHint = this . teamsContext . loginHint ; } try { const response = await this . userAgentApplication . acquireTokenSilent ( accessTokenRequest ) ; return response . accessToken ; } catch ( e ) { if ( this . requiresInteraction ( e ) ) { return null ; } else { throw e ; } } } }