From a91fa7066a554fa5aabd9df5ca33365e6bc8663d Mon Sep 17 00:00:00 2001 From: André Oliveira <37463445+SpecialAro@users.noreply.github.com> Date: Fri, 13 Oct 2023 13:14:08 +0100 Subject: Add new token request (#1384) * Add new token request This exists so that the user generates a new JWT token with the new adonisjs update on the server (that is now stored - hashed and using the adonis5-jwt package - which previously wasn't). This logic enhances security as we can delete the tokens on the jwt_tokens database in order to log-off users in case the APP_KEY is compromised (if we are hacked, for instance). After some time (maybe months after the migration) we can delete the old code on the server side that handles the deprecated JWT tokens (and possibly change the APP_KEY used to sign the old certificates - we can now probably use certs to sign the JWT - to enhance security as well). * Update src/api/server/ServerApi.ts Co-authored-by: MCMXC <16797721+mcmxcdev@users.noreply.github.com> * Update src/stores/UserStore.ts Co-authored-by: MCMXC <16797721+mcmxcdev@users.noreply.github.com> --------- Co-authored-by: MCMXC <16797721+mcmxcdev@users.noreply.github.com> --- src/stores/UserStore.ts | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'src/stores') diff --git a/src/stores/UserStore.ts b/src/stores/UserStore.ts index 0616acdad..f98f7d340 100644 --- a/src/stores/UserStore.ts +++ b/src/stores/UserStore.ts @@ -50,6 +50,11 @@ export default class UserStore extends TypedStore { 'getInfo', ); + @observable requestNewTokenRequest: CachedRequest = new CachedRequest( + this.api.user, + 'requestNewToken', + ); + @observable updateUserInfoRequest: Request = new Request( this.api.user, 'updateInfo', @@ -174,6 +179,11 @@ export default class UserStore extends TypedStore { @computed get data() { if (!this.isLoggedIn) return {}; + const newTokenNeeded = this._shouldRequestNewToken(this.authToken); + if (newTokenNeeded) { + this._requestNewToken(); + } + return this.getUserInfoRequest.execute().result || {}; } @@ -367,6 +377,32 @@ export default class UserStore extends TypedStore { } // Helpers + _shouldRequestNewToken(authToken): boolean { + try { + const decoded = jwt.decode(authToken); + if (!decoded) { + throw new Error('Invalid token'); + } + + if (decoded.uid) { + return true; + } + + return false; + } catch { + return true; + } + } + + _requestNewToken(): void { + // Logic to request new token (use an endpoint for that) + const data = this.requestNewTokenRequest.execute().result; + if (data) { + this.authToken = data.token; + localStorage.setItem('authToken', data.token); + } + } + _parseToken(authToken) { try { const decoded = jwt.decode(authToken); -- cgit v1.2.3-54-g00ecf