diff --git a/ExpressAPI/.idea/jetbrainsConfiguration b/ExpressAPI/.idea/jetbrainsConfiguration
index ffc5d65f9f0f0e825688177425e526131aa84631..f572bf3afa0a98675247df85c599b5d1e5a62d0d 160000
--- a/ExpressAPI/.idea/jetbrainsConfiguration
+++ b/ExpressAPI/.idea/jetbrainsConfiguration
@@ -1 +1 @@
-Subproject commit ffc5d65f9f0f0e825688177425e526131aa84631
+Subproject commit f572bf3afa0a98675247df85c599b5d1e5a62d0d
diff --git a/ExpressAPI/package-lock.json b/ExpressAPI/package-lock.json
index 760ee8e43a64e8471e6752843ac3858a7a0acfad..7f414466df56364dbc435a8393f8fcc30c9bda47 100644
--- a/ExpressAPI/package-lock.json
+++ b/ExpressAPI/package-lock.json
@@ -9,7 +9,7 @@
             "version": "3.6.0",
             "license": "AGPLv3",
             "dependencies": {
-                "@gitbeaker/rest": "^39.34.2",
+                "@gitbeaker/rest": "^40.0.1",
                 "@prisma/client": "^5.9.1",
                 "axios": "^1.6.7",
                 "compression": "^1.7.4",
@@ -224,11 +224,11 @@
             "dev": true
         },
         "node_modules/@gitbeaker/core": {
-            "version": "39.34.2",
-            "resolved": "https://registry.npmjs.org/@gitbeaker/core/-/core-39.34.2.tgz",
-            "integrity": "sha512-Vs1BKnEMnHltq1nMuBKxust1E+JUroDVKLy87ElLgvjAkH726mEVJCFnNC2/o2Ru7Et2qqhFN+PlUeYzzAbU2w==",
+            "version": "40.0.1",
+            "resolved": "https://registry.npmjs.org/@gitbeaker/core/-/core-40.0.1.tgz",
+            "integrity": "sha512-Zh2eVUgy2kYVnp7Db4gWoFqFbjgsnm2FvBEERbH3UM3cOA/iMqM+tw/of+Qk4yO+gv6tGZ9f4nF7+vK0tQFmDA==",
             "dependencies": {
-                "@gitbeaker/requester-utils": "^39.34.2",
+                "@gitbeaker/requester-utils": "^40.0.1",
                 "qs": "^6.11.2",
                 "xcase": "^2.0.1"
             },
@@ -237,11 +237,11 @@
             }
         },
         "node_modules/@gitbeaker/core/node_modules/qs": {
-            "version": "6.11.2",
-            "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz",
-            "integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==",
+            "version": "6.12.0",
+            "resolved": "https://registry.npmjs.org/qs/-/qs-6.12.0.tgz",
+            "integrity": "sha512-trVZiI6RMOkO476zLGaBIzszOdFPnCCXHPG9kn0yuS1uz6xdVxPfZdB3vUig9pxPFDM9BRAgz/YUIVQ1/vuiUg==",
             "dependencies": {
-                "side-channel": "^1.0.4"
+                "side-channel": "^1.0.6"
             },
             "engines": {
                 "node": ">=0.6"
@@ -251,9 +251,9 @@
             }
         },
         "node_modules/@gitbeaker/requester-utils": {
-            "version": "39.34.2",
-            "resolved": "https://registry.npmjs.org/@gitbeaker/requester-utils/-/requester-utils-39.34.2.tgz",
-            "integrity": "sha512-ToCwNKQe/+uHjB2kPTXY72SvbAyjsPABb9T1EiMGuVahk6rWdhtVZIM659rGuqdJGTqQ4y18wk0A+w6D3Z2lCQ==",
+            "version": "40.0.1",
+            "resolved": "https://registry.npmjs.org/@gitbeaker/requester-utils/-/requester-utils-40.0.1.tgz",
+            "integrity": "sha512-cn6fltKuQ3TbthoMTg+JsKQfozqGcRcz1jT9Nqzr4gpHWgjdQ/nr5JpjwzKABQNVL2JH3UJWr6Eji60CFZDZ6Q==",
             "dependencies": {
                 "picomatch-browser": "^2.2.6",
                 "qs": "^6.11.2",
@@ -265,11 +265,11 @@
             }
         },
         "node_modules/@gitbeaker/requester-utils/node_modules/qs": {
-            "version": "6.11.2",
-            "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz",
-            "integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==",
+            "version": "6.12.0",
+            "resolved": "https://registry.npmjs.org/qs/-/qs-6.12.0.tgz",
+            "integrity": "sha512-trVZiI6RMOkO476zLGaBIzszOdFPnCCXHPG9kn0yuS1uz6xdVxPfZdB3vUig9pxPFDM9BRAgz/YUIVQ1/vuiUg==",
             "dependencies": {
-                "side-channel": "^1.0.4"
+                "side-channel": "^1.0.6"
             },
             "engines": {
                 "node": ">=0.6"
@@ -279,12 +279,12 @@
             }
         },
         "node_modules/@gitbeaker/rest": {
-            "version": "39.34.2",
-            "resolved": "https://registry.npmjs.org/@gitbeaker/rest/-/rest-39.34.2.tgz",
-            "integrity": "sha512-MT4Vue1ltvsR7Nug18A6DIk+u+gu64+b0Un/R2XIsLB7eSAX8Pm/sQnYxsjHksroZJVlyGHiGsaxbllX75Pntg==",
+            "version": "40.0.1",
+            "resolved": "https://registry.npmjs.org/@gitbeaker/rest/-/rest-40.0.1.tgz",
+            "integrity": "sha512-JEd9WNuzgur7gLiJPMWPYKaWe5uX1ic8CGKR1fMtBityFZ2xyZkTZ+LG0nqWTV1MyiowYnJ1swTh8Yff+kLsKA==",
             "dependencies": {
-                "@gitbeaker/core": "^39.34.2",
-                "@gitbeaker/requester-utils": "^39.34.2"
+                "@gitbeaker/core": "^40.0.1",
+                "@gitbeaker/requester-utils": "^40.0.1"
             },
             "engines": {
                 "node": ">=18.0.0"
@@ -1801,14 +1801,15 @@
             }
         },
         "node_modules/call-bind": {
-            "version": "1.0.6",
-            "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.6.tgz",
-            "integrity": "sha512-Mj50FLHtlsoVfRfnHaZvyrooHcrlceNZdL/QBvJJVd9Ta55qCQK0gs4ss2oZDeV9zFCs6ewzYgVE5yfVmfFpVg==",
+            "version": "1.0.7",
+            "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
+            "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==",
             "dependencies": {
+                "es-define-property": "^1.0.0",
                 "es-errors": "^1.3.0",
                 "function-bind": "^1.1.2",
-                "get-intrinsic": "^1.2.3",
-                "set-function-length": "^1.2.0"
+                "get-intrinsic": "^1.2.4",
+                "set-function-length": "^1.2.1"
             },
             "engines": {
                 "node": ">= 0.4"
@@ -2326,17 +2327,19 @@
             }
         },
         "node_modules/define-data-property": {
-            "version": "1.1.2",
-            "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.2.tgz",
-            "integrity": "sha512-SRtsSqsDbgpJBbW3pABMCOt6rQyeM8s8RiyeSN8jYG8sYmt/kGJejbydttUsnDs1tadr19tvhT4ShwMyoqAm4g==",
+            "version": "1.1.4",
+            "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
+            "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
             "dependencies": {
+                "es-define-property": "^1.0.0",
                 "es-errors": "^1.3.0",
-                "get-intrinsic": "^1.2.2",
-                "gopd": "^1.0.1",
-                "has-property-descriptors": "^1.0.1"
+                "gopd": "^1.0.1"
             },
             "engines": {
                 "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
             }
         },
         "node_modules/delayed-stream": {
@@ -2535,6 +2538,17 @@
                 "is-arrayish": "^0.2.1"
             }
         },
+        "node_modules/es-define-property": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz",
+            "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==",
+            "dependencies": {
+                "get-intrinsic": "^1.2.4"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            }
+        },
         "node_modules/es-errors": {
             "version": "1.3.0",
             "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
@@ -3437,20 +3451,20 @@
             }
         },
         "node_modules/has-property-descriptors": {
-            "version": "1.0.1",
-            "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz",
-            "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==",
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
+            "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
             "dependencies": {
-                "get-intrinsic": "^1.2.2"
+                "es-define-property": "^1.0.0"
             },
             "funding": {
                 "url": "https://github.com/sponsors/ljharb"
             }
         },
         "node_modules/has-proto": {
-            "version": "1.0.1",
-            "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz",
-            "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==",
+            "version": "1.0.3",
+            "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz",
+            "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==",
             "engines": {
                 "node": ">= 0.4"
             },
@@ -3470,9 +3484,9 @@
             }
         },
         "node_modules/hasown": {
-            "version": "2.0.0",
-            "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz",
-            "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==",
+            "version": "2.0.2",
+            "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
+            "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
             "dependencies": {
                 "function-bind": "^1.1.2"
             },
@@ -8410,16 +8424,16 @@
             }
         },
         "node_modules/set-function-length": {
-            "version": "1.2.1",
-            "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.1.tgz",
-            "integrity": "sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==",
+            "version": "1.2.2",
+            "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
+            "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
             "dependencies": {
-                "define-data-property": "^1.1.2",
+                "define-data-property": "^1.1.4",
                 "es-errors": "^1.3.0",
                 "function-bind": "^1.1.2",
-                "get-intrinsic": "^1.2.3",
+                "get-intrinsic": "^1.2.4",
                 "gopd": "^1.0.1",
-                "has-property-descriptors": "^1.0.1"
+                "has-property-descriptors": "^1.0.2"
             },
             "engines": {
                 "node": ">= 0.4"
@@ -8512,11 +8526,11 @@
             "dev": true
         },
         "node_modules/side-channel": {
-            "version": "1.0.5",
-            "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.5.tgz",
-            "integrity": "sha512-QcgiIWV4WV7qWExbN5llt6frQB/lBven9pqliLXfGPB+K9ZYXxDozp0wLkHS24kWCm+6YXH/f0HhnObZnZOBnQ==",
+            "version": "1.0.6",
+            "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz",
+            "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==",
             "dependencies": {
-                "call-bind": "^1.0.6",
+                "call-bind": "^1.0.7",
                 "es-errors": "^1.3.0",
                 "get-intrinsic": "^1.2.4",
                 "object-inspect": "^1.13.1"
diff --git a/ExpressAPI/package.json b/ExpressAPI/package.json
index b2da7463ee002bf102ec7288d0d8c6c337b9abab..119426c43cc4492ba747bcb8a3f22958a2e55ed5 100644
--- a/ExpressAPI/package.json
+++ b/ExpressAPI/package.json
@@ -28,7 +28,7 @@
         "seed": "node dist/prisma/seed"
     },
     "dependencies"   : {
-        "@gitbeaker/rest"     : "^39.34.2",
+        "@gitbeaker/rest"     : "^40.0.1",
         "@prisma/client"      : "^5.9.1",
         "axios"               : "^1.6.7",
         "compression"         : "^1.7.4",
diff --git a/ExpressAPI/prisma/seed.ts b/ExpressAPI/prisma/seed.ts
index fc8dce5183e470dafbfd99caa6eca2de6faec393..74d814d9f269ff4ca5c3651ab743f979799758f5 100644
--- a/ExpressAPI/prisma/seed.ts
+++ b/ExpressAPI/prisma/seed.ts
@@ -17,7 +17,7 @@ async function main() {
 main().then(async () => {
     await db.$disconnect();
 }).catch(async e => {
-    logger.error(e);
+    logger.error(JSON.stringify(e));
     await db.$disconnect();
     process.exit(1);
 });
diff --git a/ExpressAPI/src/config/Config.ts b/ExpressAPI/src/config/Config.ts
index a768fded7ca22aae497741693e813a785157a61f..2eaa5ec692b2c84a82c917564ac27634c3433639 100644
--- a/ExpressAPI/src/config/Config.ts
+++ b/ExpressAPI/src/config/Config.ts
@@ -1,8 +1,8 @@
-import GitlabVisibility from '../shared/types/Gitlab/GitlabVisibility';
 import path             from 'path';
 import fs               from 'fs';
 import { Exercise }     from '../types/DatabaseTypes';
 import JSON5            from 'json5';
+import GitlabVisibility from '../shared/types/Gitlab/GitlabVisibility';
 
 
 type ConfigGitlabBadge = {
@@ -52,13 +52,13 @@ class Config {
 
     public readonly assignment: {
         default: {
-            description: string; initReadme: boolean; sharedRunnersEnabled: boolean; visibility: string; wikiEnabled: boolean; template: string
+            description: string; initReadme: boolean; sharedRunnersEnabled: boolean; visibility: GitlabVisibility; wikiEnabled: boolean; template: string
         }; baseFiles: Array<string>; filename: string
     };
 
     public readonly exercise: {
         maxSameName: number; maxPerAssignment: number; resultsFolder: string, pipelineResultsFolder: string; default: {
-            description: string; visibility: string;
+            description: string; visibility: GitlabVisibility;
         };
     };
 
@@ -116,7 +116,7 @@ class Config {
                 description         : process.env.ASSIGNMENT_DEFAULT_DESCRIPTION?.convertWithEnvVars() ?? '',
                 initReadme          : process.env.ASSIGNMENT_DEFAULT_INIT_README?.toBoolean() ?? false,
                 sharedRunnersEnabled: process.env.ASSIGNMENT_DEFAULT_SHARED_RUNNERS_ENABLED?.toBoolean() ?? true,
-                visibility          : process.env.ASSIGNMENT_DEFAULT_VISIBILITY || GitlabVisibility.PRIVATE,
+                visibility          : process.env.ASSIGNMENT_DEFAULT_VISIBILITY as GitlabVisibility || 'private',
                 wikiEnabled         : process.env.ASSIGNMENT_DEFAULT_WIKI_ENABLED?.toBoolean() ?? false,
                 template            : process.env.ASSIGNMENT_DEFAULT_TEMPLATE?.replace('{{USERNAME}}', this.gitlab.account.username).replace('{{TOKEN}}', this.gitlab.account.token) ?? ''
             },
@@ -131,7 +131,7 @@ class Config {
             pipelineResultsFolder: process.env.EXERCISE_PIPELINE_RESULTS_FOLDER ?? '', //Do not use convertWithEnvVars() because it is used in the exercise creation and muste be interpreted at exercise runtime
             default              : {
                 description: process.env.EXERCISE_DEFAULT_DESCRIPTION?.convertWithEnvVars() ?? '',
-                visibility : process.env.EXERCISE_DEFAULT_VISIBILITY || GitlabVisibility.PRIVATE
+                visibility : process.env.EXERCISE_DEFAULT_VISIBILITY as GitlabVisibility || 'private'
             }
         };
     }
diff --git a/ExpressAPI/src/express/API.ts b/ExpressAPI/src/express/API.ts
index 0f885ecf1ca1297c12abbc42b0c384a20521ccf7..519918ef7da595f36394abd87f6d58c2aa6ea273 100644
--- a/ExpressAPI/src/express/API.ts
+++ b/ExpressAPI/src/express/API.ts
@@ -21,7 +21,7 @@ import DojoCliVersionHelper           from '../helpers/DojoCliVersionHelper';
 
 class API implements WorkerTask {
     private readonly backend: Express;
-    private server: http.Server | undefined;
+    private server!: http.Server;
 
     constructor() {
         this.backend = express();
@@ -38,9 +38,7 @@ class API implements WorkerTask {
 
     private initBaseMiddlewares() {
         this.backend.use(multer({
-                                    limits: {
-                                        fieldSize: 15728640 // 15MB
-                                    }
+                                    limits: { fieldSize: 100 * 1024 * 1024 }
                                 }).none()); //Used for extract params from body with format "form-data", The none is for say that we do not wait a file in params
         this.backend.use(morganMiddleware); //Log API accesses
         this.backend.use(helmet()); //Help to secure express, https://helmetjs.github.io/
@@ -91,7 +89,7 @@ class API implements WorkerTask {
             const {
                       port,
                       address
-                  } = this.server!.address() as AddressInfo;
+                  } = this.server.address() as AddressInfo;
             logger.info(`Server started on http://${ address }:${ port }`);
         });
     }
diff --git a/ExpressAPI/src/helpers/DojoCliVersionHelper.ts b/ExpressAPI/src/helpers/DojoCliVersionHelper.ts
index 962bf1c1d41ed2d9da7c8dfbac9fb9c51be8396e..4fd8d2505f55d38cd7f0925c94a6b23eb154d9aa 100644
--- a/ExpressAPI/src/helpers/DojoCliVersionHelper.ts
+++ b/ExpressAPI/src/helpers/DojoCliVersionHelper.ts
@@ -1,6 +1,6 @@
 import Config        from '../config/Config';
-import GitlabRelease from '../shared/types/Gitlab/GitlabRelease';
 import GitlabManager from '../managers/GitlabManager';
+import * as Gitlab   from '@gitbeaker/rest';
 
 
 class DojoCliVersionHelper {
@@ -8,7 +8,7 @@ class DojoCliVersionHelper {
     private latestVersion: string | undefined;
 
     private async updateVersion(): Promise<void> {
-        const releases: Array<GitlabRelease> = await GitlabManager.getRepositoryReleases(Config.dojoCLI.repositoryId);
+        const releases: Array<Gitlab.ReleaseSchema> = await GitlabManager.getRepositoryReleases(Config.dojoCLI.repositoryId);
         for ( const release of releases ) {
             if ( !isNaN(+release.tag_name.replace('.', '')) ) {
                 this.latestVersion = release.tag_name;
diff --git a/ExpressAPI/src/helpers/DojoValidators.ts b/ExpressAPI/src/helpers/DojoValidators.ts
index 442f1608730d62f94772846d00fdfc28235d4406..26f60f4ce97d986c2ba2867ad268d79a43ce34c6 100644
--- a/ExpressAPI/src/helpers/DojoValidators.ts
+++ b/ExpressAPI/src/helpers/DojoValidators.ts
@@ -34,7 +34,7 @@ class DojoValidators {
                                                                    try {
                                                                        return value === 'null' || value === 'undefined' || value === '' ? null : value;
                                                                    } catch ( error ) {
-                                                                       logger.error(`null sanitizer error: ${ error }`);
+                                                                       logger.error(`null sanitizer error: ${ JSON.stringify(error) }`);
 
                                                                        return value;
                                                                    }
@@ -84,7 +84,7 @@ class DojoValidators {
                                                                                   return Config.assignment.default.template;
                                                                               }
                                                                           } catch ( error ) {
-                                                                              logger.error(`Template url sanitizer error: ${ error }`);
+                                                                              logger.error(`Template url sanitizer error: ${ JSON.stringify(error) }`);
 
                                                                               return value;
                                                                           }
diff --git a/ExpressAPI/src/helpers/GlobalHelper.ts b/ExpressAPI/src/helpers/GlobalHelper.ts
index e7e6e344f29769d48a8517d77ec7eb0b7493aa2d..6bd7b8890dd7b08c7f3188ac5fc0100d0da57dcc 100644
--- a/ExpressAPI/src/helpers/GlobalHelper.ts
+++ b/ExpressAPI/src/helpers/GlobalHelper.ts
@@ -1,31 +1,59 @@
-import express          from 'express';
-import GitlabRepository from '../shared/types/Gitlab/GitlabRepository';
-import logger           from '../shared/logging/WinstonLogger';
-import GitlabManager    from '../managers/GitlabManager';
-import { AxiosError }   from 'axios';
-import { StatusCodes }  from 'http-status-codes';
-import DojoStatusCode   from '../shared/types/Dojo/DojoStatusCode';
+import express                   from 'express';
+import logger                    from '../shared/logging/WinstonLogger';
+import GitlabManager             from '../managers/GitlabManager';
+import DojoStatusCode            from '../shared/types/Dojo/DojoStatusCode';
+import { StatusCodes }           from 'http-status-codes';
+import { GitbeakerRequestError } from '@gitbeaker/requester-utils';
+import * as Gitlab               from '@gitbeaker/rest';
 
 
 class GlobalHelper {
-    async repositoryCreationError(message: string, error: unknown, req: express.Request, res: express.Response, gitlabError: DojoStatusCode, internalError: DojoStatusCode, repositoryToRemove?: GitlabRepository): Promise<void> {
-        logger.error(message);
-        logger.error(error);
+    repoCreationFnExecCreator(req: express.Request, res: express.Response, gitlabError: DojoStatusCode, internalError: DojoStatusCode, repositoryToRemove?: Gitlab.ProjectSchema) {
+        return async (toExec: () => Promise<unknown>, errorMessage?: string) => {
+            try {
+                return await toExec();
+            } catch ( error ) {
+                if ( errorMessage ) {
+                    logger.error(errorMessage);
+                    logger.error(JSON.stringify(error));
 
-        try {
-            if ( repositoryToRemove ) {
-                await GitlabManager.deleteRepository(repositoryToRemove.id);
+                    try {
+                        if ( repositoryToRemove ) {
+                            await GitlabManager.deleteRepository(repositoryToRemove.id);
+                        }
+                    } catch ( deleteError ) {
+                        logger.error('Repository deletion error');
+                        logger.error(JSON.stringify(deleteError));
+                    }
+
+                    if ( error instanceof GitbeakerRequestError ) {
+                        req.session.sendResponse(res, StatusCodes.INTERNAL_SERVER_ERROR, {}, `Unknown gitlab error: ${ errorMessage }`, gitlabError);
+                        throw error;
+                    }
+
+                    req.session.sendResponse(res, StatusCodes.INTERNAL_SERVER_ERROR, {}, `Unknown error: ${ errorMessage }`, internalError);
+                    throw error;
+                }
             }
-        } catch ( deleteError ) {
-            logger.error('Repository deletion error');
-            logger.error(deleteError);
-        }
 
-        if ( error instanceof AxiosError ) {
-            return req.session.sendResponse(res, StatusCodes.INTERNAL_SERVER_ERROR, {}, `Unknown gitlab error: ${ message }`, gitlabError);
-        }
+            return undefined;
+        };
+    }
+
+    isRepoNameAlreadyTaken(errorDescription: unknown) {
+        return errorDescription instanceof Object && 'name' in errorDescription && errorDescription.name instanceof Array && errorDescription.name.length > 0 && errorDescription.name[0] === 'has already been taken';
+    }
 
-        return req.session.sendResponse(res, StatusCodes.INTERNAL_SERVER_ERROR, {}, `Unknown error: ${ message }`, internalError);
+    addRepoMember(repositoryId: number) {
+        return async (memberId: number): Promise<Gitlab.MemberSchema | false> => {
+            try {
+                return await GitlabManager.addRepositoryMember(repositoryId, memberId, Gitlab.AccessLevel.DEVELOPER);
+            } catch ( error ) {
+                logger.error('Add member error');
+                logger.error(JSON.stringify(error));
+                return false;
+            }
+        };
     }
 }
 
diff --git a/ExpressAPI/src/helpers/Prisma/Extensions/UserResultExtension.ts b/ExpressAPI/src/helpers/Prisma/Extensions/UserResultExtension.ts
index 8a8640ea20e19fa9df3692a920a7cb05f0a4fb6a..af63f05ed484cf5de6bd45421f484627a6845e63 100644
--- a/ExpressAPI/src/helpers/Prisma/Extensions/UserResultExtension.ts
+++ b/ExpressAPI/src/helpers/Prisma/Extensions/UserResultExtension.ts
@@ -1,6 +1,6 @@
 import { Prisma, UserRole } from '@prisma/client';
 import LazyVal              from '../../../shared/helpers/LazyVal';
-import GitlabUser           from '../../../shared/types/Gitlab/GitlabUser';
+import * as Gitlab          from '@gitbeaker/rest';
 import GitlabManager        from '../../../managers/GitlabManager';
 
 
@@ -26,7 +26,7 @@ export default Prisma.defineExtension(client => {
                                        },
                                        gitlabProfile  : {
                                            compute(user) {
-                                               return new LazyVal<GitlabUser | undefined>(() => GitlabManager.getUserById(user.id));
+                                               return new LazyVal<Gitlab.UserSchema | undefined>(() => GitlabManager.getUserById(user.id));
                                            }
                                        }
                                    }
diff --git a/ExpressAPI/src/managers/AssignmentManager.ts b/ExpressAPI/src/managers/AssignmentManager.ts
index ad51e6b80209bfd4b9b623720d7968672e2a9ad0..9053b8e5ef05469e31c55be50476d98bbb70308d 100644
--- a/ExpressAPI/src/managers/AssignmentManager.ts
+++ b/ExpressAPI/src/managers/AssignmentManager.ts
@@ -45,7 +45,6 @@ class AssignmentManager {
         } else {
             return this.getByName(nameOrUrl, include);
         }
-
     }
 }
 
diff --git a/ExpressAPI/src/managers/GitlabManager.ts b/ExpressAPI/src/managers/GitlabManager.ts
index 528d24dd41e5da167008484c70f0802eb05b0353..f48e9391cad444bf03d0660a3392ef1b08be9f5b 100644
--- a/ExpressAPI/src/managers/GitlabManager.ts
+++ b/ExpressAPI/src/managers/GitlabManager.ts
@@ -1,86 +1,39 @@
-import axios                    from 'axios';
-import Config                   from '../config/Config';
-import GitlabRepository         from '../shared/types/Gitlab/GitlabRepository';
-import GitlabAccessLevel        from '../shared/types/Gitlab/GitlabAccessLevel';
-import GitlabMember             from '../shared/types/Gitlab/GitlabMember';
-import { StatusCodes }          from 'http-status-codes';
-import GitlabVisibility         from '../shared/types/Gitlab/GitlabVisibility';
-import GitlabUser               from '../shared/types/Gitlab/GitlabUser';
-import GitlabTreeFile           from '../shared/types/Gitlab/GitlabTreeFile';
-import parseLinkHeader          from 'parse-link-header';
-import GitlabFile               from '../shared/types/Gitlab/GitlabFile';
-import express                  from 'express';
-import GitlabRoute              from '../shared/types/Gitlab/GitlabRoute';
-import SharedConfig             from '../shared/config/SharedConfig';
-import GitlabProfile            from '../shared/types/Gitlab/GitlabProfile';
-import GitlabRelease            from '../shared/types/Gitlab/GitlabRelease';
-import { CommitSchema, Gitlab } from '@gitbeaker/rest';
-import logger                   from '../shared/logging/WinstonLogger';
-import DojoStatusCode           from '../shared/types/Dojo/DojoStatusCode';
+import Config                                                                                                                                                                                 from '../config/Config';
+import { StatusCodes }                                                                                                                                                                        from 'http-status-codes';
+import GitlabVisibility                                                                                                                                                                       from '../shared/types/Gitlab/GitlabVisibility';
+import express                                                                                                                                                                                from 'express';
+import SharedConfig                                                                                                                                                                           from '../shared/config/SharedConfig';
+import { CommitSchema, ExpandedUserSchema, Gitlab, MemberSchema, ProjectBadgeSchema, ProjectSchema, ReleaseSchema, RepositoryFileExpandedSchema, RepositoryFileSchema, RepositoryTreeSchema } from '@gitbeaker/rest';
+import logger                                                                                                                                                                                 from '../shared/logging/WinstonLogger';
+import { AccessLevel, EditProjectOptions, ProjectVariableSchema, ProtectedBranchAccessLevel, ProtectedBranchSchema }                                                                          from '@gitbeaker/core';
+import DojoStatusCode                                                                                                                                                                         from '../shared/types/Dojo/DojoStatusCode';
+import SharedGitlabManager                                                                                                                                                                    from '../shared/managers/SharedGitlabManager';
 
 
-class GitlabManager {
-    readonly api = new Gitlab({
-                                  host : SharedConfig.gitlab.URL,
-                                  token: Config.gitlab.account.token
-                              });
-
-    private getApiUrl(route: GitlabRoute): string {
-        return `${ SharedConfig.gitlab.apiURL }${ route }`;
-    }
-
-    public async getUserProfile(token: string): Promise<GitlabProfile | undefined> {
-        try {
-            return (await axios.get<GitlabProfile>(this.getApiUrl(GitlabRoute.PROFILE_GET), {
-                headers: {
-                    DojoOverrideAuthorization: true,
-                    DojoAuthorizationHeader  : 'Authorization',
-                    DojoAuthorizationValue   : `Bearer ${ token }`
-                }
-            })).data;
-        } catch ( e ) {
-            return undefined;
-        }
+class GitlabManager extends SharedGitlabManager {
+    constructor() {
+        super(Config.gitlab.account.token);
     }
 
-    public async getUserById(id: number): Promise<GitlabUser | undefined> {
+    getUserProfile(token: string): Promise<ExpandedUserSchema> | undefined {
         try {
-            const user = (await axios.get<GitlabUser>(`${ this.getApiUrl(GitlabRoute.USERS_GET) }/${ String(id) }`)).data;
+            const profileApi = new Gitlab({
+                                              host      : SharedConfig.gitlab.URL,
+                                              oauthToken: token
+                                          });
 
-            return user.id === id ? user : undefined;
+            return profileApi.Users.showCurrentUser();
         } catch ( e ) {
             return undefined;
         }
     }
 
-    public async getUserByUsername(username: string): Promise<GitlabUser | undefined> {
-        try {
-            const params: Record<string, string> = {};
-            params['search'] = username;
-            const user = (await axios.get<Array<GitlabUser>>(this.getApiUrl(GitlabRoute.USERS_GET), { params: params })).data[0];
-
-            return user.username === username ? user : undefined;
-        } catch ( e ) {
-            return undefined;
-        }
-    }
-
-    async getRepository(projectIdOrNamespace: string): Promise<GitlabRepository> {
-        const response = await axios.get<GitlabRepository>(this.getApiUrl(GitlabRoute.REPOSITORY_GET).replace('{{id}}', encodeURIComponent(projectIdOrNamespace)));
-
-        return response.data;
+    getRepositoryMembers(idOrNamespace: string): Promise<Array<MemberSchema>> {
+        return this.api.ProjectMembers.all(idOrNamespace, { includeInherited: true });
     }
 
-    async getRepositoryMembers(idOrNamespace: string): Promise<Array<GitlabMember>> {
-        const response = await axios.get<Array<GitlabMember>>(this.getApiUrl(GitlabRoute.REPOSITORY_MEMBERS_GET).replace('{{id}}', encodeURIComponent(idOrNamespace)));
-
-        return response.data;
-    }
-
-    async getRepositoryReleases(repoId: number): Promise<Array<GitlabRelease>> {
-        const response = await axios.get<Array<GitlabRelease>>(this.getApiUrl(GitlabRoute.REPOSITORY_RELEASES_GET).replace('{{id}}', String(repoId)));
-
-        return response.data;
+    getRepositoryReleases(repoId: number): Promise<Array<ReleaseSchema>> {
+        return this.api.ProjectReleases.all(repoId);
     }
 
     async getRepositoryLastCommit(repoId: number, branch: string = 'main'): Promise<CommitSchema | undefined> {
@@ -93,89 +46,70 @@ class GitlabManager {
 
             return commits.length > 0 ? commits[0] : undefined;
         } catch ( e ) {
-            logger.error(e);
+            logger.error(JSON.stringify(e));
             return undefined;
         }
     }
 
-    async createRepository(name: string, description: string, visibility: string, initializeWithReadme: boolean, namespace: number, sharedRunnersEnabled: boolean, wikiEnabled: boolean, importUrl: string): Promise<GitlabRepository> {
-        const response = await axios.post<GitlabRepository>(this.getApiUrl(GitlabRoute.REPOSITORY_CREATE), {
-            name                  : name,
-            description           : description,
-            import_url            : importUrl,
-            initialize_with_readme: initializeWithReadme,
-            namespace_id          : namespace,
-            shared_runners_enabled: sharedRunnersEnabled,
-            visibility            : visibility,
-            wiki_enabled          : wikiEnabled
-        });
-
-        return response.data;
+    createRepository(name: string, description: string, visibility: 'public' | 'internal' | 'private', initializeWithReadme: boolean, namespace: number, sharedRunnersEnabled: boolean, wikiEnabled: boolean, importUrl: string): Promise<ProjectSchema> {
+        return this.api.Projects.create({
+                                            name                : name,
+                                            description         : description,
+                                            importUrl           : importUrl,
+                                            initializeWithReadme: initializeWithReadme,
+                                            namespaceId         : namespace,
+                                            sharedRunnersEnabled: sharedRunnersEnabled,
+                                            visibility          : visibility,
+                                            wikiAccessLevel     : wikiEnabled ? 'enabled' : 'disabled'
+                                        });
     }
 
     deleteRepository(repoId: number): Promise<void> {
-        return axios.delete(this.getApiUrl(GitlabRoute.REPOSITORY_DELETE).replace('{{id}}', String(repoId)));
+        return this.api.Projects.remove(repoId);
     }
 
-    async forkRepository(forkId: number, name: string, path: string, description: string, visibility: string, namespace: number): Promise<GitlabRepository> {
-        const response = await axios.post<GitlabRepository>(this.getApiUrl(GitlabRoute.REPOSITORY_FORK).replace('{{id}}', String(forkId)), {
-            name        : name,
-            path        : path,
-            description : description,
-            namespace_id: namespace,
-            visibility  : visibility
+    forkRepository(forkId: number, name: string, path: string, description: string, visibility: 'public' | 'internal' | 'private', namespace: number): Promise<ProjectSchema> {
+        return this.api.Projects.fork(forkId, {
+            name       : name,
+            path       : path,
+            description: description,
+            namespaceId: namespace,
+            visibility : visibility
         });
-
-        return response.data;
     }
 
-    async editRepository(repoId: number, newAttributes: Partial<GitlabRepository>): Promise<GitlabRepository> {
-        const response = await axios.put<GitlabRepository>(this.getApiUrl(GitlabRoute.REPOSITORY_EDIT).replace('{{id}}', String(repoId)), newAttributes);
-
-        return response.data;
+    editRepository(repoId: number, newAttributes: EditProjectOptions): Promise<ProjectSchema> {
+        return this.api.Projects.edit(repoId, newAttributes);
     }
 
-    changeRepositoryVisibility(repoId: number, visibility: GitlabVisibility): Promise<GitlabRepository> {
-        return this.editRepository(repoId, { visibility: visibility.toString() });
+    changeRepositoryVisibility(repoId: number, visibility: GitlabVisibility): Promise<ProjectSchema> {
+        return this.editRepository(repoId, { visibility: visibility });
     }
 
-    async addRepositoryMember(repoId: number, userId: number, accessLevel: GitlabAccessLevel): Promise<GitlabMember> {
-        const response = await axios.post<GitlabMember>(this.getApiUrl(GitlabRoute.REPOSITORY_MEMBER_ADD).replace('{{id}}', String(repoId)), {
-            user_id     : userId,
-            access_level: accessLevel
-        });
-
-        return response.data;
+    addRepositoryMember(repoId: number, userId: number, accessLevel: Exclude<AccessLevel, AccessLevel.ADMIN>): Promise<MemberSchema> {
+        return this.api.ProjectMembers.add(repoId, userId, accessLevel);
     }
 
-    async addRepositoryVariable(repoId: number, key: string, value: string, isProtected: boolean, isMasked: boolean): Promise<GitlabMember> {
-        const response = await axios.post<GitlabMember>(this.getApiUrl(GitlabRoute.REPOSITORY_VARIABLES_ADD).replace('{{id}}', String(repoId)), {
-            key          : key,
-            variable_type: 'env_var',
-            value        : value,
-            protected    : isProtected,
-            masked       : isMasked
+    addRepositoryVariable(repoId: number, key: string, value: string, isProtected: boolean, isMasked: boolean): Promise<ProjectVariableSchema> {
+        return this.api.ProjectVariables.create(repoId, key, value, {
+            variableType: 'env_var',
+            protected   : isProtected,
+            masked      : isMasked
         });
-
-        return response.data;
     }
 
-    async addRepositoryBadge(repoId: number, linkUrl: string, imageUrl: string, name: string): Promise<GitlabMember> {
-        const response = await axios.post<GitlabMember>(this.getApiUrl(GitlabRoute.REPOSITORY_BADGES_ADD).replace('{{id}}', String(repoId)), {
-            link_url : linkUrl,
-            image_url: imageUrl,
-            name     : name
+    addRepositoryBadge(repoId: number, linkUrl: string, imageUrl: string, name: string): Promise<ProjectBadgeSchema> {
+        return this.api.ProjectBadges.add(repoId, linkUrl, imageUrl, {
+            name: name
         });
-
-        return response.data;
     }
 
     async checkTemplateAccess(projectIdOrNamespace: string, req: express.Request, res?: express.Response): Promise<boolean> {
         // Get the Gitlab project and check if it have public or internal visibility
         try {
-            const project: GitlabRepository = await this.getRepository(projectIdOrNamespace);
+            const project: ProjectSchema = await this.getRepository(projectIdOrNamespace);
 
-            if ( [ GitlabVisibility.PUBLIC.valueOf(), GitlabVisibility.INTERNAL.valueOf() ].includes(project.visibility) ) {
+            if ( [ 'public', 'internal' ].includes(project.visibility) ) {
                 req.session.sendResponse(res, StatusCodes.OK);
                 return true;
             }
@@ -191,7 +125,7 @@ class GitlabManager {
             dojo: false
         };
         members.forEach(member => {
-            if ( member.access_level >= GitlabAccessLevel.REPORTER ) {
+            if ( member.access_level >= AccessLevel.REPORTER ) {
                 if ( member.id === req.session.profile.id ) {
                     isUsersAtLeastReporter.user = true;
                 } else if ( member.id === Config.gitlab.account.id ) {
@@ -209,91 +143,49 @@ class GitlabManager {
         }
     }
 
-    async protectBranch(repoId: number, branchName: string, allowForcePush: boolean, allowedToMerge: GitlabAccessLevel, allowedToPush: GitlabAccessLevel, allowedToUnprotect: GitlabAccessLevel): Promise<GitlabMember> {
-        const response = await axios.post<GitlabMember>(this.getApiUrl(GitlabRoute.REPOSITORY_BRANCHES_PROTECT).replace('{{id}}', String(repoId)), {
-            name                  : branchName,
-            allow_force_push      : allowForcePush,
-            merge_access_level    : allowedToMerge.valueOf(),
-            push_access_level     : allowedToPush.valueOf(),
-            unprotect_access_level: allowedToUnprotect.valueOf()
+    protectBranch(repoId: number, branchName: string, allowForcePush: boolean, allowedToMerge: ProtectedBranchAccessLevel, allowedToPush: ProtectedBranchAccessLevel, allowedToUnprotect: ProtectedBranchAccessLevel): Promise<ProtectedBranchSchema> {
+        return this.api.ProtectedBranches.protect(repoId, branchName, {
+            allowForcePush      : allowForcePush,
+            mergeAccessLevel    : allowedToMerge,
+            pushAccessLevel     : allowedToPush,
+            unprotectAccessLevel: allowedToUnprotect
         });
-
-        return response.data;
     }
 
-    async getRepositoryTree(repoId: number, recursive: boolean = true, branch: string = 'main'): Promise<Array<GitlabTreeFile>> {
-        const address: string | undefined = this.getApiUrl(GitlabRoute.REPOSITORY_TREE).replace('{{id}}', String(repoId));
-        let params: Partial<parseLinkHeader.Link | { recursive: boolean, per_page: number }> | undefined = {
-            pagination: 'keyset',
-            recursive : recursive,
-            per_page  : 100,
-            ref       : branch
-        };
-
-        const results: Array<GitlabTreeFile> = [];
-
-        while ( params !== undefined ) {
-            const response = await axios.get<Array<GitlabTreeFile>>(address, {
-                params: params
-            });
-
-            results.push(...response.data);
-
-            if ( 'link' in response.headers ) {
-                params = parseLinkHeader(response.headers['link'])?.next ?? undefined;
-            } else {
-                params = undefined;
-            }
-        }
-
-        return results;
-    }
-
-    private getRepositoryFileUrl(repoId: number, filePath: string): string {
-        return this.getApiUrl(GitlabRoute.REPOSITORY_FILE).replace('{{id}}', String(repoId)).replace('{{filePath}}', encodeURIComponent(filePath));
-    }
-
-    async getFile(repoId: number, filePath: string, branch: string = 'main'): Promise<GitlabFile> {
-        const response = await axios.get<GitlabFile>(this.getRepositoryFileUrl(repoId, filePath), {
-            params: {
-                ref: branch
-            }
+    getRepositoryTree(repoId: number, recursive: boolean = true, branch: string = 'main'): Promise<Array<RepositoryTreeSchema>> {
+        return this.api.Repositories.allRepositoryTrees(repoId, {
+            recursive: recursive,
+            ref      : branch
         });
+    }
 
-        return response.data;
+    getFile(repoId: number, filePath: string, branch: string = 'main'): Promise<RepositoryFileExpandedSchema> {
+        return this.api.RepositoryFiles.show(repoId, filePath, branch);
     }
 
-    private async createUpdateFile(create: boolean, repoId: number, filePath: string, fileBase64: string, commitMessage: string, branch: string = 'main', authorName: string = 'Dojo', authorMail: string | undefined = undefined) {
-        const axiosFunction = create ? axios.post : axios.put;
+    private createUpdateFile(create: boolean, repoId: number, filePath: string, fileBase64: string, commitMessage: string, branch: string = 'main', authorName: string = 'Dojo', authorMail: string | undefined = undefined): Promise<RepositoryFileSchema> {
+        const gitFunction = create ? this.api.RepositoryFiles.create.bind(this.api) : this.api.RepositoryFiles.edit.bind(this.api);
 
-        await axiosFunction(this.getRepositoryFileUrl(repoId, filePath), {
-            encoding      : 'base64',
-            branch        : branch,
-            commit_message: commitMessage,
-            content       : fileBase64,
-            author_name   : authorName,
-            author_email  : authorMail
+        return gitFunction(repoId, filePath, branch, fileBase64, commitMessage, {
+            encoding   : 'base64',
+            authorName : authorName,
+            authorEmail: authorMail
         });
     }
 
-    async createFile(repoId: number, filePath: string, fileBase64: string, commitMessage: string, branch: string = 'main', authorName: string = 'Dojo', authorMail: string | undefined = undefined) {
+    createFile(repoId: number, filePath: string, fileBase64: string, commitMessage: string, branch: string = 'main', authorName: string = 'Dojo', authorMail: string | undefined = undefined): Promise<RepositoryFileSchema> {
         return this.createUpdateFile(true, repoId, filePath, fileBase64, commitMessage, branch, authorName, authorMail);
     }
 
-    async updateFile(repoId: number, filePath: string, fileBase64: string, commitMessage: string, branch: string = 'main', authorName: string = 'Dojo', authorMail: string | undefined = undefined) {
+    updateFile(repoId: number, filePath: string, fileBase64: string, commitMessage: string, branch: string = 'main', authorName: string = 'Dojo', authorMail: string | undefined = undefined): Promise<RepositoryFileSchema> {
         return this.createUpdateFile(false, repoId, filePath, fileBase64, commitMessage, branch, authorName, authorMail);
     }
 
-    async deleteFile(repoId: number, filePath: string, commitMessage: string, branch: string = 'main', authorName: string = 'Dojo', authorMail: string | undefined = undefined) {
-        await axios.delete(this.getRepositoryFileUrl(repoId, filePath), {
-            data: {
-                branch        : branch,
-                commit_message: commitMessage,
-                author_name   : authorName,
-                author_email  : authorMail
-            }
+    deleteFile(repoId: number, filePath: string, commitMessage: string, branch: string = 'main', authorName: string = 'Dojo', authorMail: string | undefined = undefined): Promise<void> {
+        return this.api.RepositoryFiles.remove(repoId, filePath, branch, commitMessage, {
+            authorName : authorName,
+            authorEmail: authorMail
         });
-
     }
 }
 
diff --git a/ExpressAPI/src/managers/HttpManager.ts b/ExpressAPI/src/managers/HttpManager.ts
index e67828d06b4b4289b74d241e1c0aa60b25d280be..408adc592d9119e511e1eff457cfde149937c68f 100644
--- a/ExpressAPI/src/managers/HttpManager.ts
+++ b/ExpressAPI/src/managers/HttpManager.ts
@@ -1,8 +1,6 @@
 import axios, { AxiosError, AxiosRequestHeaders } from 'axios';
-import Config                                     from '../config/Config';
 import FormData                                   from 'form-data';
 import logger                                     from '../shared/logging/WinstonLogger';
-import SharedConfig                               from '../shared/config/SharedConfig';
 
 
 class HttpManager {
@@ -16,19 +14,6 @@ class HttpManager {
             if ( config.data instanceof FormData ) {
                 config.headers = { ...config.headers, ...(config.data as FormData).getHeaders() } as AxiosRequestHeaders;
             }
-
-            if ( config.url && config.url.indexOf(SharedConfig.gitlab.apiURL) !== -1 && !config.headers.DojoOverrideAuthorization ) {
-                config.headers['PRIVATE-TOKEN'] = Config.gitlab.account.token;
-            }
-
-            if ( config.headers.DojoOverrideAuthorization && 'DojoAuthorizationHeader' in config.headers && 'DojoAuthorizationValue' in config.headers ) {
-                config.headers[config.headers.DojoAuthorizationHeader] = config.headers.DojoAuthorizationValue;
-
-                delete config.headers.DojoOverrideAuthorization;
-                delete config.headers.DojoAuthorizationHeader;
-                delete config.headers.DojoAuthorizationValue;
-            }
-
             return config;
         });
     }
diff --git a/ExpressAPI/src/managers/UserManager.ts b/ExpressAPI/src/managers/UserManager.ts
index 686ee267551004d22b1745e93f343c30c21aec02..6008cf5d7d301e02fbd83919f076d29193cf5bac 100644
--- a/ExpressAPI/src/managers/UserManager.ts
+++ b/ExpressAPI/src/managers/UserManager.ts
@@ -1,8 +1,7 @@
-import GitlabUser    from '../shared/types/Gitlab/GitlabUser';
-import { Prisma }    from '@prisma/client';
-import db            from '../helpers/DatabaseHelper';
-import GitlabProfile from '../shared/types/Gitlab/GitlabProfile';
-import { User }      from '../types/DatabaseTypes';
+import { Prisma }  from '@prisma/client';
+import db          from '../helpers/DatabaseHelper';
+import { User }    from '../types/DatabaseTypes';
+import * as Gitlab from '@gitbeaker/rest';
 
 
 class UserManager {
@@ -24,7 +23,7 @@ class UserManager {
                                         }) as unknown as User ?? undefined;
     }
 
-    async getUpdateFromGitlabProfile(gitlabProfile: GitlabProfile): Promise<User> {
+    async getUpdateFromGitlabProfile(gitlabProfile: Gitlab.ExpandedUserSchema): Promise<User> {
         await db.user.upsert({
                                  where : {
                                      id: gitlabProfile.id
@@ -46,7 +45,7 @@ class UserManager {
         return (await this.getById(gitlabProfile.id))!;
     }
 
-    async getFromGitlabUser(gitlabUser: GitlabUser, createIfNotExist: boolean = false, include: Prisma.UserInclude | undefined = undefined): Promise<User | number | undefined> {
+    async getFromGitlabUser(gitlabUser: Gitlab.UserSchema, createIfNotExist: boolean = false, include: Prisma.UserInclude | undefined = undefined): Promise<User | number | undefined> {
         let user = await this.getById(gitlabUser.id, include) ?? gitlabUser.id;
 
         if ( typeof user === 'number' && createIfNotExist ) {
@@ -61,7 +60,7 @@ class UserManager {
         return user;
     }
 
-    async getFromGitlabUsers(gitlabUsers: Array<GitlabUser>, createIfNotExist: boolean = false, include: Prisma.UserInclude | undefined = undefined): Promise<Array<User | number | undefined>> {
+    async getFromGitlabUsers(gitlabUsers: Array<Gitlab.UserSchema>, createIfNotExist: boolean = false, include: Prisma.UserInclude | undefined = undefined): Promise<Array<User | number | undefined>> {
         return Promise.all(gitlabUsers.map(gitlabUser => this.getFromGitlabUser(gitlabUser, createIfNotExist, include)));
     }
 }
diff --git a/ExpressAPI/src/middlewares/ClientVersionCheckerMiddleware.ts b/ExpressAPI/src/middlewares/ClientVersionCheckerMiddleware.ts
index 952fd955aea5dc836081f48a0db33d8a7ac20b4e..f58b2b761a13d06482652eab64594234ac906f92 100644
--- a/ExpressAPI/src/middlewares/ClientVersionCheckerMiddleware.ts
+++ b/ExpressAPI/src/middlewares/ClientVersionCheckerMiddleware.ts
@@ -1,9 +1,9 @@
-import express            from 'express';
-import Config             from '../config/Config';
-import semver             from 'semver/preload';
-import Session            from '../controllers/Session';
-import { HttpStatusCode } from 'axios';
-import DojoStatusCode     from '../shared/types/Dojo/DojoStatusCode';
+import express         from 'express';
+import Config          from '../config/Config';
+import semver          from 'semver/preload';
+import Session         from '../controllers/Session';
+import DojoStatusCode  from '../shared/types/Dojo/DojoStatusCode';
+import { StatusCodes } from 'http-status-codes';
 
 
 class ClientVersionCheckerMiddleware {
@@ -19,13 +19,13 @@ class ClientVersionCheckerMiddleware {
                             next();
                             return;
                         } else {
-                            new Session().sendResponse(res, HttpStatusCode.MethodNotAllowed, {}, `Client version ${ requestClientVersion } is not supported. Please update your client.`, DojoStatusCode.CLIENT_VERSION_NOT_SUPPORTED);
+                            new Session().sendResponse(res, StatusCodes.METHOD_NOT_ALLOWED, {}, `Client version ${ requestClientVersion } is not supported. Please update your client.`, DojoStatusCode.CLIENT_VERSION_NOT_SUPPORTED);
                             return;
                         }
                     }
                 }
 
-                new Session().sendResponse(res, HttpStatusCode.MethodNotAllowed, {}, `Unsupported client.`, DojoStatusCode.CLIENT_NOT_SUPPORTED);
+                new Session().sendResponse(res, StatusCodes.METHOD_NOT_ALLOWED, {}, `Unsupported client.`, DojoStatusCode.CLIENT_NOT_SUPPORTED);
             } else {
                 next();
             }
diff --git a/ExpressAPI/src/middlewares/SecurityMiddleware.ts b/ExpressAPI/src/middlewares/SecurityMiddleware.ts
index 6b4a0756419e4b5052988c6cf08cc5c527b2ba70..a3a505902c4ef17af352f5023e3198fd1bbdf506 100644
--- a/ExpressAPI/src/middlewares/SecurityMiddleware.ts
+++ b/ExpressAPI/src/middlewares/SecurityMiddleware.ts
@@ -6,40 +6,38 @@ import AssignmentManager from '../managers/AssignmentManager';
 
 
 class SecurityMiddleware {
+    private isConnected(checkIfConnected: boolean, req: express.Request): boolean {
+        return checkIfConnected && req.session.profile !== null && req.session.profile !== undefined;
+    }
+
+    private async checkType(checkType: SecurityCheckType, req: express.Request): Promise<boolean> {
+        try {
+            switch ( String(checkType) ) {
+                case SecurityCheckType.TEACHING_STAFF:
+                    return req.session.profile.isTeachingStaff;
+                case SecurityCheckType.ASSIGNMENT_STAFF:
+                    return await AssignmentManager.isUserAllowedToAccessAssignment(req.boundParams.assignment!, req.session.profile);
+                case SecurityCheckType.ASSIGNMENT_IS_PUBLISHED:
+                    return req.boundParams.assignment?.published ?? false;
+                case SecurityCheckType.EXERCISE_SECRET:
+                    return (req.headers.exercisesecret as string | undefined) === req.boundParams.exercise!.secret;
+                default:
+                    return false;
+            }
+        } catch ( e ) {
+            logger.error('Security check failed !!! => ' + JSON.stringify(e));
+            return false;
+        }
+    }
+
     // First check if connected then check if at least ONE rule match. It's NOT an AND but it's a OR function.
     check(checkIfConnected: boolean, ...checkTypes: Array<SecurityCheckType>): (req: express.Request, res: express.Response, next: express.NextFunction) => void {
         return async (req: express.Request, res: express.Response, next: express.NextFunction) => {
-            if ( checkIfConnected && (req.session.profile === null || req.session.profile === undefined) ) {
+            if ( !this.isConnected(checkIfConnected, req) ) {
                 return req.session.sendResponse(res, StatusCodes.UNAUTHORIZED);
             }
 
-            let isAllowed = checkTypes.length === 0;
-
-            if ( !isAllowed ) {
-                for ( const checkType of checkTypes ) {
-                    try {
-                        switch ( String(checkType) ) {
-                            case SecurityCheckType.TEACHING_STAFF:
-                                isAllowed = isAllowed || req.session.profile.isTeachingStaff;
-                                break;
-                            case SecurityCheckType.ASSIGNMENT_STAFF:
-                                isAllowed = isAllowed || await AssignmentManager.isUserAllowedToAccessAssignment(req.boundParams.assignment!, req.session.profile);
-                                break;
-                            case SecurityCheckType.ASSIGNMENT_IS_PUBLISHED:
-                                isAllowed = isAllowed || (req.boundParams.assignment?.published ?? false);
-                                break;
-                            case SecurityCheckType.EXERCISE_SECRET:
-                                isAllowed = isAllowed || (req.headers.exercisesecret as string | undefined) === req.boundParams.exercise!.secret;
-                                break;
-                            default:
-                                break;
-                        }
-                    } catch ( e ) {
-                        logger.error('Security check failed !!! => ' + e);
-                        isAllowed = isAllowed || false;
-                    }
-                }
-            }
+            const isAllowed: boolean = checkTypes.length === 0 ? true : checkTypes.find(async checkType => this.checkType(checkType, req)) !== undefined;
 
             if ( !isAllowed ) {
                 return req.session.sendResponse(res, StatusCodes.FORBIDDEN);
diff --git a/ExpressAPI/src/routes/AssignmentRoutes.ts b/ExpressAPI/src/routes/AssignmentRoutes.ts
index 9f46f4973a57441ea2b043c117e343e77ccbed5a..121c4c4fe75ecfc3e69d649043eacd64c0d5702e 100644
--- a/ExpressAPI/src/routes/AssignmentRoutes.ts
+++ b/ExpressAPI/src/routes/AssignmentRoutes.ts
@@ -1,31 +1,27 @@
-import { Express }                    from 'express-serve-static-core';
-import express                        from 'express';
-import * as ExpressValidator          from 'express-validator';
-import { StatusCodes }                from 'http-status-codes';
-import RoutesManager                  from '../express/RoutesManager';
-import ParamsValidatorMiddleware      from '../middlewares/ParamsValidatorMiddleware';
-import SecurityMiddleware             from '../middlewares/SecurityMiddleware';
-import SecurityCheckType              from '../types/SecurityCheckType';
-import GitlabUser                     from '../shared/types/Gitlab/GitlabUser';
-import GitlabManager                  from '../managers/GitlabManager';
-import Config                         from '../config/Config';
-import GitlabMember                   from '../shared/types/Gitlab/GitlabMember';
-import GitlabAccessLevel              from '../shared/types/Gitlab/GitlabAccessLevel';
-import GitlabRepository               from '../shared/types/Gitlab/GitlabRepository';
-import { AxiosError, HttpStatusCode } from 'axios';
-import logger                         from '../shared/logging/WinstonLogger';
-import DojoValidators                 from '../helpers/DojoValidators';
-import { Prisma }                     from '@prisma/client';
-import db                             from '../helpers/DatabaseHelper';
-import { Assignment }                 from '../types/DatabaseTypes';
-import AssignmentManager              from '../managers/AssignmentManager';
-import GitlabVisibility               from '../shared/types/Gitlab/GitlabVisibility';
-import fs                             from 'fs';
-import path                           from 'path';
-import SharedAssignmentHelper         from '../shared/helpers/Dojo/SharedAssignmentHelper';
-import GlobalHelper                   from '../helpers/GlobalHelper';
-import DojoStatusCode                 from '../shared/types/Dojo/DojoStatusCode';
-import DojoModelsHelper               from '../helpers/DojoModelsHelper';
+import { Express }               from 'express-serve-static-core';
+import express                   from 'express';
+import * as ExpressValidator     from 'express-validator';
+import { StatusCodes }           from 'http-status-codes';
+import RoutesManager             from '../express/RoutesManager';
+import ParamsValidatorMiddleware from '../middlewares/ParamsValidatorMiddleware';
+import SecurityMiddleware        from '../middlewares/SecurityMiddleware';
+import SecurityCheckType         from '../types/SecurityCheckType';
+import GitlabManager             from '../managers/GitlabManager';
+import Config                    from '../config/Config';
+import logger                    from '../shared/logging/WinstonLogger';
+import DojoValidators            from '../helpers/DojoValidators';
+import { Prisma }                from '@prisma/client';
+import db                        from '../helpers/DatabaseHelper';
+import { Assignment }            from '../types/DatabaseTypes';
+import AssignmentManager         from '../managers/AssignmentManager';
+import fs                        from 'fs';
+import path                      from 'path';
+import SharedAssignmentHelper    from '../shared/helpers/Dojo/SharedAssignmentHelper';
+import GlobalHelper              from '../helpers/GlobalHelper';
+import DojoStatusCode            from '../shared/types/Dojo/DojoStatusCode';
+import DojoModelsHelper          from '../helpers/DojoModelsHelper';
+import * as Gitlab               from '@gitbeaker/rest';
+import { GitbeakerRequestError } from '@gitbeaker/requester-utils';
 
 
 class AssignmentRoutes implements RoutesManager {
@@ -84,88 +80,75 @@ class AssignmentRoutes implements RoutesManager {
 
     private async createAssignment(req: express.Request, res: express.Response) {
         const params: {
-            name: string, members: Array<GitlabUser>, template: string
+            name: string, members: Array<Gitlab.UserSchema>, template: string
         } = req.body;
         params.members = [ await req.session.profile.gitlabProfile.value, ...params.members ];
         params.members = params.members.removeObjectDuplicates(gitlabUser => gitlabUser.id);
 
 
-        let repository: GitlabRepository;
+        let repository: Gitlab.ProjectSchema;
         try {
             repository = await GitlabManager.createRepository(params.name, Config.assignment.default.description.replace('{{ASSIGNMENT_NAME}}', params.name), Config.assignment.default.visibility, Config.assignment.default.initReadme, Config.gitlab.group.assignments, Config.assignment.default.sharedRunnersEnabled, Config.assignment.default.wikiEnabled, params.template);
         } catch ( error ) {
             logger.error('Repo creation error');
-            logger.error(error);
-
-            if ( error instanceof AxiosError ) {
-                if ( error.response?.data.message.name && error.response.data.message.name === 'has already been taken' ) {
-                    return req.session.sendResponse(res, StatusCodes.CONFLICT, {}, `Repository name has already been take`, DojoStatusCode.ASSIGNMENT_NAME_CONFLICT);
+            logger.error(JSON.stringify(error));
+
+            if ( error instanceof GitbeakerRequestError ) {
+                if ( error.cause?.description ) {
+                    const description = error.cause.description as unknown;
+                    if ( GlobalHelper.isRepoNameAlreadyTaken(description) ) {
+                        req.session.sendResponse(res, StatusCodes.CONFLICT, {}, `Repository name has already been taken`, DojoStatusCode.ASSIGNMENT_NAME_CONFLICT);
+                        return;
+                    }
                 }
 
-                return req.session.sendResponse(res, error.response?.status ?? HttpStatusCode.InternalServerError);
+                req.session.sendResponse(res, error.cause?.response.status ?? StatusCodes.INTERNAL_SERVER_ERROR);
+                return;
             }
 
-            return req.session.sendResponse(res, HttpStatusCode.InternalServerError);
+            req.session.sendResponse(res, StatusCodes.INTERNAL_SERVER_ERROR);
+            return;
         }
 
         await new Promise(resolve => setTimeout(resolve, Config.gitlab.repository.timeoutAfterCreation));
 
-        try {
-            await GitlabManager.protectBranch(repository.id, '*', true, GitlabAccessLevel.DEVELOPER, GitlabAccessLevel.DEVELOPER, GitlabAccessLevel.OWNER);
-
-            await GitlabManager.addRepositoryBadge(repository.id, Config.gitlab.badges.pipeline.link, Config.gitlab.badges.pipeline.imageUrl, 'Pipeline Status');
-        } catch ( error ) {
-            return GlobalHelper.repositoryCreationError('Repo params error', error, req, res, DojoStatusCode.ASSIGNMENT_CREATION_GITLAB_ERROR, DojoStatusCode.ASSIGNMENT_CREATION_INTERNAL_ERROR, repository);
-        }
-
-        try {
-            await GitlabManager.deleteFile(repository.id, '.gitlab-ci.yml', 'Remove .gitlab-ci.yml');
-        } catch ( error ) { /* empty */ }
+        const repoCreationFnExec = GlobalHelper.repoCreationFnExecCreator(req, res, DojoStatusCode.ASSIGNMENT_CREATION_GITLAB_ERROR, DojoStatusCode.ASSIGNMENT_CREATION_INTERNAL_ERROR, repository);
 
         try {
-            await GitlabManager.createFile(repository.id, '.gitlab-ci.yml', fs.readFileSync(path.join(__dirname, '../../assets/assignment_gitlab_ci.yml'), 'base64'), 'Add .gitlab-ci.yml (DO NOT MODIFY THIS FILE)');
+            await repoCreationFnExec(() => GitlabManager.protectBranch(repository.id, '*', true, Gitlab.AccessLevel.DEVELOPER, Gitlab.AccessLevel.DEVELOPER, Gitlab.AccessLevel.ADMIN), 'Branch protection modification error');
+            await repoCreationFnExec(() => GitlabManager.addRepositoryBadge(repository.id, Config.gitlab.badges.pipeline.link, Config.gitlab.badges.pipeline.imageUrl, 'Pipeline Status'), 'Pipeline badge addition error');
+            await repoCreationFnExec(() => GitlabManager.deleteFile(repository.id, '.gitlab-ci.yml', 'Remove .gitlab-ci.yml'));
+            await repoCreationFnExec(() => GitlabManager.createFile(repository.id, '.gitlab-ci.yml', fs.readFileSync(path.join(__dirname, '../../assets/assignment_gitlab_ci.yml'), 'base64'), 'Add .gitlab-ci.yml (DO NOT MODIFY THIS FILE)'), 'CI/CD file creation error');
+
+            await repoCreationFnExec(() => Promise.all(params.members.map(member => member.id).map(GlobalHelper.addRepoMember(repository.id))), 'Add repository members error');
+
+            const assignment: Assignment = await repoCreationFnExec(() => db.assignment.create({
+                                                                                                   data: {
+                                                                                                       name              : repository.name,
+                                                                                                       gitlabId          : repository.id,
+                                                                                                       gitlabLink        : repository.web_url,
+                                                                                                       gitlabCreationInfo: repository as unknown as Prisma.JsonObject,
+                                                                                                       gitlabLastInfo    : repository as unknown as Prisma.JsonObject,
+                                                                                                       gitlabLastInfoDate: new Date(),
+                                                                                                       staff             : {
+                                                                                                           connectOrCreate: [ ...params.members.map(gitlabUser => {
+                                                                                                               return {
+                                                                                                                   create: {
+                                                                                                                       id            : gitlabUser.id,
+                                                                                                                       gitlabUsername: gitlabUser.name
+                                                                                                                   },
+                                                                                                                   where : {
+                                                                                                                       id: gitlabUser.id
+                                                                                                                   }
+                                                                                                               };
+                                                                                                           }) ]
+                                                                                                       }
+                                                                                                   }
+                                                                                               }), 'Database error') as Assignment;
+
+            req.session.sendResponse(res, StatusCodes.OK, assignment);
         } catch ( error ) {
-            return GlobalHelper.repositoryCreationError('CI file error', error, req, res, DojoStatusCode.ASSIGNMENT_CREATION_GITLAB_ERROR, DojoStatusCode.ASSIGNMENT_CREATION_INTERNAL_ERROR, repository);
-        }
-
-        try {
-            await Promise.all(params.members.map(member => member.id).map(async (memberId: number): Promise<GitlabMember | false> => {
-                try {
-                    return await GitlabManager.addRepositoryMember(repository.id, memberId, GitlabAccessLevel.DEVELOPER);
-                } catch ( error ) {
-                    logger.error('Add member error');
-                    logger.error(error);
-                    return false;
-                }
-            }));
-
-            const assignment: Assignment = await db.assignment.create({
-                                                                          data: {
-                                                                              name              : repository.name,
-                                                                              gitlabId          : repository.id,
-                                                                              gitlabLink        : repository.web_url,
-                                                                              gitlabCreationInfo: repository as unknown as Prisma.JsonObject,
-                                                                              gitlabLastInfo    : repository as unknown as Prisma.JsonObject,
-                                                                              gitlabLastInfoDate: new Date(),
-                                                                              staff             : {
-                                                                                  connectOrCreate: [ ...params.members.map(gitlabUser => {
-                                                                                      return {
-                                                                                          create: {
-                                                                                              id            : gitlabUser.id,
-                                                                                              gitlabUsername: gitlabUser.name
-                                                                                          },
-                                                                                          where : {
-                                                                                              id: gitlabUser.id
-                                                                                          }
-                                                                                      };
-                                                                                  }) ]
-                                                                              }
-                                                                          }
-                                                                      }) as unknown as Assignment;
-
-            return req.session.sendResponse(res, StatusCodes.OK, assignment);
-        } catch ( error ) {
-            return GlobalHelper.repositoryCreationError('DB error', error, req, res, DojoStatusCode.ASSIGNMENT_CREATION_GITLAB_ERROR, DojoStatusCode.ASSIGNMENT_CREATION_INTERNAL_ERROR, repository);
+            /* Empty */
         }
     }
 
@@ -180,7 +163,7 @@ class AssignmentRoutes implements RoutesManager {
             }
 
             try {
-                await GitlabManager.changeRepositoryVisibility(req.boundParams.assignment!.gitlabId, publish ? GitlabVisibility.INTERNAL : GitlabVisibility.PRIVATE);
+                await GitlabManager.changeRepositoryVisibility(req.boundParams.assignment!.gitlabId, publish ? 'internal' : 'private');
 
                 await db.assignment.update({
                                                where: {
@@ -193,13 +176,14 @@ class AssignmentRoutes implements RoutesManager {
 
                 req.session.sendResponse(res, StatusCodes.OK);
             } catch ( error ) {
-                if ( error instanceof AxiosError ) {
-                    res.status(error.response?.status ?? HttpStatusCode.InternalServerError).send();
+                logger.error(JSON.stringify(error));
+
+                if ( error instanceof GitbeakerRequestError ) {
+                    req.session.sendResponse(res, error.cause?.response.status ?? StatusCodes.INTERNAL_SERVER_ERROR, undefined, 'Error while updating the assignment state');
                     return;
                 }
 
-                logger.error(error);
-                res.status(StatusCodes.INTERNAL_SERVER_ERROR).send();
+                req.session.sendResponse(res, StatusCodes.INTERNAL_SERVER_ERROR, undefined, 'Error while updating the assignment state');
             }
         };
     }
@@ -223,7 +207,7 @@ class AssignmentRoutes implements RoutesManager {
             const lastCommit = await GitlabManager.getRepositoryLastCommit(req.boundParams.exercise!.gitlabId);
             if ( lastCommit ) {
                 if ( !isUpdate ) {
-                    await GitlabManager.changeRepositoryVisibility(req.boundParams.exercise!.gitlabId, GitlabVisibility.INTERNAL);
+                    await GitlabManager.changeRepositoryVisibility(req.boundParams.exercise!.gitlabId, 'internal');
                 }
 
                 await db.exercise.update({
diff --git a/ExpressAPI/src/routes/ExerciseRoutes.ts b/ExpressAPI/src/routes/ExerciseRoutes.ts
index d5cb5b68c164dec82a2bf3c4c4750c0477f73225..34607a0484e811c48956ec67a76b911bd0aff8d2 100644
--- a/ExpressAPI/src/routes/ExerciseRoutes.ts
+++ b/ExpressAPI/src/routes/ExerciseRoutes.ts
@@ -5,23 +5,15 @@ import { StatusCodes }           from 'http-status-codes';
 import RoutesManager             from '../express/RoutesManager';
 import ParamsValidatorMiddleware from '../middlewares/ParamsValidatorMiddleware';
 import SecurityMiddleware        from '../middlewares/SecurityMiddleware';
-import GitlabUser                from '../shared/types/Gitlab/GitlabUser';
 import GitlabManager             from '../managers/GitlabManager';
 import Config                    from '../config/Config';
-import GitlabRepository          from '../shared/types/Gitlab/GitlabRepository';
-import { AxiosError }            from 'axios';
 import logger                    from '../shared/logging/WinstonLogger';
 import DojoValidators            from '../helpers/DojoValidators';
 import { v4 as uuidv4 }          from 'uuid';
-import GitlabMember              from '../shared/types/Gitlab/GitlabMember';
-import GitlabAccessLevel         from '../shared/types/Gitlab/GitlabAccessLevel';
 import { Prisma }                from '@prisma/client';
 import { Assignment, Exercise }  from '../types/DatabaseTypes';
 import db                        from '../helpers/DatabaseHelper';
 import SecurityCheckType         from '../types/SecurityCheckType';
-import GitlabTreeFile            from '../shared/types/Gitlab/GitlabTreeFile';
-import GitlabFile                from '../shared/types/Gitlab/GitlabFile';
-import GitlabTreeFileType        from '../shared/types/Gitlab/GitlabTreeFileType';
 import JSON5                     from 'json5';
 import fs                        from 'fs';
 import path                      from 'path';
@@ -31,6 +23,9 @@ import DojoStatusCode            from '../shared/types/Dojo/DojoStatusCode';
 import GlobalHelper              from '../helpers/GlobalHelper';
 import { IFileDirStat }          from '../shared/helpers/recursiveFilesStats/RecursiveFilesStats';
 import ExerciseManager           from '../managers/ExerciseManager';
+import * as Gitlab               from '@gitbeaker/rest';
+import GitlabTreeFileType        from '../shared/types/Gitlab/GitlabTreeFileType';
+import { GitbeakerRequestError } from '@gitbeaker/requester-utils';
 
 
 class ExerciseRoutes implements RoutesManager {
@@ -77,19 +72,19 @@ class ExerciseRoutes implements RoutesManager {
         backend.post('/exercises/:exerciseIdOrUrl/results', SecurityMiddleware.check(false, SecurityCheckType.EXERCISE_SECRET), ParamsValidatorMiddleware.validate(this.resultValidator), this.createResult.bind(this));
     }
 
-    private getExerciseName(assignment: Assignment, members: Array<GitlabUser>, suffix: number): string {
+    private getExerciseName(assignment: Assignment, members: Array<Gitlab.UserSchema>, suffix: number): string {
         const memberNames: string = members.map(member => member.username).sort((a, b) => a.localeCompare(b)).join(' + ');
         const suffixString: string = suffix > 0 ? ` - ${ suffix }` : '';
         return `DojoEx - ${ assignment.name } - ${ memberNames }${ suffixString }`;
     }
 
     private getExercisePath(assignment: Assignment, exerciseId: string): string {
-        return `dojo-ex_${ (assignment.gitlabLastInfo as unknown as GitlabRepository).path }_${ exerciseId }`;
+        return `dojo-ex_${ (assignment.gitlabLastInfo as unknown as Gitlab.ProjectSchema).path }_${ exerciseId }`;
     }
 
-    private async checkExerciseLimit(assignment: Assignment, members: Array<GitlabUser>): Promise<Array<GitlabUser>> {
-        const exercises: Array<Exercise> = await ExerciseManager.getFromAssignment(assignment.name, { members: true });
-        const reachedLimitUsers: Array<GitlabUser> = [];
+    private async checkExerciseLimit(assignment: Assignment, members: Array<Gitlab.UserSchema>): Promise<Array<Gitlab.UserSchema>> {
+        const exercises: Array<Exercise> | undefined = await ExerciseManager.getFromAssignment(assignment.name, { members: true });
+        const reachedLimitUsers: Array<Gitlab.UserSchema> = [];
         if ( exercises.length > 0 ) {
             for ( const member of members ) {
                 const exerciseCount: number = exercises.filter(exercise => exercise.members.findIndex(exerciseMember => exerciseMember.id === member.id) !== -1).length;
@@ -102,20 +97,21 @@ class ExerciseRoutes implements RoutesManager {
         return reachedLimitUsers;
     }
 
-    private async createExerciseRepository(assignment: Assignment, members: Array<GitlabUser>, exerciseId: string, req: express.Request, res: express.Response): Promise<GitlabRepository | undefined> {
-        let repository!: GitlabRepository;
+    private async createExerciseRepository(assignment: Assignment, members: Array<Gitlab.UserSchema>, exerciseId: string, req: express.Request, res: express.Response): Promise<Gitlab.ProjectSchema | undefined> {
+        let repository!: Gitlab.ProjectSchema;
 
         let suffix: number = 0;
         do {
             try {
-                repository = await GitlabManager.forkRepository((assignment.gitlabCreationInfo as unknown as GitlabRepository).id, this.getExerciseName(assignment, members, suffix), this.getExercisePath(req.boundParams.assignment!, exerciseId), Config.exercise.default.description.replace('{{ASSIGNMENT_NAME}}', assignment.name), Config.exercise.default.visibility, Config.gitlab.group.exercises);
+                repository = await GitlabManager.forkRepository((assignment.gitlabCreationInfo as unknown as Gitlab.ProjectSchema).id, this.getExerciseName(assignment, members, suffix), this.getExercisePath(req.boundParams.assignment!, exerciseId), Config.exercise.default.description.replace('{{ASSIGNMENT_NAME}}', assignment.name), Config.exercise.default.visibility, Config.gitlab.group.exercises);
                 break;
             } catch ( error ) {
                 logger.error('Repo creation error');
-                logger.error(error);
+                logger.error(JSON.stringify(error));
 
-                if ( error instanceof AxiosError ) {
-                    if ( error.response?.data.message.name && error.response.data.message.name === 'has already been taken' ) {
+                if ( error instanceof GitbeakerRequestError && error.cause?.description ) {
+                    const description = error.cause.description as unknown;
+                    if ( GlobalHelper.isRepoNameAlreadyTaken(description) ) {
                         suffix++;
                     } else {
                         req.session.sendResponse(res, StatusCodes.INTERNAL_SERVER_ERROR, {}, 'Unknown gitlab error while forking repository', DojoStatusCode.EXERCISE_CREATION_GITLAB_ERROR);
@@ -128,22 +124,16 @@ class ExerciseRoutes implements RoutesManager {
             }
         } while ( suffix < Config.exercise.maxSameName );
 
-        if ( suffix >= Config.exercise.maxSameName ) {
-            logger.error('Max exercise with same name reached');
-            req.session.sendResponse(res, StatusCodes.INSUFFICIENT_SPACE_ON_RESOURCE, undefined, 'Max exercise per assignment reached', DojoStatusCode.MAX_EXERCISE_PER_ASSIGNMENT_REACHED);
-            return undefined;
-        }
-
         return repository;
     }
 
     private async createExercise(req: express.Request, res: express.Response) {
-        const params: { members: Array<GitlabUser> } = req.body;
+        const params: { members: Array<Gitlab.UserSchema> } = req.body;
         params.members = [ await req.session.profile.gitlabProfile.value, ...params.members ].removeObjectDuplicates(gitlabUser => gitlabUser.id);
         const assignment: Assignment = req.boundParams.assignment!;
 
 
-        const reachedLimitUsers: Array<GitlabUser> = await this.checkExerciseLimit(assignment, params.members);
+        const reachedLimitUsers: Array<Gitlab.UserSchema> = await this.checkExerciseLimit(assignment, params.members);
         if ( reachedLimitUsers.length > 0 ) {
             req.session.sendResponse(res, StatusCodes.INSUFFICIENT_SPACE_ON_RESOURCE, reachedLimitUsers, 'Max exercise per assignment reached', DojoStatusCode.MAX_EXERCISE_PER_ASSIGNMENT_REACHED);
             return;
@@ -152,7 +142,7 @@ class ExerciseRoutes implements RoutesManager {
 
         const exerciseId: string = uuidv4();
         const secret: string = uuidv4();
-        const repository: GitlabRepository | undefined = await this.createExerciseRepository(assignment, params.members, exerciseId, req, res);
+        const repository: Gitlab.ProjectSchema | undefined = await this.createExerciseRepository(assignment, params.members, exerciseId, req, res);
 
         if ( !repository ) {
             return;
@@ -160,77 +150,61 @@ class ExerciseRoutes implements RoutesManager {
 
         await new Promise(resolve => setTimeout(resolve, Config.gitlab.repository.timeoutAfterCreation));
 
-        try {
-            await GitlabManager.protectBranch(repository.id, '*', false, GitlabAccessLevel.DEVELOPER, GitlabAccessLevel.DEVELOPER, GitlabAccessLevel.OWNER);
-
-            await GitlabManager.addRepositoryVariable(repository.id, 'DOJO_EXERCISE_ID', exerciseId, false, true);
-            await GitlabManager.addRepositoryVariable(repository.id, 'DOJO_SECRET', secret, false, true);
-            await GitlabManager.addRepositoryVariable(repository.id, 'DOJO_RESULTS_FOLDER', Config.exercise.pipelineResultsFolder, false, false);
-
-            await GitlabManager.addRepositoryBadge(repository.id, Config.gitlab.badges.pipeline.link, Config.gitlab.badges.pipeline.imageUrl, 'Pipeline Status');
-        } catch ( error ) {
-            GlobalHelper.repositoryCreationError('Repo params error', error, req, res, DojoStatusCode.EXERCISE_CREATION_GITLAB_ERROR, DojoStatusCode.EXERCISE_CREATION_INTERNAL_ERROR, repository);
-            return;
-        }
-
-        try {
-            await GitlabManager.updateFile(repository.id, '.gitlab-ci.yml', fs.readFileSync(path.join(__dirname, '../../assets/exercise_gitlab_ci.yml'), 'base64'), 'Add .gitlab-ci.yml (DO NOT MODIFY THIS FILE)');
-        } catch ( error ) {
-            GlobalHelper.repositoryCreationError('CI file update error', error, req, res, DojoStatusCode.EXERCISE_CREATION_GITLAB_ERROR, DojoStatusCode.EXERCISE_CREATION_INTERNAL_ERROR, repository);
-            return;
-        }
+        const repoCreationFnExec = GlobalHelper.repoCreationFnExecCreator(req, res, DojoStatusCode.EXERCISE_CREATION_GITLAB_ERROR, DojoStatusCode.EXERCISE_CREATION_INTERNAL_ERROR, repository);
 
         try {
-            await Promise.all([ ...new Set([ ...assignment.staff.map(user => user.id), ...params.members.map(member => member.id) ]) ].map(async (memberId: number): Promise<GitlabMember | false> => {
-                try {
-                    return await GitlabManager.addRepositoryMember(repository.id, memberId, GitlabAccessLevel.DEVELOPER);
-                } catch ( error ) {
-                    logger.error('Add member error');
-                    logger.error(error);
-                    return false;
-                }
-            }));
-
-            const exercise: Exercise = await db.exercise.create({
-                                                                    data: {
-                                                                        id                : exerciseId,
-                                                                        assignmentName    : assignment.name,
-                                                                        name              : repository.name,
-                                                                        secret            : secret,
-                                                                        gitlabId          : repository.id,
-                                                                        gitlabLink        : repository.web_url,
-                                                                        gitlabCreationInfo: repository as unknown as Prisma.JsonObject,
-                                                                        gitlabLastInfo    : repository as unknown as Prisma.JsonObject,
-                                                                        gitlabLastInfoDate: new Date(),
-                                                                        members           : {
-                                                                            connectOrCreate: [ ...params.members.map(gitlabUser => {
-                                                                                return {
-                                                                                    create: {
-                                                                                        id            : gitlabUser.id,
-                                                                                        gitlabUsername: gitlabUser.name
-                                                                                    },
-                                                                                    where : {
-                                                                                        id: gitlabUser.id
-                                                                                    }
-                                                                                };
-                                                                            }) ]
-                                                                        }
-                                                                    }
-                                                                }) as unknown as Exercise;
+            await repoCreationFnExec(() => GitlabManager.protectBranch(repository.id, '*', false, Gitlab.AccessLevel.DEVELOPER, Gitlab.AccessLevel.DEVELOPER, Gitlab.AccessLevel.ADMIN), 'Branch protection modification error');
+            await repoCreationFnExec(() => GitlabManager.addRepositoryBadge(repository.id, Config.gitlab.badges.pipeline.link, Config.gitlab.badges.pipeline.imageUrl, 'Pipeline Status'), 'Pipeline badge addition error');
+
+            await repoCreationFnExec(async () => {
+                await GitlabManager.addRepositoryVariable(repository.id, 'DOJO_EXERCISE_ID', exerciseId, false, true);
+                await GitlabManager.addRepositoryVariable(repository.id, 'DOJO_SECRET', secret, false, true);
+                await GitlabManager.addRepositoryVariable(repository.id, 'DOJO_RESULTS_FOLDER', Config.exercise.pipelineResultsFolder, false, false);
+            }, 'Pipeline variables addition error');
+
+            await repoCreationFnExec(() => GitlabManager.updateFile(repository.id, '.gitlab-ci.yml', fs.readFileSync(path.join(__dirname, '../../assets/exercise_gitlab_ci.yml'), 'base64'), 'Add .gitlab-ci.yml (DO NOT MODIFY THIS FILE)'), 'CI/CD file update error');
+
+            await repoCreationFnExec(async () => Promise.all([ ...new Set([ ...assignment.staff, ...params.members ].map(member => member.id)) ].map(GlobalHelper.addRepoMember(repository.id))), 'Add repository members error');
+
+            const exercise: Exercise = await repoCreationFnExec(() => db.exercise.create({
+                                                                                             data: {
+                                                                                                 id                : exerciseId,
+                                                                                                 assignmentName    : assignment.name,
+                                                                                                 name              : repository.name,
+                                                                                                 secret            : secret,
+                                                                                                 gitlabId          : repository.id,
+                                                                                                 gitlabLink        : repository.web_url,
+                                                                                                 gitlabCreationInfo: repository as unknown as Prisma.JsonObject,
+                                                                                                 gitlabLastInfo    : repository as unknown as Prisma.JsonObject,
+                                                                                                 gitlabLastInfoDate: new Date(),
+                                                                                                 members           : {
+                                                                                                     connectOrCreate: [ ...params.members.map(gitlabUser => {
+                                                                                                         return {
+                                                                                                             create: {
+                                                                                                                 id            : gitlabUser.id,
+                                                                                                                 gitlabUsername: gitlabUser.name
+                                                                                                             },
+                                                                                                             where : {
+                                                                                                                 id: gitlabUser.id
+                                                                                                             }
+                                                                                                         };
+                                                                                                     }) ]
+                                                                                                 }
+                                                                                             }
+                                                                                         })) as Exercise;
 
             req.session.sendResponse(res, StatusCodes.OK, exercise);
             return;
         } catch ( error ) {
-            await GlobalHelper.repositoryCreationError('DB error', error, req, res, DojoStatusCode.EXERCISE_CREATION_GITLAB_ERROR, DojoStatusCode.EXERCISE_CREATION_INTERNAL_ERROR, repository);
-            return;
+            /* Empty */
         }
     }
 
     private async getAssignment(req: express.Request, res: express.Response) {
-        const repoTree: Array<GitlabTreeFile> = await GitlabManager.getRepositoryTree(req.boundParams.exercise!.assignment.gitlabId);
+        const repoTree: Array<Gitlab.RepositoryTreeSchema> = await GitlabManager.getRepositoryTree(req.boundParams.exercise!.assignment.gitlabId);
 
-        let assignmentHjsonFile!: GitlabFile;
-        const immutableFiles: Array<GitlabFile> = await Promise.all(Config.assignment.baseFiles.map(async (baseFile: string) => {
+        let assignmentHjsonFile!: Gitlab.RepositoryFileExpandedSchema;
+        const immutableFiles: Array<Gitlab.RepositoryFileExpandedSchema> = await Promise.all(Config.assignment.baseFiles.map(async (baseFile: string) => {
             const file = await GitlabManager.getFile(req.boundParams.exercise!.assignment.gitlabId, baseFile);
 
             if ( baseFile === Config.assignment.filename ) {
diff --git a/ExpressAPI/src/routes/SessionRoutes.ts b/ExpressAPI/src/routes/SessionRoutes.ts
index 60b630d9fcf37254f4f068acc0272265ca149d1c..b4f223e664ed675c40f2648a96ca4e42daf8d610 100644
--- a/ExpressAPI/src/routes/SessionRoutes.ts
+++ b/ExpressAPI/src/routes/SessionRoutes.ts
@@ -8,7 +8,6 @@ import SecurityMiddleware        from '../middlewares/SecurityMiddleware';
 import GitlabManager             from '../managers/GitlabManager';
 import UserManager               from '../managers/UserManager';
 import DojoStatusCode            from '../shared/types/Dojo/DojoStatusCode';
-import SharedGitlabManager       from '../shared/managers/SharedGitlabManager';
 import Config                    from '../config/Config';
 
 
@@ -64,7 +63,7 @@ class SessionRoutes implements RoutesManager {
                 refreshToken: string
             } = req.body;
 
-            const gitlabTokens = await SharedGitlabManager.getTokens(params.refreshToken, true, Config.login.gitlab.client.secret);
+            const gitlabTokens = await GitlabManager.getTokens(params.refreshToken, true, Config.login.gitlab.client.secret);
 
             req.session.sendResponse(res, StatusCodes.OK, gitlabTokens);
         } catch ( error ) {
diff --git a/ExpressAPI/src/shared b/ExpressAPI/src/shared
index 985c0b6a5dcb640404e5cf5fc91978215f961e3b..6e78095b3fe73f2c2987de1a3d3b55511335a2bf 160000
--- a/ExpressAPI/src/shared
+++ b/ExpressAPI/src/shared
@@ -1 +1 @@
-Subproject commit 985c0b6a5dcb640404e5cf5fc91978215f961e3b
+Subproject commit 6e78095b3fe73f2c2987de1a3d3b55511335a2bf
diff --git a/ExpressAPI/src/types/DatabaseTypes.ts b/ExpressAPI/src/types/DatabaseTypes.ts
index 14e9b00a7f35a210302854e69c94dcc2f4dc63b4..2a9726980de2a1bcc8187be1df7d3837c0fd4def 100644
--- a/ExpressAPI/src/types/DatabaseTypes.ts
+++ b/ExpressAPI/src/types/DatabaseTypes.ts
@@ -1,6 +1,6 @@
-import { Prisma } from '@prisma/client';
-import LazyVal    from '../shared/helpers/LazyVal';
-import GitlabUser from '../shared/types/Gitlab/GitlabUser';
+import { Prisma }  from '@prisma/client';
+import LazyVal     from '../shared/helpers/LazyVal';
+import * as Gitlab from '@gitbeaker/rest';
 
 
 const userBase = Prisma.validator<Prisma.UserDefaultArgs>()({
@@ -29,7 +29,7 @@ const resultBase = Prisma.validator<Prisma.ResultDefaultArgs>()({
 export type User = Prisma.UserGetPayload<typeof userBase> & {
     isTeachingStaff: boolean
     isAdmin: boolean
-    gitlabProfile: LazyVal<GitlabUser>
+    gitlabProfile: LazyVal<Gitlab.UserSchema>
 }
 export type Exercise = Prisma.ExerciseGetPayload<typeof exerciseBase> & {
     isCorrection: boolean