import { SignInResult } from "./signin-result" ; import { SignInProvider } from "./signin-provider" ; export class GoogleProvider implements SignInProvider { static readonly apiUrl = "https://apis.google.com/js/api:client.js" ; constructor ( private clientId ) { } signIn ( ) { return this . loadDependencies ( ) . then ( ( ) => this . signInWithGoogleAuth2 ( ) ) ; } loadDependencies ( ) { return this . appendGoogleScript ( ) . then ( ( ) => this . loadAuth ( ) ) ; } private appendGoogleScript ( ) { const gapiLoad = window . gapi ?. load ; if ( ! gapiLoad ) { return new Promise < void > ( ( resolve , reject ) => { const scriptEl = window . document . createElement ( "script" ) ; scriptEl . async = true ; scriptEl . src = GoogleProvider . apiUrl ; scriptEl . onload = ( ) => resolve ( ) ; scriptEl . onerror = ( error ) => reject ( { message : "Error loading Google Platform library" , error : error } ) ; window . document . head . appendChild ( scriptEl ) ; } ) ; } return Promise . resolve ( ) ; } private loadAuth ( ) { if ( ! window . gapi || ! window . gapi . load ) { return Promise . reject ( "Couldn't find gapi.load" ) ; } if ( window . gapi . auth2 ) { return Promise . resolve ( ) ; } return new Promise < void > ( resolve => window . gapi . load ( "auth2" , ( ) => resolve ( ) ) ) ; } private signInWithGoogleAuth2 ( ) { if ( ! gapi ?. auth2 ) { return Promise . reject ( "gapi.auth2 wasn't loaded" ) ; } const auth = gapi . auth2 . init ( { client_id : this . clientId , cookie_policy : "single_host_origin" } ) ; if ( auth . isSignedIn . get ( ) ) { const user = auth . currentUser . get ( ) ; return Promise . resolve ( this . getSignInResultFromUser ( user ) ) ; } return auth . signIn ( ) . then ( user => this . getSignInResultFromUser ( user ) ) ; } private getSignInResultFromUser ( user ) { const profile = user . getBasicProfile ( ) ; const authResponse = user . getAuthResponse ( true ) ; return { email : profile . getEmail ( ) , name : profile . getName ( ) , imageUrl : profile . getImageUrl ( ) , accessToken : authResponse ?. access_token , accessTokenExpiration : new Date ( authResponse . expires_at ) , provider : "Google" , error : null , providerData : user } ; } }