From df2db270b71481142e56d88f9bb292022d919978 Mon Sep 17 00:00:00 2001 From: Pragati Date: Wed, 8 Nov 2023 09:59:03 -0800 Subject: [PATCH 1/5] add support for importing users with totp second factor --- src/auth/auth-api-request.ts | 34 +++++++++++++++++++++++++++++++-- src/auth/auth-config.ts | 9 ++++++++- src/auth/user-import-builder.ts | 5 +++++ src/utils/error.ts | 4 ++++ 4 files changed, 49 insertions(+), 3 deletions(-) diff --git a/src/auth/auth-api-request.ts b/src/auth/auth-api-request.ts index 9fd535777c..7fa261cdfe 100644 --- a/src/auth/auth-api-request.ts +++ b/src/auth/auth-api-request.ts @@ -28,7 +28,7 @@ import * as utils from '../utils/index'; import { UserImportOptions, UserImportRecord, UserImportResult, - UserImportBuilder, AuthFactorInfo, convertMultiFactorInfoToServerFormat, + UserImportBuilder, AuthFactorInfo, convertMultiFactorInfoToServerFormat, TotpInfoResponse, } from './user-import-builder'; import { ActionCodeSettings, ActionCodeSettingsBuilder } from './action-code-settings-builder'; import { Tenant, TenantServerResponse, CreateTenantRequest, UpdateTenantRequest } from './tenant'; @@ -43,6 +43,7 @@ import { SAMLUpdateAuthProviderRequest } from './auth-config'; import { ProjectConfig, ProjectConfigServerResponse, UpdateProjectConfigRequest } from './project-config'; +import {TotpInfo} from './user-record'; /** Firebase Auth request header. */ const FIREBASE_AUTH_HEADER = { @@ -251,6 +252,7 @@ function validateAuthFactorInfo(request: AuthFactorInfo): void { displayName: true, phoneInfo: true, enrolledAt: true, + totpInfo: true, }; // Remove unsupported keys from the original request. for (const key in request) { @@ -260,7 +262,7 @@ function validateAuthFactorInfo(request: AuthFactorInfo): void { } // No enrollment ID is available for signupNewUser. Use another identifier. const authFactorInfoIdentifier = - request.mfaEnrollmentId || request.phoneInfo || JSON.stringify(request); + request.mfaEnrollmentId || request.phoneInfo || request.totpInfo || JSON.stringify(request); // Enrollment uid may or may not be specified for update operations. if (typeof request.mfaEnrollmentId !== 'undefined' && !validator.isNonEmptyString(request.mfaEnrollmentId)) { @@ -293,6 +295,8 @@ function validateAuthFactorInfo(request: AuthFactorInfo): void { `The second factor "phoneNumber" for "${authFactorInfoIdentifier}" must be a non-empty ` + 'E.164 standard compliant identifier string.'); } + } else if(typeof request.totpInfo !== 'undefined') { + validateTotpInfo(request.totpInfo); } else { // Invalid second factor. For example, a phone second factor may have been provided without // a phone number. A TOTP based second factor may require a secret key, etc. @@ -302,6 +306,32 @@ function validateAuthFactorInfo(request: AuthFactorInfo): void { } } +/** + * Validates an TotpInfoResponse object. All unsupported parameters + * are removed from the original request. If an invalid field is passed + * an error is thrown. + * + * @param request - The TotpInfoResponse request object. + */ +function validateTotpInfo(request: TotpInfoResponse): void { + const validKeys = { + sharedSecretKey: true, + }; + // Remove unsupported keys from the original request. + for (const key in request) { + if (!(key in validKeys)) { + delete request[key]; + } + } + if (typeof request.sharedSecretKey !== 'undefined' && + !validator.isString(request.sharedSecretKey)) { + throw new FirebaseAuthError( + AuthClientErrorCode.INVALID_SHARED_SECRET_KEY, + `"totpInfo.sharedSecretKey" must be a valid string.`, + ); + } +} + /** * Validates a providerUserInfo object. All unsupported parameters diff --git a/src/auth/auth-config.ts b/src/auth/auth-config.ts index 28ee595c46..e0e3fb3b16 100644 --- a/src/auth/auth-config.ts +++ b/src/auth/auth-config.ts @@ -93,11 +93,18 @@ export interface UpdatePhoneMultiFactorInfoRequest extends BaseUpdateMultiFactor phoneNumber: string; } +export interface UpdateTotpMultiFactorInfoRequest extends BaseUpdateMultiFactorInfoRequest { + totpInfo: TotpInfo; +} + +export interface TotpInfo { + sharedSecretKey: string; +} /** * Type representing the properties of a user-enrolled second factor * for an `UpdateRequest`. */ -export type UpdateMultiFactorInfoRequest = | UpdatePhoneMultiFactorInfoRequest; +export type UpdateMultiFactorInfoRequest = | UpdatePhoneMultiFactorInfoRequest | UpdateTotpMultiFactorInfoRequest; /** * The multi-factor related user settings for create operations. diff --git a/src/auth/user-import-builder.ts b/src/auth/user-import-builder.ts index 23e4e5aba3..0218c6eeca 100644 --- a/src/auth/user-import-builder.ts +++ b/src/auth/user-import-builder.ts @@ -262,9 +262,14 @@ export interface AuthFactorInfo { displayName?: string; phoneInfo?: string; enrolledAt?: string; + totpInfo?: TotpInfoResponse; [key: string]: any; } +export interface TotpInfoResponse { + sharedSecretKey?: string; + [key: string]: any; +} /** UploadAccount endpoint request user interface. */ interface UploadAccountUser { diff --git a/src/utils/error.ts b/src/utils/error.ts index cdb7faef05..48365275aa 100644 --- a/src/utils/error.ts +++ b/src/utils/error.ts @@ -439,6 +439,10 @@ export class AuthClientErrorCode { code: 'invalid-display-name', message: 'The displayName field must be a valid string.', }; + public static INVALID_SHARED_SECRET_KEY = { + code: 'invalid-shared-secret-key', + message: 'The sharedSecretKey field must be a valid string.', + }; public static INVALID_DYNAMIC_LINK_DOMAIN = { code: 'invalid-dynamic-link-domain', message: 'The provided dynamic link domain is not configured or authorized ' + From 40f91803f9275fb9bf80e353b227b4ada586bf61 Mon Sep 17 00:00:00 2001 From: Pragati Date: Wed, 8 Nov 2023 13:40:04 -0800 Subject: [PATCH 2/5] adding unit tests --- src/auth/auth-api-request.ts | 1 - src/auth/user-import-builder.ts | 29 ++++++++++++++++-- test/unit/auth/user-import-builder.spec.ts | 34 +++++++++++++++++++++- 3 files changed, 60 insertions(+), 4 deletions(-) diff --git a/src/auth/auth-api-request.ts b/src/auth/auth-api-request.ts index 7fa261cdfe..93790ede3e 100644 --- a/src/auth/auth-api-request.ts +++ b/src/auth/auth-api-request.ts @@ -43,7 +43,6 @@ import { SAMLUpdateAuthProviderRequest } from './auth-config'; import { ProjectConfig, ProjectConfigServerResponse, UpdateProjectConfigRequest } from './project-config'; -import {TotpInfo} from './user-record'; /** Firebase Auth request header. */ const FIREBASE_AUTH_HEADER = { diff --git a/src/auth/user-import-builder.ts b/src/auth/user-import-builder.ts index 0218c6eeca..740cae439b 100644 --- a/src/auth/user-import-builder.ts +++ b/src/auth/user-import-builder.ts @@ -20,7 +20,7 @@ import * as utils from '../utils'; import * as validator from '../utils/validator'; import { AuthClientErrorCode, FirebaseAuthError } from '../utils/error'; import { - UpdateMultiFactorInfoRequest, UpdatePhoneMultiFactorInfoRequest, MultiFactorUpdateSettings + UpdateMultiFactorInfoRequest, UpdatePhoneMultiFactorInfoRequest, MultiFactorUpdateSettings, UpdateTotpMultiFactorInfoRequest } from './auth-config'; export type HashAlgorithmType = 'SCRYPT' | 'STANDARD_SCRYPT' | 'HMAC_SHA512' | @@ -355,6 +355,23 @@ export function convertMultiFactorInfoToServerFormat(multiFactorInfo: UpdateMult } } return authFactorInfo; + } else if(isTotpFactor(multiFactorInfo)) { + // If any required field is missing or invalid, validation will still fail later. + const authFactorInfo: AuthFactorInfo = { + mfaEnrollmentId: multiFactorInfo.uid, + displayName: multiFactorInfo.displayName, + // Required for all phone second factors. + totpInfo: { + sharedSecretKey: multiFactorInfo.totpInfo.sharedSecretKey, + }, + enrolledAt, + }; + for (const objKey in authFactorInfo) { + if (typeof authFactorInfo[objKey] === 'undefined') { + delete authFactorInfo[objKey]; + } + } + return authFactorInfo; } else { // Unsupported second factor. throw new FirebaseAuthError( @@ -368,6 +385,11 @@ function isPhoneFactor(multiFactorInfo: UpdateMultiFactorInfoRequest): return multiFactorInfo.factorId === 'phone'; } +function isTotpFactor(multiFactorInfo: UpdateMultiFactorInfoRequest): + multiFactorInfo is UpdateTotpMultiFactorInfoRequest { + return multiFactorInfo.factorId === 'totp'; +} + /** * @param {any} obj The object to check for number field within. * @param {string} key The entry key. @@ -390,6 +412,7 @@ function getNumberField(obj: any, key: string): number { */ function populateUploadAccountUser( user: UserImportRecord, userValidator?: ValidatorFunction): UploadAccountUser { + console.log("USER_IN_PROGRESS= ", user.uid); const result: UploadAccountUser = { localId: user.uid, email: user.email, @@ -443,6 +466,7 @@ function populateUploadAccountUser( if (validator.isNonNullObject(user.multiFactor) && validator.isNonEmptyArray(user.multiFactor.enrolledFactors)) { user.multiFactor.enrolledFactors.forEach((multiFactorInfo) => { + console.log("MFA_INFO= ", JSON.stringify(multiFactorInfo)); result.mfaInfo!.push(convertMultiFactorInfoToServerFormat(multiFactorInfo)); }); } @@ -495,7 +519,7 @@ export class UserImportBuilder { this.validatedUsers = []; this.userImportResultErrors = []; this.indexMap = {}; - + console.log("USERS_ppl = ", JSON.stringify(users)); this.validatedUsers = this.populateUsers(users, userRequestValidator); this.validatedOptions = this.populateOptions(options, this.requiresHashOptions); } @@ -745,6 +769,7 @@ export class UserImportBuilder { const populatedUsers: UploadAccountUser[] = []; users.forEach((user, index) => { try { + console.log("user uid= ", user.uid); const result = populateUploadAccountUser(user, userValidator); if (typeof result.passwordHash !== 'undefined') { this.requiresHashOptions = true; diff --git a/test/unit/auth/user-import-builder.spec.ts b/test/unit/auth/user-import-builder.spec.ts index 859265a03a..1bec9a151a 100644 --- a/test/unit/auth/user-import-builder.spec.ts +++ b/test/unit/auth/user-import-builder.spec.ts @@ -110,6 +110,23 @@ describe('UserImportBuilder', () => { phoneNumber: '+16505551000', factorId: 'phone', }, + { + uid: 'enrollmentId3', + enrollmentTime: now.toISOString(), + displayName: 'displayNameTotp', + totpInfo: { + sharedSecretKey: "VIAAQYSO37EKAWB2KAXEQ7EGUMLWI3P4" + }, + factorId: 'totp', + }, + { + uid: 'enrollmentId4', + enrollmentTime: now.toISOString(), + totpInfo: { + sharedSecretKey: "WSUKMEVTQ62EUBF37F2R466ZVLNFL3IF" + }, + factorId: 'totp', + }, ], }, }, @@ -163,6 +180,21 @@ describe('UserImportBuilder', () => { mfaEnrollmentId: 'enrolledSecondFactor2', phoneInfo: '+16505551000', }, + { + mfaEnrollmentId: 'enrollmentId3', + enrolledAt: now.toISOString(), + displayName: 'displayNameTotp', + totpInfo: { + sharedSecretKey: "VIAAQYSO37EKAWB2KAXEQ7EGUMLWI3P4" + } + }, + { + mfaEnrollmentId: 'enrollmentId4', + enrolledAt: now.toISOString(), + totpInfo: { + sharedSecretKey: "WSUKMEVTQ62EUBF37F2R466ZVLNFL3IF" + } + }, ], }, ]; @@ -825,7 +857,7 @@ describe('UserImportBuilder', () => { uid: 'enrollmentId2', secret: 'SECRET', displayName: 'Google Authenticator on personal phone', - factorId: 'totp', + factorId: 'unsupportedFactorId', } as any, ], }, From 86961e4fad9cd67d9ea11d58519223dfe2cdf5d6 Mon Sep 17 00:00:00 2001 From: Pragati Date: Tue, 14 Nov 2023 11:06:04 -0800 Subject: [PATCH 3/5] changes --- etc/firebase-admin.auth.api.md | 10 ++++- src/auth/auth-api-request.ts | 4 +- src/auth/index.ts | 1 + src/auth/user-import-builder.ts | 15 ++++--- test/unit/auth/user-import-builder.spec.ts | 52 +++++++++++----------- 5 files changed, 47 insertions(+), 35 deletions(-) diff --git a/etc/firebase-admin.auth.api.md b/etc/firebase-admin.auth.api.md index 3723abd051..80df3be641 100644 --- a/etc/firebase-admin.auth.api.md +++ b/etc/firebase-admin.auth.api.md @@ -498,7 +498,7 @@ export interface UidIdentifier { export type UpdateAuthProviderRequest = SAMLUpdateAuthProviderRequest | OIDCUpdateAuthProviderRequest; // @public -export type UpdateMultiFactorInfoRequest = UpdatePhoneMultiFactorInfoRequest; +export type UpdateMultiFactorInfoRequest = UpdatePhoneMultiFactorInfoRequest | UpdateTotpMultiFactorInfoRequest; // @public export interface UpdatePhoneMultiFactorInfoRequest extends BaseUpdateMultiFactorInfoRequest { @@ -543,6 +543,14 @@ export interface UpdateTenantRequest { } | null; } +// @public (undocumented) +export interface UpdateTotpMultiFactorInfoRequest extends BaseUpdateMultiFactorInfoRequest { + // Warning: (ae-forgotten-export) The symbol "TotpInfo" needs to be exported by the entry point index.d.ts + // + // (undocumented) + totpInfo: TotpInfo; +} + // @public export type UserIdentifier = UidIdentifier | EmailIdentifier | PhoneIdentifier | ProviderIdentifier; diff --git a/src/auth/auth-api-request.ts b/src/auth/auth-api-request.ts index 93790ede3e..bb15f960bd 100644 --- a/src/auth/auth-api-request.ts +++ b/src/auth/auth-api-request.ts @@ -294,7 +294,7 @@ function validateAuthFactorInfo(request: AuthFactorInfo): void { `The second factor "phoneNumber" for "${authFactorInfoIdentifier}" must be a non-empty ` + 'E.164 standard compliant identifier string.'); } - } else if(typeof request.totpInfo !== 'undefined') { + } else if (typeof request.totpInfo !== 'undefined') { validateTotpInfo(request.totpInfo); } else { // Invalid second factor. For example, a phone second factor may have been provided without @@ -326,7 +326,7 @@ function validateTotpInfo(request: TotpInfoResponse): void { !validator.isString(request.sharedSecretKey)) { throw new FirebaseAuthError( AuthClientErrorCode.INVALID_SHARED_SECRET_KEY, - `"totpInfo.sharedSecretKey" must be a valid string.`, + '"totpInfo.sharedSecretKey" must be a valid string.', ); } } diff --git a/src/auth/index.ts b/src/auth/index.ts index a559a706f8..3e94499304 100644 --- a/src/auth/index.ts +++ b/src/auth/index.ts @@ -103,6 +103,7 @@ export { PasswordPolicyEnforcementState, CustomStrengthOptionsConfig, EmailPrivacyConfig, + UpdateTotpMultiFactorInfoRequest, } from './auth-config'; export { diff --git a/src/auth/user-import-builder.ts b/src/auth/user-import-builder.ts index 740cae439b..d8ab7f3201 100644 --- a/src/auth/user-import-builder.ts +++ b/src/auth/user-import-builder.ts @@ -20,7 +20,8 @@ import * as utils from '../utils'; import * as validator from '../utils/validator'; import { AuthClientErrorCode, FirebaseAuthError } from '../utils/error'; import { - UpdateMultiFactorInfoRequest, UpdatePhoneMultiFactorInfoRequest, MultiFactorUpdateSettings, UpdateTotpMultiFactorInfoRequest + UpdateMultiFactorInfoRequest, UpdatePhoneMultiFactorInfoRequest, MultiFactorUpdateSettings, + UpdateTotpMultiFactorInfoRequest } from './auth-config'; export type HashAlgorithmType = 'SCRYPT' | 'STANDARD_SCRYPT' | 'HMAC_SHA512' | @@ -355,7 +356,9 @@ export function convertMultiFactorInfoToServerFormat(multiFactorInfo: UpdateMult } } return authFactorInfo; - } else if(isTotpFactor(multiFactorInfo)) { + } else if (isTotpFactor(multiFactorInfo)) { + console.log('TOTP_FACTOR_'); + console.log(multiFactorInfo.uid); // If any required field is missing or invalid, validation will still fail later. const authFactorInfo: AuthFactorInfo = { mfaEnrollmentId: multiFactorInfo.uid, @@ -412,7 +415,7 @@ function getNumberField(obj: any, key: string): number { */ function populateUploadAccountUser( user: UserImportRecord, userValidator?: ValidatorFunction): UploadAccountUser { - console.log("USER_IN_PROGRESS= ", user.uid); + console.log('USER_IN_PROGRESS= ', user.uid); const result: UploadAccountUser = { localId: user.uid, email: user.email, @@ -466,7 +469,7 @@ function populateUploadAccountUser( if (validator.isNonNullObject(user.multiFactor) && validator.isNonEmptyArray(user.multiFactor.enrolledFactors)) { user.multiFactor.enrolledFactors.forEach((multiFactorInfo) => { - console.log("MFA_INFO= ", JSON.stringify(multiFactorInfo)); + console.log('MFA_INFO= ', JSON.stringify(multiFactorInfo)); result.mfaInfo!.push(convertMultiFactorInfoToServerFormat(multiFactorInfo)); }); } @@ -519,7 +522,7 @@ export class UserImportBuilder { this.validatedUsers = []; this.userImportResultErrors = []; this.indexMap = {}; - console.log("USERS_ppl = ", JSON.stringify(users)); + console.log('USERS_ppl = ', JSON.stringify(users)); this.validatedUsers = this.populateUsers(users, userRequestValidator); this.validatedOptions = this.populateOptions(options, this.requiresHashOptions); } @@ -769,7 +772,7 @@ export class UserImportBuilder { const populatedUsers: UploadAccountUser[] = []; users.forEach((user, index) => { try { - console.log("user uid= ", user.uid); + console.log('user uid= ', user.uid); const result = populateUploadAccountUser(user, userValidator); if (typeof result.passwordHash !== 'undefined') { this.requiresHashOptions = true; diff --git a/test/unit/auth/user-import-builder.spec.ts b/test/unit/auth/user-import-builder.spec.ts index 1bec9a151a..55c506cc5b 100644 --- a/test/unit/auth/user-import-builder.spec.ts +++ b/test/unit/auth/user-import-builder.spec.ts @@ -110,20 +110,20 @@ describe('UserImportBuilder', () => { phoneNumber: '+16505551000', factorId: 'phone', }, + // { + // uid: 'enrolledSecondFactor3', + // enrollmentTime: now.toISOString(), + // displayName: 'displayNameTotp', + // totpInfo: { + // sharedSecretKey: "VIAAQYSO37EKAWB2KAXEQ7EGUMLWI3P4" + // }, + // factorId: 'totp', + // }, { - uid: 'enrollmentId3', + uid: 'enrolledSecondFactor4', enrollmentTime: now.toISOString(), - displayName: 'displayNameTotp', totpInfo: { - sharedSecretKey: "VIAAQYSO37EKAWB2KAXEQ7EGUMLWI3P4" - }, - factorId: 'totp', - }, - { - uid: 'enrollmentId4', - enrollmentTime: now.toISOString(), - totpInfo: { - sharedSecretKey: "WSUKMEVTQ62EUBF37F2R466ZVLNFL3IF" + sharedSecretKey: 'WSUKMEVTQ62EUBF37F2R466ZVLNFL3IF' }, factorId: 'totp', }, @@ -180,21 +180,21 @@ describe('UserImportBuilder', () => { mfaEnrollmentId: 'enrolledSecondFactor2', phoneInfo: '+16505551000', }, - { - mfaEnrollmentId: 'enrollmentId3', - enrolledAt: now.toISOString(), - displayName: 'displayNameTotp', - totpInfo: { - sharedSecretKey: "VIAAQYSO37EKAWB2KAXEQ7EGUMLWI3P4" - } - }, - { - mfaEnrollmentId: 'enrollmentId4', - enrolledAt: now.toISOString(), - totpInfo: { - sharedSecretKey: "WSUKMEVTQ62EUBF37F2R466ZVLNFL3IF" - } - }, + // { + // mfaEnrollmentId: 'enrolledSecondFactor3', + // enrolledAt: now.toISOString(), + // displayName: 'displayNameTotp', + // totpInfo: { + // sharedSecretKey: "VIAAQYSO37EKAWB2KAXEQ7EGUMLWI3P4" + // } + // }, + // { + // mfaEnrollmentId: 'enrolledSecondFactor4', + // enrolledAt: now.toISOString(), + // totpInfo: { + // sharedSecretKey: "WSUKMEVTQ62EUBF37F2R466ZVLNFL3IF" + // } + // }, ], }, ]; From fa847b4f3f1b2faf527ce7918299537eeef5ce43 Mon Sep 17 00:00:00 2001 From: Pragati Date: Tue, 14 Nov 2023 12:40:17 -0800 Subject: [PATCH 4/5] fix unit tests --- src/auth/user-import-builder.ts | 14 +++---- test/unit/auth/user-import-builder.spec.ts | 48 +++++++++++----------- 2 files changed, 29 insertions(+), 33 deletions(-) diff --git a/src/auth/user-import-builder.ts b/src/auth/user-import-builder.ts index d8ab7f3201..d3257e6af8 100644 --- a/src/auth/user-import-builder.ts +++ b/src/auth/user-import-builder.ts @@ -327,8 +327,9 @@ export type ValidatorFunction = (data: UploadAccountUser) => void; * @param multiFactorInfo - The client format second factor. * @returns The corresponding AuthFactorInfo server request format. */ -export function convertMultiFactorInfoToServerFormat(multiFactorInfo: UpdateMultiFactorInfoRequest): AuthFactorInfo { +export function convertMultiFactorInfoToServerFormat(multiFactorInfo: UpdateMultiFactorInfoRequest, isUploadRequest: boolean = false): AuthFactorInfo { let enrolledAt; + console.log("enrollmentTime: ", multiFactorInfo.enrollmentTime); if (typeof multiFactorInfo.enrollmentTime !== 'undefined') { if (validator.isUTCDateString(multiFactorInfo.enrollmentTime)) { // Convert from UTC date string (client side format) to ISO date string (server side format). @@ -356,9 +357,7 @@ export function convertMultiFactorInfoToServerFormat(multiFactorInfo: UpdateMult } } return authFactorInfo; - } else if (isTotpFactor(multiFactorInfo)) { - console.log('TOTP_FACTOR_'); - console.log(multiFactorInfo.uid); + } else if (isUploadRequest && isTotpFactor(multiFactorInfo)) { // If any required field is missing or invalid, validation will still fail later. const authFactorInfo: AuthFactorInfo = { mfaEnrollmentId: multiFactorInfo.uid, @@ -464,13 +463,11 @@ function populateUploadAccountUser( }); }); } - // Convert user.multiFactor.enrolledFactors to server format. if (validator.isNonNullObject(user.multiFactor) && validator.isNonEmptyArray(user.multiFactor.enrolledFactors)) { user.multiFactor.enrolledFactors.forEach((multiFactorInfo) => { - console.log('MFA_INFO= ', JSON.stringify(multiFactorInfo)); - result.mfaInfo!.push(convertMultiFactorInfoToServerFormat(multiFactorInfo)); + result.mfaInfo!.push(convertMultiFactorInfoToServerFormat(multiFactorInfo, true)); }); } @@ -492,7 +489,9 @@ function populateUploadAccountUser( if (typeof userValidator === 'function') { userValidator(result); } + console.log("RESULT=$=", JSON.stringify(result)) return result; + } @@ -772,7 +771,6 @@ export class UserImportBuilder { const populatedUsers: UploadAccountUser[] = []; users.forEach((user, index) => { try { - console.log('user uid= ', user.uid); const result = populateUploadAccountUser(user, userValidator); if (typeof result.passwordHash !== 'undefined') { this.requiresHashOptions = true; diff --git a/test/unit/auth/user-import-builder.spec.ts b/test/unit/auth/user-import-builder.spec.ts index 55c506cc5b..27ac11d8a3 100644 --- a/test/unit/auth/user-import-builder.spec.ts +++ b/test/unit/auth/user-import-builder.spec.ts @@ -110,18 +110,17 @@ describe('UserImportBuilder', () => { phoneNumber: '+16505551000', factorId: 'phone', }, - // { - // uid: 'enrolledSecondFactor3', - // enrollmentTime: now.toISOString(), - // displayName: 'displayNameTotp', - // totpInfo: { - // sharedSecretKey: "VIAAQYSO37EKAWB2KAXEQ7EGUMLWI3P4" - // }, - // factorId: 'totp', - // }, + { + uid: 'enrolledSecondFactor3', + enrollmentTime: now.toUTCString(), + displayName: 'displayNameTotp', + totpInfo: { + sharedSecretKey: "VIAAQYSO37EKAWB2KAXEQ7EGUMLWI3P4" + }, + factorId: 'totp', + }, { uid: 'enrolledSecondFactor4', - enrollmentTime: now.toISOString(), totpInfo: { sharedSecretKey: 'WSUKMEVTQ62EUBF37F2R466ZVLNFL3IF' }, @@ -180,21 +179,20 @@ describe('UserImportBuilder', () => { mfaEnrollmentId: 'enrolledSecondFactor2', phoneInfo: '+16505551000', }, - // { - // mfaEnrollmentId: 'enrolledSecondFactor3', - // enrolledAt: now.toISOString(), - // displayName: 'displayNameTotp', - // totpInfo: { - // sharedSecretKey: "VIAAQYSO37EKAWB2KAXEQ7EGUMLWI3P4" - // } - // }, - // { - // mfaEnrollmentId: 'enrolledSecondFactor4', - // enrolledAt: now.toISOString(), - // totpInfo: { - // sharedSecretKey: "WSUKMEVTQ62EUBF37F2R466ZVLNFL3IF" - // } - // }, + { + mfaEnrollmentId: 'enrolledSecondFactor3', + enrolledAt: now.toISOString(), + displayName: 'displayNameTotp', + totpInfo: { + sharedSecretKey: "VIAAQYSO37EKAWB2KAXEQ7EGUMLWI3P4" + } + }, + { + mfaEnrollmentId: 'enrolledSecondFactor4', + totpInfo: { + sharedSecretKey: "WSUKMEVTQ62EUBF37F2R466ZVLNFL3IF" + } + }, ], }, ]; From 3fe1821dffc0d9b8da42dda2b8a52402c14651e6 Mon Sep 17 00:00:00 2001 From: Pragati Date: Tue, 14 Nov 2023 12:45:12 -0800 Subject: [PATCH 5/5] fix lint --- src/auth/user-import-builder.ts | 6 +++--- test/unit/auth/user-import-builder.spec.ts | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/auth/user-import-builder.ts b/src/auth/user-import-builder.ts index d3257e6af8..c311153a8c 100644 --- a/src/auth/user-import-builder.ts +++ b/src/auth/user-import-builder.ts @@ -327,9 +327,9 @@ export type ValidatorFunction = (data: UploadAccountUser) => void; * @param multiFactorInfo - The client format second factor. * @returns The corresponding AuthFactorInfo server request format. */ -export function convertMultiFactorInfoToServerFormat(multiFactorInfo: UpdateMultiFactorInfoRequest, isUploadRequest: boolean = false): AuthFactorInfo { +export function convertMultiFactorInfoToServerFormat(multiFactorInfo: UpdateMultiFactorInfoRequest, + isUploadRequest = false): AuthFactorInfo { let enrolledAt; - console.log("enrollmentTime: ", multiFactorInfo.enrollmentTime); if (typeof multiFactorInfo.enrollmentTime !== 'undefined') { if (validator.isUTCDateString(multiFactorInfo.enrollmentTime)) { // Convert from UTC date string (client side format) to ISO date string (server side format). @@ -489,7 +489,7 @@ function populateUploadAccountUser( if (typeof userValidator === 'function') { userValidator(result); } - console.log("RESULT=$=", JSON.stringify(result)) + console.log('RESULT=$=', JSON.stringify(result)) return result; } diff --git a/test/unit/auth/user-import-builder.spec.ts b/test/unit/auth/user-import-builder.spec.ts index 27ac11d8a3..34e8704931 100644 --- a/test/unit/auth/user-import-builder.spec.ts +++ b/test/unit/auth/user-import-builder.spec.ts @@ -115,7 +115,7 @@ describe('UserImportBuilder', () => { enrollmentTime: now.toUTCString(), displayName: 'displayNameTotp', totpInfo: { - sharedSecretKey: "VIAAQYSO37EKAWB2KAXEQ7EGUMLWI3P4" + sharedSecretKey: 'VIAAQYSO37EKAWB2KAXEQ7EGUMLWI3P4' }, factorId: 'totp', }, @@ -184,13 +184,13 @@ describe('UserImportBuilder', () => { enrolledAt: now.toISOString(), displayName: 'displayNameTotp', totpInfo: { - sharedSecretKey: "VIAAQYSO37EKAWB2KAXEQ7EGUMLWI3P4" + sharedSecretKey: 'VIAAQYSO37EKAWB2KAXEQ7EGUMLWI3P4' } }, { mfaEnrollmentId: 'enrolledSecondFactor4', totpInfo: { - sharedSecretKey: "WSUKMEVTQ62EUBF37F2R466ZVLNFL3IF" + sharedSecretKey: 'WSUKMEVTQ62EUBF37F2R466ZVLNFL3IF' } }, ],