diff --git a/docgen/content-sources/node/toc.yaml b/docgen/content-sources/node/toc.yaml index 4466e2559f..bba7cf4f64 100644 --- a/docgen/content-sources/node/toc.yaml +++ b/docgen/content-sources/node/toc.yaml @@ -86,6 +86,10 @@ toc: path: /docs/reference/admin/node/admin.auth.UserInfo - title: "UserMetadata" path: /docs/reference/admin/node/admin.auth.UserMetadata + - title: "UserMetadataRequest" + path: /docs/reference/admin/node/admin.auth.UserMetadataRequest + - title: "UserProviderRequest" + path: /docs/reference/admin/node/admin.auth.UserProviderRequest - title: "UserRecord" path: /docs/reference/admin/node/admin.auth.UserRecord - title: "SessionCookieOptions" diff --git a/src/auth.d.ts b/src/auth.d.ts index eedb08786b..cfc2c1fd9c 100644 --- a/src/auth.d.ts +++ b/src/auth.d.ts @@ -624,6 +624,58 @@ export namespace admin.auth { errors: _admin.FirebaseArrayIndexError[]; } + /** + * User metadata to include when importing a user. + */ + interface UserMetadataRequest { + + /** + * The date the user last signed in, formatted as a UTC string. + */ + lastSignInTime?: string; + + /** + * The date the user was created, formatted as a UTC string. + */ + creationTime?: string; + } + + /** + * User provider data to include when importing a user. + */ + interface UserProviderRequest { + + /** + * The user identifier for the linked provider. + */ + uid: string; + + /** + * The display name for the linked provider. + */ + displayName?: string; + + /** + * The email for the linked provider. + */ + email?: string; + + /** + * The phone number for the linked provider. + */ + phoneNumber?: string; + + /** + * The photo URL for the linked provider. + */ + photoURL?: string; + + /** + * The linked provider ID (for example, "google.com" for the Google provider). + */ + providerId: string; + } + /** * Interface representing a user to import to Firebase Auth via the * {@link https://firebase.google.com/docs/reference/admin/node/admin.auth.Auth#importUsers `importUsers()`} method. @@ -643,7 +695,7 @@ export namespace admin.auth { /** * Whether or not the user's primary email is verified. */ - emailVerified: boolean; + emailVerified?: boolean; /** * The user's display name. @@ -664,17 +716,17 @@ export namespace admin.auth { * Whether or not the user is disabled: `true` for disabled; `false` for * enabled. */ - disabled: boolean; + disabled?: boolean; /** * Additional metadata about the user. */ - metadata: admin.auth.UserMetadata; + metadata?: admin.auth.UserMetadataRequest; /** * An array of providers (for example, Google, Facebook) linked to the user. */ - providerData?: admin.auth.UserInfo[]; + providerData?: admin.auth.UserProviderRequest[]; /** * The user's custom claims object if available, typically used to define @@ -703,6 +755,11 @@ export namespace admin.auth { * to the tenant corresponding to that `TenantAwareAuth` instance's tenant ID. */ tenantId?: string | null; + + /** + * The user's multi-factor related properties. + */ + multiFactor?: admin.auth.MultiFactorUpdateSettings; } /** diff --git a/test/integration/auth.spec.ts b/test/integration/auth.spec.ts index 209b24ec14..19f33b1d05 100755 --- a/test/integration/auth.spec.ts +++ b/test/integration/auth.spec.ts @@ -1421,7 +1421,7 @@ describe('admin.auth', () => { describe('importUsers()', () => { const randomUid = 'import_' + generateRandomString(20).toLowerCase(); - let importUserRecord: any; + let importUserRecord: admin.auth.UserImportRecord; const rawPassword = 'password'; const rawSalt = 'NaCl'; // Simulate a user stored using SCRYPT being migrated to Firebase Auth via importUsers. @@ -1635,15 +1635,15 @@ describe('admin.auth', () => { return admin.auth().getUser(uid); }).then((userRecord) => { // The phone number provider will be appended to the list of accounts. - importUserRecord.providerData.push({ - uid: importUserRecord.phoneNumber, + importUserRecord.providerData?.push({ + uid: importUserRecord.phoneNumber!, providerId: 'phone', - phoneNumber: importUserRecord.phoneNumber, + phoneNumber: importUserRecord.phoneNumber!, }); const actualUserRecord: {[key: string]: any} = userRecord.toJSON(); for (const key of Object.keys(importUserRecord)) { expect(JSON.stringify(actualUserRecord[key])) - .to.be.equal(JSON.stringify(importUserRecord[key])); + .to.be.equal(JSON.stringify((importUserRecord as any)[key])); } }).should.eventually.be.fulfilled; }); @@ -1652,6 +1652,23 @@ describe('admin.auth', () => { const uid = generateRandomString(20).toLowerCase(); const email = uid + '@example.com'; const now = new Date(1476235905000).toUTCString(); + const enrolledFactors: admin.auth.UpdatePhoneMultiFactorInfoRequest[] = [ + { + uid: 'mfaUid1', + phoneNumber: '+16505550001', + displayName: 'Work phone number', + factorId: 'phone', + enrollmentTime: now, + } , + { + uid: 'mfaUid2', + phoneNumber: '+16505550002', + displayName: 'Personal phone number', + factorId: 'phone', + enrollmentTime: now, + }, + ]; + importUserRecord = { uid, email, @@ -1671,22 +1688,7 @@ describe('admin.auth', () => { }, ], multiFactor: { - enrolledFactors: [ - { - uid: 'mfaUid1', - phoneNumber: '+16505550001', - displayName: 'Work phone number', - factorId: 'phone', - enrollmentTime: now, - }, - { - uid: 'mfaUid2', - phoneNumber: '+16505550002', - displayName: 'Personal phone number', - factorId: 'phone', - enrollmentTime: now, - }, - ], + enrolledFactors, }, }; uids.push(importUserRecord.uid); @@ -1702,7 +1704,7 @@ describe('admin.auth', () => { const actualUserRecord: {[key: string]: any} = userRecord.toJSON(); expect(actualUserRecord.multiFactor.enrolledFactors.length).to.equal(2); expect(actualUserRecord.multiFactor.enrolledFactors) - .to.deep.equal(importUserRecord.multiFactor.enrolledFactors); + .to.deep.equal(importUserRecord.multiFactor?.enrolledFactors); }).should.eventually.be.fulfilled; }); @@ -1741,7 +1743,9 @@ describe('admin.auth', () => { * @retunr {Promise} A promise that resolved on success. */ function testImportAndSignInUser( - importUserRecord: any, importOptions: any, rawPassword: string): Promise { + importUserRecord: admin.auth.UserImportRecord, + importOptions: any, + rawPassword: string): Promise { const users = [importUserRecord]; // Import the user record. return admin.auth().importUsers(users, importOptions) @@ -1751,7 +1755,7 @@ function testImportAndSignInUser( expect(result.successCount).to.equal(1); expect(result.errors.length).to.equal(0); // Sign in with an email and password to the imported account. - return clientAuth().signInWithEmailAndPassword(users[0].email, rawPassword); + return clientAuth().signInWithEmailAndPassword(users[0].email!, rawPassword); }) .then(({user}) => { // Confirm successful sign-in.