UNPKG

voluptasmollitia

Version:
165 lines (155 loc) 4.93 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 { extractQuerystring, querystringDecode } from '@firebase/util'; import { ActionCodeOperation } from '../model/public_types'; import { AuthErrorCode } from './errors'; import { _assert } from './util/assert'; /** * Enums for fields in URL query string. * * @enum {string} */ const enum QueryField { API_KEY = 'apiKey', CODE = 'oobCode', CONTINUE_URL = 'continueUrl', LANGUAGE_CODE = 'languageCode', MODE = 'mode', TENANT_ID = 'tenantId' } /** * Maps the mode string in action code URL to Action Code Info operation. * * @param mode */ function parseMode(mode: string | null): ActionCodeOperation | null { switch (mode) { case 'recoverEmail': return ActionCodeOperation.RECOVER_EMAIL; case 'resetPassword': return ActionCodeOperation.PASSWORD_RESET; case 'signIn': return ActionCodeOperation.EMAIL_SIGNIN; case 'verifyEmail': return ActionCodeOperation.VERIFY_EMAIL; case 'verifyAndChangeEmail': return ActionCodeOperation.VERIFY_AND_CHANGE_EMAIL; case 'revertSecondFactorAddition': return ActionCodeOperation.REVERT_SECOND_FACTOR_ADDITION; default: return null; } } /** * Helper to parse FDL links * * @param url */ function parseDeepLink(url: string): string { const link = querystringDecode(extractQuerystring(url))['link']; // Double link case (automatic redirect). const doubleDeepLink = link ? querystringDecode(extractQuerystring(link))['deep_link_id'] : null; // iOS custom scheme links. const iOSDeepLink = querystringDecode(extractQuerystring(url))[ 'deep_link_id' ]; const iOSDoubleDeepLink = iOSDeepLink ? querystringDecode(extractQuerystring(iOSDeepLink))['link'] : null; return iOSDoubleDeepLink || iOSDeepLink || doubleDeepLink || link || url; } /** * A utility class to parse email action URLs such as password reset, email verification, * email link sign in, etc. * * @public */ export class ActionCodeURL { /** * The API key of the email action link. */ readonly apiKey: string; /** * The action code of the email action link. */ readonly code: string; /** * The continue URL of the email action link. Null if not provided. */ readonly continueUrl: string | null; /** * The language code of the email action link. Null if not provided. */ readonly languageCode: string | null; /** * The action performed by the email action link. It returns from one of the types from * {@link ActionCodeInfo} */ readonly operation: ActionCodeOperation; /** * The tenant ID of the email action link. Null if the email action is from the parent project. */ readonly tenantId: string | null; /** * @param actionLink - The link from which to extract the URL. * @returns The ActionCodeURL object, or null if the link is invalid. * * @internal */ constructor(actionLink: string) { const searchParams = querystringDecode(extractQuerystring(actionLink)); const apiKey = searchParams[QueryField.API_KEY] ?? null; const code = searchParams[QueryField.CODE] ?? null; const operation = parseMode(searchParams[QueryField.MODE] ?? null); // Validate API key, code and mode. _assert(apiKey && code && operation, AuthErrorCode.ARGUMENT_ERROR); this.apiKey = apiKey; this.operation = operation; this.code = code; this.continueUrl = searchParams[QueryField.CONTINUE_URL] ?? null; this.languageCode = searchParams[QueryField.LANGUAGE_CODE] ?? null; this.tenantId = searchParams[QueryField.TENANT_ID] ?? null; } /** * Parses the email action link string and returns an {@link ActionCodeURL} if the link is valid, * otherwise returns null. * * @param link - The email action link string. * @returns The ActionCodeURL object, or null if the link is invalid. * * @public */ static parseLink(link: string): ActionCodeURL | null { const actionLink = parseDeepLink(link); try { return new ActionCodeURL(actionLink); } catch { return null; } } } /** * Parses the email action link string and returns an {@link ActionCodeURL} if * the link is valid, otherwise returns null. * * @public */ export function parseActionCodeURL(link: string): ActionCodeURL | null { return ActionCodeURL.parseLink(link); }