From ff77a182629e473724c712c89116e8f949193bad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=A9grier?= Date: Wed, 8 Dec 2021 10:58:53 +0100 Subject: [PATCH 1/2] Don't retry Axios if a token decryption failed If a token decryption failed, it will emit a HTTP 500. We should not retry Axios in this case but rather fail. Note: a token decryption failed should not throw a HTTP 500 but another error code (HTTP 401?) So maybe this fix is plainly wrong. --- front/src/Connexion/AxiosUtils.ts | 6 ++++++ messages/protos/messages.proto | 3 +++ 2 files changed, 9 insertions(+) diff --git a/front/src/Connexion/AxiosUtils.ts b/front/src/Connexion/AxiosUtils.ts index 9d50ce4f..f4cd160f 100644 --- a/front/src/Connexion/AxiosUtils.ts +++ b/front/src/Connexion/AxiosUtils.ts @@ -13,6 +13,12 @@ axiosWithRetry.defaults.raxConfig = { maxRetryAfter: 60_000, + statusCodesToRetry: [ + [100, 199], + [429, 429], + [501, 599], + ], + // You can detect when a retry is happening, and figure out how many // retry attempts have been made onRetryAttempt: (err) => { diff --git a/messages/protos/messages.proto b/messages/protos/messages.proto index 5b319feb..7a4d74d9 100644 --- a/messages/protos/messages.proto +++ b/messages/protos/messages.proto @@ -259,6 +259,9 @@ message BanUserMessage{ string message = 2; } +/** + * Messages going from back and pusher to the front + */ message ServerToClientMessage { oneof message { BatchMessage batchMessage = 1; From 598c7412a250de5e74ac81ae38c83e81ad5ff57d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=A9grier?= Date: Wed, 8 Dec 2021 14:46:23 +0100 Subject: [PATCH 2/2] When sending an invalid token, the HTTP API from the Pusher now returns a 401 instead of an HTTP 500. --- front/src/Connexion/Room.ts | 7 ++++--- pusher/src/Controller/MapController.ts | 15 ++++++++++----- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/front/src/Connexion/Room.ts b/front/src/Connexion/Room.ts index 4b6d82a4..044d8d67 100644 --- a/front/src/Connexion/Room.ts +++ b/front/src/Connexion/Room.ts @@ -116,11 +116,12 @@ export class Room { this._contactPage = data.contactPage || CONTACT_URL; return new MapDetail(data.mapUrl, data.textures); } catch (e) { - console.error("Error => getMapDetail", e, e.response); - //TODO fix me and manage Error class - if (e.response?.data === "Token decrypted error") { + if (axios.isAxiosError(e) && e.response?.status == 401 && e.response?.data === "Token decrypted error") { + console.warn("JWT token sent could not be decrypted. Maybe it expired?"); localUserStore.setAuthToken(null); window.location.assign("/login"); + } else { + console.error("Error => getMapDetail", e, e.response); } throw e; } diff --git a/pusher/src/Controller/MapController.ts b/pusher/src/Controller/MapController.ts index 7f76ff9e..23eef566 100644 --- a/pusher/src/Controller/MapController.ts +++ b/pusher/src/Controller/MapController.ts @@ -8,6 +8,7 @@ import { isMapDetailsData, MapDetailsData } from "../Services/AdminApi/MapDetail import { socketManager } from "../Services/SocketManager"; import { AuthTokenData, jwtTokenManager } from "../Services/JWTTokenManager"; import { v4 } from "uuid"; +import { InvalidTokenError } from "./InvalidTokenError"; export class MapController extends BaseController { constructor(private App: TemplatedApp) { @@ -85,11 +86,15 @@ export class MapController extends BaseController { userId = authTokenData.identifier; console.info("JWT expire, but decoded", userId); } catch (e) { - // The token was not good, redirect user on login page - res.writeStatus("500"); - res.writeHeader("Access-Control-Allow-Origin", FRONT_URL); - res.end("Token decrypted error"); - return; + if (e instanceof InvalidTokenError) { + // The token was not good, redirect user on login page + res.writeStatus("401 Unauthorized"); + res.writeHeader("Access-Control-Allow-Origin", FRONT_URL); + res.end("Token decrypted error"); + return; + } else { + return this.errorToResponse(e, res); + } } } }