From fc439c585e0871dd423361eed9921fa42f2a8f71 Mon Sep 17 00:00:00 2001 From: Alex Tugarev Date: Tue, 21 Jun 2022 09:19:35 +0000 Subject: [PATCH 1/2] Add caching for pending token renewals --- components/server/src/user/token-service.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/components/server/src/user/token-service.ts b/components/server/src/user/token-service.ts index eb68cbe299a27b..bff26363920e42 100644 --- a/components/server/src/user/token-service.ts +++ b/components/server/src/user/token-service.ts @@ -28,7 +28,23 @@ export class TokenService implements TokenProvider { }); } + protected getTokenForHostCache = new Map>(); + async getTokenForHost(user: User, host: string): Promise { + // (AT) when it comes to token renewal, the awaited http requests may + // cause "parallel" calls to repeat the renewal, which will fail. + // Caching for pending operations should solve this issue. + const key = `${host}-${user.id}`; + let promise = this.getTokenForHostCache.get(key); + if (!promise) { + promise = this.doGetTokenForHost(user, host); + this.getTokenForHostCache.set(key, promise); + promise.finally(() => this.getTokenForHostCache.delete(key)); + } + return promise; + } + + async doGetTokenForHost(user: User, host: string): Promise { const identity = this.getIdentityForHost(user, host); let token = await this.userDB.findTokenForIdentity(identity); if (!token) { From 20e84343f974bf63a4cbd3da9f696696df2b2994 Mon Sep 17 00:00:00 2001 From: Alex Tugarev Date: Tue, 21 Jun 2022 09:40:13 +0000 Subject: [PATCH 2/2] Avoid token renewal 30mins before time of expiry --- components/server/src/user/token-service.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/components/server/src/user/token-service.ts b/components/server/src/user/token-service.ts index bff26363920e42..eab626eb8449b4 100644 --- a/components/server/src/user/token-service.ts +++ b/components/server/src/user/token-service.ts @@ -52,9 +52,9 @@ export class TokenService implements TokenProvider { `No token found for user ${identity.authProviderId}/${identity.authId}/${identity.authName}!`, ); } - const refreshTime = new Date(); - refreshTime.setTime(refreshTime.getTime() + 30 * 60 * 1000); - if (token.expiryDate && token.expiryDate < refreshTime.toISOString()) { + const aboutToExpireTime = new Date(); + aboutToExpireTime.setTime(aboutToExpireTime.getTime() + 5 * 60 * 1000); + if (token.expiryDate && token.expiryDate < aboutToExpireTime.toISOString()) { const { authProvider } = this.hostContextProvider.get(host)!; if (authProvider.refreshToken) { await authProvider.refreshToken(user);