diff --git a/ExpressAPI/.idea/jetbrainsConfiguration b/ExpressAPI/.idea/jetbrainsConfiguration
index 4d703a2dd39ec0c2b71bbbbda8900588c4e360bd..ffc5d65f9f0f0e825688177425e526131aa84631 160000
--- a/ExpressAPI/.idea/jetbrainsConfiguration
+++ b/ExpressAPI/.idea/jetbrainsConfiguration
@@ -1 +1 @@
-Subproject commit 4d703a2dd39ec0c2b71bbbbda8900588c4e360bd
+Subproject commit ffc5d65f9f0f0e825688177425e526131aa84631
diff --git a/ExpressAPI/.idea/jsLibraryMappings.xml b/ExpressAPI/.idea/jsLibraryMappings.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d23208fbb7168875464dd7aaff4169c37be615ea
--- /dev/null
+++ b/ExpressAPI/.idea/jsLibraryMappings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="JavaScriptLibraryMappings">
+    <includedPredefinedLibrary name="Node.js Core" />
+  </component>
+</project>
\ No newline at end of file
diff --git a/ExpressAPI/.idea/jsLinters/eslint.xml b/ExpressAPI/.idea/jsLinters/eslint.xml
new file mode 100644
index 0000000000000000000000000000000000000000..541945bb0819b8ff4a3dae9431632ebd10e6f98b
--- /dev/null
+++ b/ExpressAPI/.idea/jsLinters/eslint.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="EslintConfiguration">
+    <option name="fix-on-save" value="true" />
+  </component>
+</project>
\ No newline at end of file
diff --git a/ExpressAPI/src/InitialImports.ts b/ExpressAPI/src/InitialImports.ts
index 7fd00732ce602000be8d23d218acc009c6652f8f..98e4273b1c3a1b46b6ef444a71a72bf8ae12fa6a 100644
--- a/ExpressAPI/src/InitialImports.ts
+++ b/ExpressAPI/src/InitialImports.ts
@@ -1,15 +1,15 @@
 import path    from 'node:path';
 import cluster from 'node:cluster';
+import myEnv = require('dotenv');
+import dotenvExpand = require('dotenv-expand');
 
 
 if ( cluster.isPrimary ) {
     if ( process.env.NODE_ENV && process.env.NODE_ENV === 'production' ) {
-        const myEnv = require('dotenv').config();
-        require('dotenv-expand').expand(myEnv);
+        dotenvExpand.expand(myEnv.config());
     } else {
-        require('dotenv').config({ path: path.join(__dirname, '../.env.keys') });
-        const myEnv = require('dotenv').config({ DOTENV_KEY: process.env.DOTENV_KEY_DEVELOPMENT });
-        require('dotenv-expand').expand(myEnv);
+        myEnv.config({ path: path.join(__dirname, '../.env.keys') });
+        dotenvExpand.expand(myEnv.config({ DOTENV_KEY: process.env.DOTENV_KEY_DEVELOPMENT }));
     }
 }
 
diff --git a/ExpressAPI/src/controllers/Session.ts b/ExpressAPI/src/controllers/Session.ts
index 49e044eab67d18a2108e54ef54c1d4e59b6896bb..17efe6873ccc9edd605e74571b31cd9dc63fe6f3 100644
--- a/ExpressAPI/src/controllers/Session.ts
+++ b/ExpressAPI/src/controllers/Session.ts
@@ -41,7 +41,7 @@ class Session {
         }
     }
 
-    private static getToken(profileJson: any): string | null {
+    private static getToken(profileJson: unknown): string | null {
         return profileJson === null ? null : jwt.sign({ profile: profileJson }, Config.jwtConfig.secret, Config.jwtConfig.expiresIn > 0 ? { expiresIn: Config.jwtConfig.expiresIn } : {});
     }
 
@@ -52,7 +52,7 @@ class Session {
 
         try {
             reasonPhrase = getReasonPhrase(code);
-        } catch {}
+        } catch { /* empty */ }
 
         return {
             timestamp   : (new Date()).toISOString(),
@@ -67,8 +67,8 @@ class Session {
      Send a response to the client
      Information: Data could be a promise or an object. If it's a promise, we wait on the data to be resolved before sending the response
      */
-    sendResponse(res: express.Response, code: number, data?: any, descriptionOverride?: string, internalCode?: number) {
-        Promise.resolve(data).then((toReturn: any) => {
+    sendResponse(res: express.Response, code: number, data?: unknown, descriptionOverride?: string, internalCode?: number) {
+        Promise.resolve(data).then((toReturn: unknown) => {
             this.getResponse(internalCode ?? code, toReturn, descriptionOverride).then(response => {
                 res.status(code).json(response);
             });
diff --git a/ExpressAPI/src/helpers/DojoValidators.ts b/ExpressAPI/src/helpers/DojoValidators.ts
index ccb2b6575b637cfe2cb226498cd0b24d93e43dc3..0293660deb7449cc45f47366e7fac2868c801f2e 100644
--- a/ExpressAPI/src/helpers/DojoValidators.ts
+++ b/ExpressAPI/src/helpers/DojoValidators.ts
@@ -5,13 +5,14 @@ import { BailOptions, ValidationChain }                             from 'expres
 import GitlabManager                                                from '../managers/GitlabManager';
 import express                                                      from 'express';
 import SharedExerciseHelper                                         from '../shared/helpers/Dojo/SharedExerciseHelper';
+import logger                                                       from '../shared/logging/WinstonLogger';
 
 
 declare type DojoMeta = Meta & {
     req: express.Request
 };
 
-declare type DojoCustomValidator = (input: any, meta: DojoMeta) => any;
+declare type DojoCustomValidator = (input: unknown, meta: DojoMeta) => unknown;
 
 declare type DojoCustomValidatorSchemaOptions = { errorMessage?: FieldMessageFactory | ErrorMessage, negated?: boolean, bail?: boolean | BailOptions, if?: CustomValidator | ValidationChain, options?: CustomValidator }
 
@@ -22,7 +23,7 @@ class DojoValidators {
         return arg as unknown as DojoCustomValidatorSchemaOptions;
     }
 
-    private getParamValue(req: express.Request, path: string): any {
+    private getParamValue(req: express.Request, path: string): unknown {
         return 'body' in req && path in req.body ? req.body[path] : req.query[path];
     }
 
@@ -30,7 +31,9 @@ class DojoValidators {
                                                                options: (value) => {
                                                                    try {
                                                                        return value == 'null' || value == 'undefined' || value == '' ? null : value;
-                                                                   } catch ( e ) {
+                                                                   } catch ( error ) {
+                                                                       logger.error(`null sanitizer error: ${ error }`);
+
                                                                        return value;
                                                                    }
                                                                }
@@ -39,7 +42,7 @@ class DojoValidators {
     readonly jsonSanitizer = this.toValidatorSchemaOptions({
                                                                options: (value) => {
                                                                    try {
-                                                                       return JSON.parse(value);
+                                                                       return JSON.parse(value as string);
                                                                    } catch ( e ) {
                                                                        return value;
                                                                    }
@@ -54,7 +57,7 @@ class DojoValidators {
                                                                           path
                                                                       }) => {
                                                                           return new Promise((resolve, reject) => {
-                                                                              const template = this.getParamValue(req, path);
+                                                                              const template = this.getParamValue(req, path) as string;
                                                                               if ( template ) {
                                                                                   GitlabManager.checkTemplateAccess(template, req).then((templateAccess) => {
                                                                                       templateAccess !== StatusCodes.OK ? reject() : resolve(true);
@@ -77,9 +80,11 @@ class DojoValidators {
                                                                               } else {
                                                                                   return Config.assignment.default.template;
                                                                               }
-                                                                          } catch ( e ) { }
+                                                                          } catch ( error ) {
+                                                                              logger.error(`Template url sanitizer error: ${ error }`);
 
-                                                                          return value;
+                                                                              return value;
+                                                                          }
                                                                       }
                                                                   });
 
@@ -91,7 +96,7 @@ class DojoValidators {
                                                                               path
                                                                           }) => {
                                                                               return new Promise((resolve, reject) => {
-                                                                                  const results = this.getParamValue(req, path);
+                                                                                  const results = this.getParamValue(req, path) as string;
                                                                                   if ( results ) {
                                                                                       SharedExerciseHelper.validateResultFile(results, false).isValid ? resolve(true) : reject();
                                                                                   } else {
diff --git a/ExpressAPI/src/helpers/GlobalHelper.ts b/ExpressAPI/src/helpers/GlobalHelper.ts
index c97328d8e5cbc2d99b7339da2a94219e4ef01618..8a425a0d6e27b94ba6078da3b0e9bfa4f1e0ea88 100644
--- a/ExpressAPI/src/helpers/GlobalHelper.ts
+++ b/ExpressAPI/src/helpers/GlobalHelper.ts
@@ -8,7 +8,7 @@ import DojoStatusCode   from '../shared/types/Dojo/DojoStatusCode';
 
 
 class GlobalHelper {
-    async repositoryCreationError(message: string, error: any, req: express.Request, res: express.Response, gitlabError: DojoStatusCode, internalError: DojoStatusCode, repositoryToRemove?: GitlabRepository): Promise<void> {
+    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);
 
@@ -26,7 +26,7 @@ class GlobalHelper {
         }
 
         return req.session.sendResponse(res, StatusCodes.INTERNAL_SERVER_ERROR, {}, `Unknown error: ${ message }`, internalError);
-    };
+    }
 }
 
 
diff --git a/ExpressAPI/src/managers/GitlabManager.ts b/ExpressAPI/src/managers/GitlabManager.ts
index 0c93da87efa87ca244f7a11d21d831ccb7c1bc16..80ac7427fec1bf79d6e7d6b414734c286b1c021e 100644
--- a/ExpressAPI/src/managers/GitlabManager.ts
+++ b/ExpressAPI/src/managers/GitlabManager.ts
@@ -29,32 +29,31 @@ class GitlabManager {
                     DojoAuthorizationValue   : `Bearer ${ token }`
                 }
             })).data;
-        } catch ( e ) { }
-
-        return undefined;
+        } catch ( e ) {
+            return undefined;
+        }
     }
 
     public async getUserById(id: number): Promise<GitlabUser | undefined> {
         try {
-            const params: any = {};
-            const user = (await axios.get<GitlabUser>(`${ this.getApiUrl(GitlabRoute.USERS_GET) }/${ String(id) }`, { params: params })).data;
+            const user = (await axios.get<GitlabUser>(`${ this.getApiUrl(GitlabRoute.USERS_GET) }/${ String(id) }`)).data;
 
             return user.id === id ? user : undefined;
-        } catch ( e ) { }
-
-        return undefined;
+        } catch ( e ) {
+            return undefined;
+        }
     }
 
     public async getUserByUsername(username: string): Promise<GitlabUser | undefined> {
         try {
-            const params: any = {};
+            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;
+        } catch ( e ) {
+            return undefined;
+        }
     }
 
     async getRepository(idOrNamespace: string): Promise<GitlabRepository> {
@@ -185,15 +184,15 @@ class GitlabManager {
     }
 
     async getRepositoryTree(repoId: number, recursive: boolean = true, branch: string = 'main'): Promise<Array<GitlabTreeFile>> {
-        let address: string | undefined = this.getApiUrl(GitlabRoute.REPOSITORY_TREE).replace('{{id}}', String(repoId));
-        let params: any = {
+        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
         };
 
-        let results: Array<GitlabTreeFile> = [];
+        const results: Array<GitlabTreeFile> = [];
 
         while ( params !== undefined ) {
             const response = await axios.get<Array<GitlabTreeFile>>(address, {
diff --git a/ExpressAPI/src/managers/UserManager.ts b/ExpressAPI/src/managers/UserManager.ts
index b69705e1e6b5c65c29efe2a0590b27b7a51c48b2..686ee267551004d22b1745e93f343c30c21aec02 100644
--- a/ExpressAPI/src/managers/UserManager.ts
+++ b/ExpressAPI/src/managers/UserManager.ts
@@ -24,7 +24,7 @@ class UserManager {
                                         }) as unknown as User ?? undefined;
     }
 
-    async getUpdateFromGitlabProfile(gitlabProfile: GitlabProfile, refreshToken: string): Promise<User> {
+    async getUpdateFromGitlabProfile(gitlabProfile: GitlabProfile): Promise<User> {
         await db.user.upsert({
                                  where : {
                                      id: gitlabProfile.id
diff --git a/ExpressAPI/src/middlewares/ParamsCallbackManager.ts b/ExpressAPI/src/middlewares/ParamsCallbackManager.ts
index e81e172e444e0ccaf8723fef8a31a658dbdf2eb1..9af8f193cba8598dbddaf8d710a6a343e971f0bb 100644
--- a/ExpressAPI/src/middlewares/ParamsCallbackManager.ts
+++ b/ExpressAPI/src/middlewares/ParamsCallbackManager.ts
@@ -5,16 +5,16 @@ import ExerciseManager   from '../managers/ExerciseManager';
 import AssignmentManager from '../managers/AssignmentManager';
 
 
-type GetFunction = (id: string | number, ...args: Array<any>) => Promise<any>
+type GetFunction = (id: string | number, ...args: Array<unknown>) => Promise<unknown>
 
 
 class ParamsCallbackManager {
-    protected listenParam(paramName: string, backend: Express, getFunction: GetFunction, args: Array<any>, indexName: string) {
+    protected listenParam(paramName: string, backend: Express, getFunction: GetFunction, args: Array<unknown>, indexName: string) {
         backend.param(paramName, (req: express.Request, res: express.Response, next: express.NextFunction, id: string | number) => {
             getFunction(id, ...args).then(result => {
                 if ( result ) {
                     this.initBoundParams(req);
-                    (req.boundParams as any)[indexName] = result;
+                    (req.boundParams as Record<string, unknown>)[indexName] = result;
 
                     next();
                 } else {
diff --git a/ExpressAPI/src/routes/AssignmentRoutes.ts b/ExpressAPI/src/routes/AssignmentRoutes.ts
index e4eb82bfa416c6fcfb1062b84883551c9b821988..025dc331c72b2a94258e472fb488ef55266896f8 100644
--- a/ExpressAPI/src/routes/AssignmentRoutes.ts
+++ b/ExpressAPI/src/routes/AssignmentRoutes.ts
@@ -58,18 +58,25 @@ class AssignmentRoutes implements RoutesManager {
         const assignment: Assignment | undefined = req.boundParams.assignment;
 
         if ( assignment && !assignment.published && !await AssignmentManager.isUserAllowedToAccessAssignment(assignment, req.session.profile) ) {
+            // eslint-disable-next-line @typescript-eslint/ban-ts-comment
             // @ts-ignore
             delete assignment.gitlabId;
+            // eslint-disable-next-line @typescript-eslint/ban-ts-comment
             // @ts-ignore
             delete assignment.gitlabLink;
+            // eslint-disable-next-line @typescript-eslint/ban-ts-comment
             // @ts-ignore
             delete assignment.gitlabCreationInfo;
+            // eslint-disable-next-line @typescript-eslint/ban-ts-comment
             // @ts-ignore
             delete assignment.gitlabLastInfo;
+            // eslint-disable-next-line @typescript-eslint/ban-ts-comment
             // @ts-ignore
             delete assignment.gitlabLastInfoDate;
+            // eslint-disable-next-line @typescript-eslint/ban-ts-comment
             // @ts-ignore
             delete assignment.staff;
+            // eslint-disable-next-line @typescript-eslint/ban-ts-comment
             // @ts-ignore
             delete assignment.exercises;
         }
diff --git a/ExpressAPI/src/routes/ExerciseRoutes.ts b/ExpressAPI/src/routes/ExerciseRoutes.ts
index 8bc2e8a43832d6d59e8fb253d6d857fad24de290..1b9bc1d28023449c88f8cd065635f6cfadaa6f6b 100644
--- a/ExpressAPI/src/routes/ExerciseRoutes.ts
+++ b/ExpressAPI/src/routes/ExerciseRoutes.ts
@@ -29,6 +29,7 @@ import AssignmentFile            from '../shared/types/Dojo/AssignmentFile';
 import ExerciseResultsFile       from '../shared/types/Dojo/ExerciseResultsFile';
 import DojoStatusCode            from '../shared/types/Dojo/DojoStatusCode';
 import GlobalHelper              from '../helpers/GlobalHelper';
+import { IFileDirStat }          from '../shared/helpers/recursiveFilesStats/RecursiveFilesStats';
 
 
 class ExerciseRoutes implements RoutesManager {
@@ -187,8 +188,8 @@ class ExerciseRoutes implements RoutesManager {
         const repoTree: Array<GitlabTreeFile> = await GitlabManager.getRepositoryTree(req.boundParams.exercise!.assignment.gitlabId);
 
         let assignmentHjsonFile!: GitlabFile;
-        let immutableFiles: Array<GitlabFile> = await Promise.all(Config.assignment.baseFiles.map(async (baseFile: string) => {
-            let file = await GitlabManager.getFile(req.boundParams.exercise!.assignment.gitlabId, baseFile);
+        const immutableFiles: Array<GitlabFile> = 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 ) {
                 assignmentHjsonFile = file;
@@ -220,7 +221,7 @@ class ExerciseRoutes implements RoutesManager {
     }
 
     private async createResult(req: express.Request, res: express.Response) {
-        const params: { exitCode: number, commit: any, results: ExerciseResultsFile, files: any, archiveBase64: string } = req.body;
+        const params: { exitCode: number, commit: Record<string, string>, results: ExerciseResultsFile, files: Array<IFileDirStat>, archiveBase64: string } = req.body;
         const exercise: Exercise = req.boundParams.exercise!;
 
         const result = await db.result.create({
diff --git a/ExpressAPI/src/routes/SessionRoutes.ts b/ExpressAPI/src/routes/SessionRoutes.ts
index 0479205b47fa69630d954e3c6e08aa703f716043..29ebdfbacc5578ec02b597af6d09539903c9a2a5 100644
--- a/ExpressAPI/src/routes/SessionRoutes.ts
+++ b/ExpressAPI/src/routes/SessionRoutes.ts
@@ -46,7 +46,7 @@ class SessionRoutes implements RoutesManager {
             const gitlabUser = await GitlabManager.getUserProfile(params.accessToken);
 
             if ( gitlabUser ) {
-                req.session.profile = await UserManager.getUpdateFromGitlabProfile(gitlabUser, params.refreshToken);
+                req.session.profile = await UserManager.getUpdateFromGitlabProfile(gitlabUser);
 
                 req.session.sendResponse(res, StatusCodes.OK);
                 return;
diff --git a/ExpressAPI/src/shared b/ExpressAPI/src/shared
index 4a5eb68209ae9204b6d4cc8020bd62cf6a5be989..101cc26895eb0b5fe97e03bb96039e0cddd94391 160000
--- a/ExpressAPI/src/shared
+++ b/ExpressAPI/src/shared
@@ -1 +1 @@
-Subproject commit 4a5eb68209ae9204b6d4cc8020bd62cf6a5be989
+Subproject commit 101cc26895eb0b5fe97e03bb96039e0cddd94391