From fd28b4d410912fd04eb5a10ff9d96e8263d8ec11 Mon Sep 17 00:00:00 2001
From: Thomas Citharel <tcit@tcit.fr>
Date: Thu, 27 May 2021 18:24:11 +0200
Subject: [PATCH] Automatically refresh jwt token periodically

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
---
 js/package.json |  1 +
 js/src/App.vue  | 22 ++++++++++++++++++++++
 js/yarn.lock    |  5 +++++
 3 files changed, 28 insertions(+)

diff --git a/js/package.json b/js/package.json
index 8b0bf22aa..84673d988 100644
--- a/js/package.json
+++ b/js/package.json
@@ -37,6 +37,7 @@
     "graphql": "^15.0.0",
     "graphql-tag": "^2.10.3",
     "intersection-observer": "^0.12.0",
+    "jwt-decode": "^3.1.2",
     "leaflet": "^1.4.0",
     "leaflet.locatecontrol": "^0.73.0",
     "lodash": "^4.17.11",
diff --git a/js/src/App.vue b/js/src/App.vue
index 1030cff25..218a48cdc 100644
--- a/js/src/App.vue
+++ b/js/src/App.vue
@@ -50,6 +50,8 @@ import { initializeCurrentActor } from "./utils/auth";
 import { CONFIG } from "./graphql/config";
 import { IConfig } from "./types/config.model";
 import { ICurrentUser } from "./types/current-user.model";
+import jwt_decode, { JwtPayload } from "jwt-decode";
+import { refreshAccessToken } from "./apollo/utils";
 
 @Component({
   apollo: {
@@ -78,6 +80,8 @@ export default class App extends Vue {
 
   online = true;
 
+  interval: number | undefined = undefined;
+
   async created(): Promise<void> {
     if (await this.initializeCurrentUser()) {
       await initializeCurrentActor(this.$apollo.provider.defaultClient);
@@ -119,11 +123,29 @@ export default class App extends Vue {
       this.online = true;
       console.log("online");
     });
+
+    this.interval = setInterval(async () => {
+      const accessToken = localStorage.getItem(AUTH_ACCESS_TOKEN);
+      if (accessToken) {
+        const token = jwt_decode<JwtPayload>(accessToken);
+        if (
+          token?.exp !== undefined &&
+          new Date(token.exp * 1000 - 60000) < new Date()
+        ) {
+          refreshAccessToken(this.$apollo.getClient());
+        }
+      }
+    }, 60000);
   }
 
   showOfflineNetworkWarning(): void {
     this.$notifier.error(this.$t("You are offline") as string);
   }
+
+  unmounted(): void {
+    clearInterval(this.interval);
+    this.interval = undefined;
+  }
 }
 </script>
 
diff --git a/js/yarn.lock b/js/yarn.lock
index aa7cef7b9..1aa1e9127 100644
--- a/js/yarn.lock
+++ b/js/yarn.lock
@@ -7509,6 +7509,11 @@ jsprim@^1.2.2:
     json-schema "0.2.3"
     verror "1.10.0"
 
+jwt-decode@^3.1.2:
+  version "3.1.2"
+  resolved "https://registry.yarnpkg.com/jwt-decode/-/jwt-decode-3.1.2.tgz#3fb319f3675a2df0c2895c8f5e9fa4b67b04ed59"
+  integrity sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A==
+
 killable@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/killable/-/killable-1.0.1.tgz#4c8ce441187a061c7474fb87ca08e2a638194892"