From 7c3730f01403b1979a9ccb27ce59c5e3a714c8f4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C3=ABl=20Minelli?= <michael@minelli.me>
Date: Sat, 13 Jan 2024 02:01:03 +0100
Subject: [PATCH] Inform about the DojoCLI version in responses header

---
 ExpressAPI/src/config/Config.ts               | 10 ++++++
 ExpressAPI/src/express/API.ts                 | 10 ++++--
 .../src/helpers/DojoCliVersionHelper.ts       | 33 +++++++++++++++++++
 3 files changed, 51 insertions(+), 2 deletions(-)
 create mode 100644 ExpressAPI/src/helpers/DojoCliVersionHelper.ts

diff --git a/ExpressAPI/src/config/Config.ts b/ExpressAPI/src/config/Config.ts
index e3a1b78..ebbad67 100644
--- a/ExpressAPI/src/config/Config.ts
+++ b/ExpressAPI/src/config/Config.ts
@@ -21,6 +21,11 @@ class Config {
         }
     }; // { version: { CLIENT: CONDITION } }
 
+    public readonly dojoCLI: {
+        versionUpdatePeriodMs: number
+        repositoryId: number
+    };
+
     public readonly jwtConfig: {
         secret: string; expiresIn: number;
     };
@@ -64,6 +69,11 @@ class Config {
 
         this.requestClientValidation = JSON5.parse(process.env.REQUEST_CLIENT_VALIDATION || '{"version": {}}');
 
+        this.dojoCLI = {
+            versionUpdatePeriodMs: Number(process.env.DOJO_CLI_VERSION_UPDATE_PERIOD_MS || 3600),
+            repositoryId         : Number(process.env.DOJO_CLI_GITLAB_REPOSITORY_ID || 0)
+        };
+
         this.jwtConfig = {
             secret   : process.env.JWT_SECRET_KEY || '',
             expiresIn: Number(process.env.SESSION_TIMEOUT || 0)
diff --git a/ExpressAPI/src/express/API.ts b/ExpressAPI/src/express/API.ts
index dcc801c..0d61b88 100644
--- a/ExpressAPI/src/express/API.ts
+++ b/ExpressAPI/src/express/API.ts
@@ -16,6 +16,7 @@ import compression                    from 'compression';
 import ClientVersionCheckerMiddleware from '../middlewares/ClientVersionCheckerMiddleware';
 import swaggerUi                      from 'swagger-ui-express';
 import path                           from 'path';
+import DojoCliVersionHelper           from '../helpers/DojoCliVersionHelper';
 
 
 class API implements WorkerTask {
@@ -25,7 +26,7 @@ class API implements WorkerTask {
     constructor() {
         this.backend = express();
 
-        this.initSwagger();
+        this.initOpenAPI();
         this.initBaseMiddlewares();
 
         this.backend.use(ClientVersionCheckerMiddleware.register());
@@ -43,9 +44,14 @@ class API implements WorkerTask {
         this.backend.use(helmet()); //Help to secure express, https://helmetjs.github.io/
         this.backend.use(cors()); //Allow CORS requests
         this.backend.use(compression()); //Compress responses
+
+        this.backend.use(async (req, res, next) => {
+            res.header('dojocli-latest-version', await DojoCliVersionHelper.getLatestVersion());
+            next();
+        });
     }
 
-    private initSwagger() {
+    private initOpenAPI() {
         const options = {
             customSiteTitle: 'Dojo API',
             explorer       : false,
diff --git a/ExpressAPI/src/helpers/DojoCliVersionHelper.ts b/ExpressAPI/src/helpers/DojoCliVersionHelper.ts
new file mode 100644
index 0000000..a44e1ec
--- /dev/null
+++ b/ExpressAPI/src/helpers/DojoCliVersionHelper.ts
@@ -0,0 +1,33 @@
+import Config        from '../config/Config';
+import GitlabRelease from '../shared/types/Gitlab/GitlabRelease';
+import GitlabManager from '../managers/GitlabManager';
+
+
+class DojoCliVersionHelper {
+    private latestUpdate: Date | undefined;
+    private latestVersion: string | undefined;
+
+    constructor() { }
+
+    private async updateVersion(): Promise<void> {
+        const releases: Array<GitlabRelease> = await GitlabManager.getRepositoryReleases(Config.dojoCLI.repositoryId);
+        for ( const release of releases ) {
+            if ( !isNaN(+release.tag_name.replace('.', '')) ) {
+                this.latestVersion = release.tag_name;
+                this.latestUpdate = new Date();
+                return;
+            }
+        }
+    }
+
+    public async getLatestVersion(): Promise<string> {
+        if ( !this.latestVersion || !this.latestUpdate || (new Date()).getTime() - this.latestUpdate.getTime() >= Config.dojoCLI.versionUpdatePeriodMs ) {
+            await this.updateVersion();
+        }
+
+        return this.latestVersion!;
+    }
+}
+
+
+export default new DojoCliVersionHelper();
\ No newline at end of file
-- 
GitLab