From 4d5c2162fb8f9e763852602ee0b7ae0b86fdd010 Mon Sep 17 00:00:00 2001 From: Rich Gowman Date: Tue, 12 May 2020 14:11:52 -0400 Subject: [PATCH 1/3] Properly parse the lastRefreshTime. It's returned from the server in a different format than the other timestamps. Fixes #887 --- src/auth/user-record.ts | 3 ++- test/integration/auth.spec.ts | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/auth/user-record.ts b/src/auth/user-record.ts index 9e33c19a8c..7d0ebef81b 100644 --- a/src/auth/user-record.ts +++ b/src/auth/user-record.ts @@ -326,7 +326,8 @@ export class UserMetadata { // These bugs have already been addressed since then. utils.addReadonlyGetter(this, 'creationTime', parseDate(response.createdAt)); utils.addReadonlyGetter(this, 'lastSignInTime', parseDate(response.lastLoginAt)); - utils.addReadonlyGetter(this, 'lastRefreshTime', parseDate(response.lastRefreshAt)); + const lastRefreshAt = response.lastRefreshAt ? new Date(response.lastRefreshAt).toUTCString() : null; + utils.addReadonlyGetter(this, 'lastRefreshTime', lastRefreshAt); } /** @return The plain object representation of the user's metadata. */ diff --git a/test/integration/auth.spec.ts b/test/integration/auth.spec.ts index c48215c295..5bd0df3c5c 100755 --- a/test/integration/auth.spec.ts +++ b/test/integration/auth.spec.ts @@ -336,6 +336,12 @@ describe('admin.auth', () => { .then((userRecord) => { expect(userRecord.metadata.lastRefreshTime).to.exist; expect(isUTCString(userRecord.metadata.lastRefreshTime!)); + expect(new Date(userRecord.metadata.creationTime).getTime()) + .lte(new Date(userRecord.metadata.lastRefreshTime!).getTime()); + const creationTimePlus1Hour = new Date(userRecord.metadata.creationTime); + creationTimePlus1Hour.setHours(creationTimePlus1Hour.getHours()+1); + expect(new Date(userRecord.metadata.lastRefreshTime!).getTime()) + .lte(creationTimePlus1Hour.getTime()); }); } finally { admin.auth().deleteUser('lastRefreshTimeUser'); From eacce1a9a1cfcacadbcae482ca57283cc6de4f17 Mon Sep 17 00:00:00 2001 From: Rich Gowman Date: Tue, 12 May 2020 14:38:13 -0400 Subject: [PATCH 2/3] Add lastRefreshTime to UserMetadata toJSON method. See #887 --- src/auth/user-record.ts | 1 + test/integration/auth.spec.ts | 1 + test/unit/auth/user-record.spec.ts | 6 ++++++ 3 files changed, 8 insertions(+) diff --git a/src/auth/user-record.ts b/src/auth/user-record.ts index 7d0ebef81b..71bed50f59 100644 --- a/src/auth/user-record.ts +++ b/src/auth/user-record.ts @@ -335,6 +335,7 @@ export class UserMetadata { return { lastSignInTime: this.lastSignInTime, creationTime: this.creationTime, + lastRefreshTime: this.lastRefreshTime, }; } } diff --git a/test/integration/auth.spec.ts b/test/integration/auth.spec.ts index 5bd0df3c5c..cda540ef71 100755 --- a/test/integration/auth.spec.ts +++ b/test/integration/auth.spec.ts @@ -1802,6 +1802,7 @@ describe('admin.auth', () => { metadata: { lastSignInTime: now, creationTime: now, + lastRefreshTime: null, // TODO(rsgowman): Switch to 'now' once importing users supports lastRefreshTime }, providerData: [ { diff --git a/test/unit/auth/user-record.spec.ts b/test/unit/auth/user-record.spec.ts index fce2041ec6..51271115f6 100644 --- a/test/unit/auth/user-record.spec.ts +++ b/test/unit/auth/user-record.spec.ts @@ -80,6 +80,7 @@ function getValidUserResponse(tenantId?: string): GetAccountInfoUserResponse { validSince: '1476136676', lastLoginAt: '1476235905000', createdAt: '1476136676000', + lastRefreshAt: '2016-10-12T01:31:45.000Z', customAttributes: JSON.stringify({ admin: true, }), @@ -156,6 +157,7 @@ function getUserJSON(tenantId?: string): object { metadata: { lastSignInTime: new Date(1476235905000).toUTCString(), creationTime: new Date(1476136676000).toUTCString(), + lastRefreshTime: new Date(1476235905000).toUTCString(), }, customClaims: { admin: true, @@ -616,14 +618,17 @@ describe('UserInfo', () => { describe('UserMetadata', () => { const expectedLastLoginAt = 1476235905000; const expectedCreatedAt = 1476136676000; + const expectedLastRefreshAt = '2016-10-12T01:31:45.000Z'; const actualMetadata: UserMetadata = new UserMetadata({ localId: 'uid123', lastLoginAt: expectedLastLoginAt.toString(), createdAt: expectedCreatedAt.toString(), + lastRefreshAt: expectedLastRefreshAt, }); const expectedMetadataJSON = { lastSignInTime: new Date(expectedLastLoginAt).toUTCString(), creationTime: new Date(expectedCreatedAt).toUTCString(), + lastRefreshTime: new Date(expectedLastRefreshAt).toUTCString(), }; describe('constructor', () => { @@ -872,6 +877,7 @@ describe('UserRecord', () => { const metadata = new UserMetadata({ createdAt: '1476136676000', lastLoginAt: '1476235905000', + lastRefreshAt: '2016-10-12T01:31:45.000Z', } as any); expect(userRecord.metadata).to.deep.equal(metadata); }); From f072d6b54b4592929afccc690b43f09c5851f1eb Mon Sep 17 00:00:00 2001 From: Rich Gowman Date: Wed, 22 Jun 2022 10:20:12 -0400 Subject: [PATCH 3/3] Don't specify lastRefreshTime in integration tests Since specifying this when importing users isn't supported. --- test/integration/auth.spec.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/test/integration/auth.spec.ts b/test/integration/auth.spec.ts index 9bae6d70be..78cfb62701 100644 --- a/test/integration/auth.spec.ts +++ b/test/integration/auth.spec.ts @@ -31,7 +31,7 @@ import { deepExtend, deepCopy } from '../../src/utils/deep-copy'; import { AuthProviderConfig, CreateTenantRequest, DeleteUsersResult, PhoneMultiFactorInfo, TenantAwareAuth, UpdatePhoneMultiFactorInfoRequest, UpdateTenantRequest, UserImportOptions, - UserImportRecord, UserRecord, getAuth, + UserImportRecord, UserMetadata, UserRecord, getAuth, } from '../../lib/auth/index'; const chalk = require('chalk'); // eslint-disable-line @typescript-eslint/no-var-requires @@ -2517,7 +2517,8 @@ describe('admin.auth', () => { metadata: { lastSignInTime: now, creationTime: now, - lastRefreshTime: null, // TODO(rsgowman): Switch to 'now' once importing users supports lastRefreshTime + // TODO(rsgowman): Enable once importing users supports lastRefreshTime + //lastRefreshTime: now, }, providerData: [ { @@ -2549,6 +2550,11 @@ describe('admin.auth', () => { providerId: 'phone', phoneNumber: importUserRecord.phoneNumber!, }); + // The lastRefreshTime should be set to null + type Writable = { + -readonly [k in keyof UserMetadata]: UserMetadata[k]; + }; + (importUserRecord.metadata as Writable).lastRefreshTime = null; const actualUserRecord: {[key: string]: any} = userRecord.toJSON(); for (const key of Object.keys(importUserRecord)) { expect(JSON.stringify(actualUserRecord[key]))