From cb2f81e5e74a111cae85077cdafc375a801606d4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C3=ABl=20Minelli?= <michael@minelli.me>
Date: Fri, 23 Feb 2024 23:55:39 +0100
Subject: [PATCH] SharedGitlabManager => Add possibility to update token

---
 managers/SharedGitlabManager.ts | 34 ++++++++++++++++++++++++++-------
 1 file changed, 27 insertions(+), 7 deletions(-)

diff --git a/managers/SharedGitlabManager.ts b/managers/SharedGitlabManager.ts
index 6984792..42039c2 100644
--- a/managers/SharedGitlabManager.ts
+++ b/managers/SharedGitlabManager.ts
@@ -1,24 +1,42 @@
 import axios                      from 'axios';
 import SharedConfig               from '../config/SharedConfig';
 import * as GitlabCore            from '@gitbeaker/core';
+import { GitbeakerRequestError }  from '@gitbeaker/requester-utils';
 import { Gitlab, PipelineSchema } from '@gitbeaker/rest';
 import GitlabToken                from '../types/Gitlab/GitlabToken';
+import { StatusCodes }            from 'http-status-codes';
 
 
 class SharedGitlabManager {
     private api!: GitlabCore.Gitlab<false>;
+    private readonly refreshTokenFunction?: () => Promise<string>;
 
     setToken(token: string) {
-        this.api = new Gitlab({
-                                  host : SharedConfig.gitlab.URL,
-                                  token: token
-                              });
+        this.api = new Gitlab(Object.assign({
+                                                host : SharedConfig.gitlab.URL,
+                                                token: token
+                                            }));
     }
 
-    constructor(token: string) {
+    constructor(token: string, refreshTokenFunction?: () => Promise<string>) {
+        this.refreshTokenFunction = refreshTokenFunction;
         this.setToken(token);
     }
 
+    private async executeGitlabRequest<T>(request: () => Promise<T>): Promise<T> {
+        try {
+            return await request();
+        } catch ( error ) {
+            if ( this.refreshTokenFunction && error instanceof GitbeakerRequestError && error.cause?.response.status === StatusCodes.UNAUTHORIZED ) {
+                this.setToken(await this.refreshTokenFunction());
+
+                return await request();
+            } else {
+                throw error;
+            }
+        }
+    }
+
     async getTokens(codeOrRefresh: string, isRefresh: boolean = false, clientSecret: string = ''): Promise<GitlabToken> {
         const response = await axios.post<GitlabToken>(SharedConfig.login.gitlab.url.token, {
             client_id    : SharedConfig.login.gitlab.client.id,
@@ -33,8 +51,10 @@ class SharedGitlabManager {
     }
 
     async getRepositoryPipelines(repoId: number, branch: string = 'main'): Promise<Array<PipelineSchema>> {
-        return await this.api.Pipelines.all(repoId, {
-            ref: branch
+        return await this.executeGitlabRequest(async () => {
+            return await this.api.Pipelines.all(repoId, {
+                ref: branch
+            });
         });
     }
 }
-- 
GitLab