From 564c28702507575907edd94d3632870175ea8ece Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nuno=20G=C3=B3is?= Date: Tue, 29 Nov 2022 19:46:40 +0000 Subject: [PATCH] Feat update token seen at (#2514) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://linear.app/unleash/issue/2-448/update-last-seen-column-for-api-tokens Co-authored-by: Ivar Conradi Ă˜sthus --- src/lib/db/api-token-store.ts | 2 +- src/lib/services/api-token-service.ts | 35 ++++++++++++++++++++++++++- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/lib/db/api-token-store.ts b/src/lib/db/api-token-store.ts index 99276c842e..30ff042604 100644 --- a/src/lib/db/api-token-store.ts +++ b/src/lib/db/api-token-store.ts @@ -203,7 +203,7 @@ export class ApiTokenStore implements IApiTokenStore { const now = new Date(); try { await this.db(TABLE) - .whereIn('secrets', secrets) + .whereIn('secret', secrets) .update({ seen_at: now }); } catch (err) { this.logger.error('Could not update lastSeen, error: ', err); diff --git a/src/lib/services/api-token-service.ts b/src/lib/services/api-token-service.ts index c1831c09dd..64ed609768 100644 --- a/src/lib/services/api-token-service.ts +++ b/src/lib/services/api-token-service.ts @@ -26,6 +26,7 @@ import { ApiTokenUpdatedEvent, } from '../types'; import { omitKeys } from '../util'; +import { IFlagResolver } from 'lib/types/experimental'; const resolveTokenPermissions = (tokenType: string) => { if (tokenType === ApiTokenType.ADMIN) { @@ -52,10 +53,16 @@ export class ApiTokenService { private timer: NodeJS.Timeout; + private seenTimer: NodeJS.Timeout; + private activeTokens: IApiToken[] = []; private eventStore: IEventStore; + private lastSeenSecrets: Set = new Set(); + + private flagResolver: IFlagResolver; + constructor( { apiTokenStore, @@ -65,8 +72,12 @@ export class ApiTokenService { IUnleashStores, 'apiTokenStore' | 'environmentStore' | 'eventStore' >, - config: Pick, + config: Pick< + IUnleashConfig, + 'getLogger' | 'authentication' | 'flagResolver' + >, ) { + this.flagResolver = config.flagResolver; this.store = apiTokenStore; this.eventStore = eventStore; this.environmentStore = environmentStore; @@ -76,6 +87,9 @@ export class ApiTokenService { () => this.fetchActiveTokens(), minutesToMilliseconds(1), ).unref(); + if (this.flagResolver.isEnabled('tokensLastSeen')) { + this.updateLastSeen(); + } if (config.authentication.initApiTokens.length > 0) { process.nextTick(async () => this.initApiTokens(config.authentication.initApiTokens), @@ -92,6 +106,19 @@ export class ApiTokenService { } } + async updateLastSeen(): Promise { + if (this.lastSeenSecrets.size > 0) { + const toStore = [...this.lastSeenSecrets]; + this.lastSeenSecrets = new Set(); + await this.store.markSeenAt(toStore); + } + + this.seenTimer = setTimeout( + async () => this.updateLastSeen(), + minutesToMilliseconds(3), + ).unref(); + } + public async getAllTokens(): Promise { return this.store.getAll(); } @@ -137,6 +164,10 @@ export class ApiTokenService { } if (token) { + if (this.flagResolver.isEnabled('tokensLastSeen')) { + this.lastSeenSecrets.add(token.secret); + } + return new ApiUser({ username: token.username, permissions: resolveTokenPermissions(token.type), @@ -269,6 +300,8 @@ export class ApiTokenService { destroy(): void { clearInterval(this.timer); + clearTimeout(this.seenTimer); this.timer = null; + this.seenTimer = null; } }