From 8bade533357478ea91f4cefcf31b3637c4e3de81 Mon Sep 17 00:00:00 2001 From: Parijat Bhatt Date: Wed, 17 Aug 2022 16:23:37 -0700 Subject: [PATCH] adding support TOTP MFA --- common/api-review/auth.api.md | 5 ++ packages/auth/src/mfa/assertions/totp.ts | 78 +++++++++++++++++++ packages/auth/src/model/enum_maps.ts | 3 +- packages/auth/src/model/public_types.ts | 12 ++- .../platform_browser/mfa/assertions/totp.ts | 50 ++++++++++++ 5 files changed, 146 insertions(+), 2 deletions(-) create mode 100644 packages/auth/src/mfa/assertions/totp.ts create mode 100644 packages/auth/src/platform_browser/mfa/assertions/totp.ts diff --git a/common/api-review/auth.api.md b/common/api-review/auth.api.md index 47fc7ec5417..db60c726333 100644 --- a/common/api-review/auth.api.md +++ b/common/api-review/auth.api.md @@ -361,6 +361,7 @@ export class FacebookAuthProvider extends BaseOAuthProvider { // @public export const FactorId: { readonly PHONE: "phone"; + readonly TOTP: "totp"; }; // @public @@ -745,6 +746,10 @@ export function signInWithRedirect(auth: Auth, provider: AuthProvider, resolver? // @public export function signOut(auth: Auth): Promise; +// @public +export interface TotpMultiFactorAssertion extends MultiFactorAssertion { +} + // @public export class TwitterAuthProvider extends BaseOAuthProvider { constructor(); diff --git a/packages/auth/src/mfa/assertions/totp.ts b/packages/auth/src/mfa/assertions/totp.ts new file mode 100644 index 00000000000..8fb437cef35 --- /dev/null +++ b/packages/auth/src/mfa/assertions/totp.ts @@ -0,0 +1,78 @@ +/** + * @license + * Copyright 2022 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 { TotpSecret } from '../../platform_browser/mfa/assertions/totp'; +import { + TotpMultiFactorAssertion, + MultiFactorSession, + FactorId +} from '../../model/public_types'; +/** + * Provider for generating a {@link TotpMultiFactorAssertion}. + * + * @public + */ +export class TotpMultiFactorGenerator { + /** + * Provides a {@link TotpMultiFactorAssertion} to confirm ownership of + * the totp(Time-based One Time Password) second factor. + * This assertion is used to complete enrollment in TOTP second factor. + * + * @param secret {@link TotpSecret}. + * @param oneTimePassword One-time password from TOTP App. + * @returns A {@link TotpMultiFactorAssertion} which can be used with + * {@link MultiFactorUser.enroll}. + */ + static assertionForEnrollment( + _secret: TotpSecret, + _oneTimePassword: string + ): TotpMultiFactorAssertion { + throw new Error('Unimplemented'); + } + /** + * Provides a {@link TotpMultiFactorAssertion} to confirm ownership of the totp second factor. + * This assertion is used to complete signIn with TOTP as the second factor. + * + * @param enrollmentId identifies the enrolled TOTP second factor. + * @param otp One-time password from TOTP App. + * @returns A {@link TotpMultiFactorAssertion} which can be used with + * {@link MultiFactorResolver.resolveSignIn}. + */ + static assertionForSignIn( + _enrollmentId: string, + _otp: string + ): TotpMultiFactorAssertion { + throw new Error('Unimplemented'); + } + /** + * Returns a promise to {@link TOTPSecret} which contains the TOTP shared secret key and other parameters. + * Creates a TOTP secret as part of enrolling a TOTP second factor. + * Used for generating a QRCode URL or inputting into a TOTP App. + * This method uses the auth instance corresponding to the user in the multiFactorSession. + * + * @param session A link to {@MultiFactorSession}. + * @returns A promise to {@link TotpSecret}. + */ + static async generateSecret( + _session: MultiFactorSession + ): Promise { + throw new Error('Unimplemented'); + } + /** + * The identifier of the TOTP second factor: `totp`. + */ + static FACTOR_ID = FactorId.TOTP; +} diff --git a/packages/auth/src/model/enum_maps.ts b/packages/auth/src/model/enum_maps.ts index 4d3e3f4a59c..e0ffec60b7e 100644 --- a/packages/auth/src/model/enum_maps.ts +++ b/packages/auth/src/model/enum_maps.ts @@ -22,7 +22,8 @@ */ export const FactorId = { /** Phone as second factor */ - PHONE: 'phone' + PHONE: 'phone', + TOTP: 'totp' } as const; /** diff --git a/packages/auth/src/model/public_types.ts b/packages/auth/src/model/public_types.ts index ea6dc857962..029d0cc0cfb 100644 --- a/packages/auth/src/model/public_types.ts +++ b/packages/auth/src/model/public_types.ts @@ -543,7 +543,8 @@ export interface AuthProvider { */ export const enum FactorId { /** Phone as second factor */ - PHONE = 'phone' + PHONE = 'phone', + TOTP = 'totp' } /** @@ -1227,3 +1228,12 @@ export interface Dependencies { */ errorMap?: AuthErrorMap; } + +/** + * The class for asserting ownership of a totp second factor. Provided by + * {@link TotpMultiFactorGenerator.assertion}. + * + * @public + */ + +export interface TotpMultiFactorAssertion extends MultiFactorAssertion {} diff --git a/packages/auth/src/platform_browser/mfa/assertions/totp.ts b/packages/auth/src/platform_browser/mfa/assertions/totp.ts new file mode 100644 index 00000000000..d62813d8d44 --- /dev/null +++ b/packages/auth/src/platform_browser/mfa/assertions/totp.ts @@ -0,0 +1,50 @@ +/** + * @license + * Copyright 2022 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. + */ + +/** + * Stores the shared secret key and other parameters to generate time-based OTPs. + * Implements methods to retrieve the shared secret key, generate a QRCode URL. + * @public + */ +export class TotpSecret { + /** + * Constructor for TotpSecret. + * @param secretKey - Shared secret key/seed used for enrolling in TOTP MFA and generating otps. + * @param hashingAlgorithm - Hashing algorithm used. + * @param codeLength - Length of the one-time passwords to be generated. + * @param codeIntervalSeconds - The interval (in seconds) when the OTP codes should change. + */ + constructor( + readonly secretKey: string, + readonly hashingAlgorithm: string, + readonly codeLength: number, + readonly codeIntervalSeconds: number + ) {} + /** + * Returns a QRCode URL as described in + * https://github.com/google/google-authenticator/wiki/Key-Uri-Format + * This can be displayed to the user as a QRCode to be scanned into a TOTP App like Google Authenticator. + * If the optional parameters are unspecified, an accountName of ": and issuer of are used. + * + * @param accountName the name of the account/app along with a user identifier. + * @param issuer issuer of the TOTP(likely the app name). + * @returns A QRCode URL string. + */ + generateQrCodeUrl(_accountName?: string, _issuer?: string): string { + throw new Error('Unimplemented'); + } +}