UNPKG

voluptasmollitia

Version:
157 lines (146 loc) 4.75 kB
/** * @license * Copyright 2019 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { AdditionalUserInfo, ProviderId, UserCredential } from '../../model/public_types'; import { IdTokenResponse, IdTokenResponseKind } from '../../model/id_token'; import { _parseToken } from './id_token_result'; import { UserCredentialInternal } from '../../model/user'; /** * Parse the `AdditionalUserInfo` from the ID token response. * */ export function _fromIdTokenResponse( idTokenResponse?: IdTokenResponse ): AdditionalUserInfo | null { if (!idTokenResponse) { return null; } const { providerId } = idTokenResponse; const profile = idTokenResponse.rawUserInfo ? JSON.parse(idTokenResponse.rawUserInfo) : {}; const isNewUser = idTokenResponse.isNewUser || idTokenResponse.kind === IdTokenResponseKind.SignupNewUser; if (!providerId && idTokenResponse?.idToken) { const signInProvider = _parseToken(idTokenResponse.idToken)?.firebase?.[ 'sign_in_provider' ]; if (signInProvider) { const filteredProviderId = signInProvider !== ProviderId.ANONYMOUS && signInProvider !== ProviderId.CUSTOM ? (signInProvider as ProviderId) : null; // Uses generic class in accordance with the legacy SDK. return new GenericAdditionalUserInfo(isNewUser, filteredProviderId); } } if (!providerId) { return null; } switch (providerId) { case ProviderId.FACEBOOK: return new FacebookAdditionalUserInfo(isNewUser, profile); case ProviderId.GITHUB: return new GithubAdditionalUserInfo(isNewUser, profile); case ProviderId.GOOGLE: return new GoogleAdditionalUserInfo(isNewUser, profile); case ProviderId.TWITTER: return new TwitterAdditionalUserInfo( isNewUser, profile, idTokenResponse.screenName || null ); case ProviderId.CUSTOM: case ProviderId.ANONYMOUS: return new GenericAdditionalUserInfo(isNewUser, null); default: return new GenericAdditionalUserInfo(isNewUser, providerId, profile); } } class GenericAdditionalUserInfo implements AdditionalUserInfo { constructor( readonly isNewUser: boolean, readonly providerId: ProviderId | string | null, readonly profile: Record<string, unknown> = {} ) {} } class FederatedAdditionalUserInfoWithUsername extends GenericAdditionalUserInfo { constructor( isNewUser: boolean, providerId: ProviderId, profile: Record<string, unknown>, readonly username: string | null ) { super(isNewUser, providerId, profile); } } class FacebookAdditionalUserInfo extends GenericAdditionalUserInfo { constructor(isNewUser: boolean, profile: Record<string, unknown>) { super(isNewUser, ProviderId.FACEBOOK, profile); } } class GithubAdditionalUserInfo extends FederatedAdditionalUserInfoWithUsername { constructor(isNewUser: boolean, profile: Record<string, unknown>) { super( isNewUser, ProviderId.GITHUB, profile, typeof profile?.login === 'string' ? profile?.login : null ); } } class GoogleAdditionalUserInfo extends GenericAdditionalUserInfo { constructor(isNewUser: boolean, profile: Record<string, unknown>) { super(isNewUser, ProviderId.GOOGLE, profile); } } class TwitterAdditionalUserInfo extends FederatedAdditionalUserInfoWithUsername { constructor( isNewUser: boolean, profile: Record<string, unknown>, screenName: string | null ) { super(isNewUser, ProviderId.TWITTER, profile, screenName); } } /** * Extracts provider specific {@link AdditionalUserInfo} for the given credential. * * @param userCredential - The user credential. * * @public */ export function getAdditionalUserInfo( userCredential: UserCredential ): AdditionalUserInfo | null { const { user, _tokenResponse } = userCredential as UserCredentialInternal; if (user.isAnonymous && !_tokenResponse) { // Handle the special case where signInAnonymously() gets called twice. // No network call is made so there's nothing to actually fill this in return { providerId: null, isNewUser: false, profile: null }; } return _fromIdTokenResponse(_tokenResponse); }