UNPKG

voluptasmollitia

Version:
140 lines (128 loc) 4.66 kB
/** * @license * Copyright 2020 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 { Auth, MultiFactorResolver, OperationType, UserCredential, MultiFactorError } from '../model/public_types'; import { _castAuth } from '../core/auth/auth_impl'; import { AuthErrorCode } from '../core/errors'; import { UserCredentialImpl } from '../core/user/user_credential_impl'; import { _assert, _fail } from '../core/util/assert'; import { UserCredentialInternal } from '../model/user'; import { MultiFactorAssertionImpl } from './mfa_assertion'; import { MultiFactorError as MultiFactorErrorInternal } from './mfa_error'; import { MultiFactorInfoImpl } from './mfa_info'; import { MultiFactorSessionImpl } from './mfa_session'; import { getModularInstance } from '@firebase/util'; export class MultiFactorResolverImpl implements MultiFactorResolver { private constructor( readonly session: MultiFactorSessionImpl, readonly hints: MultiFactorInfoImpl[], private readonly signInResolver: ( assertion: MultiFactorAssertionImpl ) => Promise<UserCredentialInternal> ) {} /** @internal */ static _fromError( authExtern: Auth, error: MultiFactorErrorInternal ): MultiFactorResolverImpl { const auth = _castAuth(authExtern); const hints = (error.serverResponse.mfaInfo || []).map(enrollment => MultiFactorInfoImpl._fromServerResponse(auth, enrollment) ); _assert( error.serverResponse.mfaPendingCredential, auth, AuthErrorCode.INTERNAL_ERROR ); const session = MultiFactorSessionImpl._fromMfaPendingCredential( error.serverResponse.mfaPendingCredential ); return new MultiFactorResolverImpl( session, hints, async ( assertion: MultiFactorAssertionImpl ): Promise<UserCredentialInternal> => { const mfaResponse = await assertion._process(auth, session); // Clear out the unneeded fields from the old login response delete error.serverResponse.mfaInfo; delete error.serverResponse.mfaPendingCredential; // Use in the new token & refresh token in the old response const idTokenResponse = { ...error.serverResponse, idToken: mfaResponse.idToken, refreshToken: mfaResponse.refreshToken }; // TODO: we should collapse this switch statement into UserCredentialImpl._forOperation and have it support the SIGN_IN case switch (error.operationType) { case OperationType.SIGN_IN: const userCredential = await UserCredentialImpl._fromIdTokenResponse( auth, error.operationType, idTokenResponse ); await auth._updateCurrentUser(userCredential.user); return userCredential; case OperationType.REAUTHENTICATE: _assert(error.user, auth, AuthErrorCode.INTERNAL_ERROR); return UserCredentialImpl._forOperation( error.user, error.operationType, idTokenResponse ); default: _fail(auth, AuthErrorCode.INTERNAL_ERROR); } } ); } async resolveSignIn( assertionExtern: MultiFactorAssertionImpl ): Promise<UserCredential> { const assertion = assertionExtern as MultiFactorAssertionImpl; return this.signInResolver(assertion); } } /** * Provides a {@link MultiFactorResolver} suitable for completion of a * multi-factor flow. * * @param auth - The auth instance. * @param error - The {@link MultiFactorError} raised during a sign-in, or * reauthentication operation. * * @public */ export function getMultiFactorResolver( auth: Auth, error: MultiFactorError ): MultiFactorResolver { const authModular = getModularInstance(auth); const errorInternal = error as MultiFactorErrorInternal; _assert(error.operationType, authModular, AuthErrorCode.ARGUMENT_ERROR); _assert( errorInternal.serverResponse?.mfaPendingCredential, authModular, AuthErrorCode.ARGUMENT_ERROR ); return MultiFactorResolverImpl._fromError(authModular, errorInternal); }