diff --git a/NodeApp/src/commander/assignment/AssignmentCommand.ts b/NodeApp/src/commander/assignment/AssignmentCommand.ts
index 90ae6167deaece3339766cc3f8a7b090263d2e79..b54c2cb00fcd0622f818ed9c621b823d9b7699e4 100644
--- a/NodeApp/src/commander/assignment/AssignmentCommand.ts
+++ b/NodeApp/src/commander/assignment/AssignmentCommand.ts
@@ -1,9 +1,10 @@
-import CommanderCommand           from '../CommanderCommand';
-import AssignmentCreateCommand    from './subcommands/AssignmentCreateCommand';
-import AssignmentPublishCommand   from './subcommands/AssignmentPublishCommand';
-import AssignmentUnpublishCommand from './subcommands/AssignmentUnpublishCommand';
-import AssignmentCheckCommand     from './subcommands/AssignmentCheckCommand';
-import AssignmentRunCommand       from './subcommands/AssignmentRunCommand';
+import CommanderCommand            from '../CommanderCommand';
+import AssignmentCreateCommand     from './subcommands/AssignmentCreateCommand';
+import AssignmentPublishCommand    from './subcommands/AssignmentPublishCommand';
+import AssignmentUnpublishCommand  from './subcommands/AssignmentUnpublishCommand';
+import AssignmentCheckCommand      from './subcommands/AssignmentCheckCommand';
+import AssignmentRunCommand        from './subcommands/AssignmentRunCommand';
+import AssignmentCorrectionCommand from './subcommands/correction/AssignmentCorrectionCommand';
 
 
 class AssignmentCommand extends CommanderCommand {
@@ -20,6 +21,7 @@ class AssignmentCommand extends CommanderCommand {
         AssignmentRunCommand.registerOnCommand(this.command);
         AssignmentPublishCommand.registerOnCommand(this.command);
         AssignmentUnpublishCommand.registerOnCommand(this.command);
+        AssignmentCorrectionCommand.registerOnCommand(this.command);
     }
 
     protected async commandAction(): Promise<void> { }
diff --git a/NodeApp/src/commander/assignment/subcommands/correction/AssignmentCorrectionCommand.ts b/NodeApp/src/commander/assignment/subcommands/correction/AssignmentCorrectionCommand.ts
new file mode 100644
index 0000000000000000000000000000000000000000..3f30a994e7fdcd0a773401db5daa36abba861579
--- /dev/null
+++ b/NodeApp/src/commander/assignment/subcommands/correction/AssignmentCorrectionCommand.ts
@@ -0,0 +1,23 @@
+import CommanderCommand                  from '../../../CommanderCommand';
+import AssignmentCorrectionLinkCommand   from './subcommands/AssignmentCorrectionLinkCommand';
+import AssignmentCorrectionUpdateCommand from './subcommands/AssignmentCorrectionUpdateCommand';
+
+
+class AssignmentCorrectionCommand extends CommanderCommand {
+    protected commandName: string = 'correction';
+
+    protected defineCommand() {
+        this.command
+        .description('manage corrections of an assignment');
+    }
+
+    protected defineSubCommands() {
+        AssignmentCorrectionLinkCommand.registerOnCommand(this.command);
+        AssignmentCorrectionUpdateCommand.registerOnCommand(this.command);
+    }
+
+    protected async commandAction(): Promise<void> { }
+}
+
+
+export default new AssignmentCorrectionCommand();
\ No newline at end of file
diff --git a/NodeApp/src/commander/assignment/subcommands/correction/subcommands/AssignmentCorrectionLinkCommand.ts b/NodeApp/src/commander/assignment/subcommands/correction/subcommands/AssignmentCorrectionLinkCommand.ts
new file mode 100644
index 0000000000000000000000000000000000000000..5d173206038be1262127faf618b74cb874022ffa
--- /dev/null
+++ b/NodeApp/src/commander/assignment/subcommands/correction/subcommands/AssignmentCorrectionLinkCommand.ts
@@ -0,0 +1,10 @@
+import AssignmentCorrectionLinkUpdateCommand from './AssignmentCorrectionLinkUpdateCommand';
+
+
+class AssignmentCorrectionLinkCommand extends AssignmentCorrectionLinkUpdateCommand {
+    protected commandName: string = 'link';
+    protected isUpdate: boolean = false;
+}
+
+
+export default new AssignmentCorrectionLinkCommand();
\ No newline at end of file
diff --git a/NodeApp/src/commander/assignment/subcommands/correction/subcommands/AssignmentCorrectionLinkUpdateCommand.ts b/NodeApp/src/commander/assignment/subcommands/correction/subcommands/AssignmentCorrectionLinkUpdateCommand.ts
new file mode 100644
index 0000000000000000000000000000000000000000..cd7b4f8897678e3e43fe2bd6973a76f0ac61db94
--- /dev/null
+++ b/NodeApp/src/commander/assignment/subcommands/correction/subcommands/AssignmentCorrectionLinkUpdateCommand.ts
@@ -0,0 +1,62 @@
+import CommanderCommand   from '../../../../CommanderCommand';
+import chalk              from 'chalk';
+import ora                from 'ora';
+import DojoBackendManager from '../../../../../managers/DojoBackendManager';
+import SessionManager     from '../../../../../managers/SessionManager';
+import Assignment         from '../../../../../sharedByClients/models/Assignment';
+
+
+abstract class AssignmentCorrectionLinkUpdateCommand extends CommanderCommand {
+    protected abstract isUpdate: boolean;
+
+    protected defineCommand() {
+        this.command
+        .description(this.isUpdate ? 'update a correction of an assignment' : 'link an exercise repo as a correction for an assignment')
+        .argument('<string>', 'id or url of the exercise that is the correction')
+        .requiredOption('-a, --assignment <string>', 'id or url of the assignment of the correction')
+        .action(this.commandAction.bind(this));
+    }
+
+    protected async commandAction(exerciseIdOrUrl: string, options: { assignment: string }): Promise<void> {
+        let assignment!: Assignment | undefined;
+
+        // Check access
+        {
+            console.log(chalk.cyan('Please wait while we check access...'));
+
+            const assignmentGetSpinner: ora.Ora = ora('Checking if assignment exists').start();
+            assignment = await DojoBackendManager.getAssignment(options.assignment);
+            if ( !assignment ) {
+                assignmentGetSpinner.fail(`The assignment doesn't exists`);
+                return;
+            }
+            assignmentGetSpinner.succeed(`The assignment exists`);
+
+
+            const assignmentAccessSpinner: ora.Ora = ora('Checking assignment access').start();
+            if ( assignment.staff.find(staff => staff.id === SessionManager.profile?.id) === undefined ) {
+                assignmentAccessSpinner.fail(`You are not in the staff of the assignment`);
+                return;
+            }
+            assignmentAccessSpinner.succeed(`You are in the staff of the assignment`);
+
+
+            const assignmentPublishedSpinner: ora.Ora = ora('Checking assignment').start();
+            if ( !assignment.published ) {
+                assignmentPublishedSpinner.fail(`Assignment is not published`);
+                return;
+            }
+            assignmentPublishedSpinner.succeed(`Assignment is published`);
+        }
+
+        // Link the exercise
+        {
+            console.log(chalk.cyan('Please wait while we link the exercise...'));
+
+            await DojoBackendManager.linkUpdateCorrection(exerciseIdOrUrl, assignment, this.isUpdate);
+        }
+    }
+}
+
+
+export default AssignmentCorrectionLinkUpdateCommand;
\ No newline at end of file
diff --git a/NodeApp/src/commander/assignment/subcommands/correction/subcommands/AssignmentCorrectionUpdateCommand.ts b/NodeApp/src/commander/assignment/subcommands/correction/subcommands/AssignmentCorrectionUpdateCommand.ts
new file mode 100644
index 0000000000000000000000000000000000000000..88a9f48dfdce248137c857f945116e0be51d171e
--- /dev/null
+++ b/NodeApp/src/commander/assignment/subcommands/correction/subcommands/AssignmentCorrectionUpdateCommand.ts
@@ -0,0 +1,10 @@
+import AssignmentCorrectionLinkUpdateCommand from './AssignmentCorrectionLinkUpdateCommand';
+
+
+class AssignmentCorrectionUpdateCommand extends AssignmentCorrectionLinkUpdateCommand {
+    protected commandName: string = 'update';
+    protected isUpdate: boolean = true;
+}
+
+
+export default new AssignmentCorrectionUpdateCommand();
\ No newline at end of file
diff --git a/NodeApp/src/helpers/AccessesHelper.ts b/NodeApp/src/helpers/AccessesHelper.ts
index e49e5819e59c74042fb5f23f79ace5587ae128c3..c9ff5e1bdaa823ca011eba7fa057e1c0b949a74e 100644
--- a/NodeApp/src/helpers/AccessesHelper.ts
+++ b/NodeApp/src/helpers/AccessesHelper.ts
@@ -3,25 +3,34 @@ import GitlabManager  from '../managers/GitlabManager';
 
 
 class AccessesHelper {
-    async checkStudent(): Promise<boolean> {
+    async checkStudent(testGitlab: boolean = false): Promise<boolean> {
         const sessionResult = await SessionManager.testSession(true, [ 'student' ]);
 
         if ( !sessionResult ) {
             return false;
         }
 
-        return (await GitlabManager.testToken(true)).every(result => result);
+        if ( testGitlab ) {
+            return (await GitlabManager.testToken(true)).every(result => result);
+        } else {
+            return true;
+        }
     }
-    
-    async checkTeachingStaff(): Promise<boolean> {
+
+    async checkTeachingStaff(testGitlab: boolean = false): Promise<boolean> {
         const sessionResult = await SessionManager.testSession(true, [ 'teachingStaff' ]);
 
         if ( !sessionResult || !sessionResult.teachingStaff ) {
             return false;
         }
 
-        return (await GitlabManager.testToken(true)).every(result => result);
+        if ( testGitlab ) {
+            return (await GitlabManager.testToken(true)).every(result => result);
+        } else {
+            return true;
+        }
     }
 }
 
+
 export default new AccessesHelper();
\ No newline at end of file
diff --git a/NodeApp/src/managers/DojoBackendManager.ts b/NodeApp/src/managers/DojoBackendManager.ts
index b8e8a41ec1beb1172244b281c61d658dc2c923ec..fcd749df9a44d151c202498cb8d5a8dfe5f2df2a 100644
--- a/NodeApp/src/managers/DojoBackendManager.ts
+++ b/NodeApp/src/managers/DojoBackendManager.ts
@@ -192,6 +192,49 @@ class DojoBackendManager {
             throw error;
         }
     }
+
+    public async linkUpdateCorrection(exerciseIdOrUrl: string, assignment: Assignment, isUpdate: boolean, verbose: boolean = true): Promise<boolean> {
+        const spinner: ora.Ora = ora(`${ isUpdate ? 'Updating' : 'Linking' } correction`);
+
+        if ( verbose ) {
+            spinner.start();
+        }
+
+        try {
+            const axiosFunction = isUpdate ? axios.patch : axios.post;
+            const route = isUpdate ? ApiRoute.ASSIGNMENT_CORRECTION_UPDATE : ApiRoute.ASSIGNMENT_CORRECTION_LINK;
+
+            await axiosFunction(this.getApiUrl(route).replace('{{assignmentNameOrUrl}}', encodeURIComponent(assignment.name)).replace('{{exerciseIdOrUrl}}', encodeURIComponent(exerciseIdOrUrl)), {
+                exerciseIdOrUrl: exerciseIdOrUrl
+            });
+
+            if ( verbose ) {
+                spinner.succeed(`Correction ${ isUpdate ? 'updated' : 'linked' }`);
+            }
+
+            return true;
+        } catch ( error ) {
+            if ( verbose ) {
+                if ( error instanceof AxiosError ) {
+                    if ( error.response?.data ) {
+                        if ( error.response.data.code === DojoStatusCode.ASSIGNMENT_EXERCISE_NOT_RELATED ) {
+                            spinner.fail(`The exercise does not belong to the assignment.`);
+                        } else if ( error.response.data.code === DojoStatusCode.EXERCISE_CORRECTION_ALREADY_EXIST ) {
+                            spinner.fail(`This exercise is already labelled as a correction. If you want to update it, please use the update command.`);
+                        } else if ( error.response.data.code === DojoStatusCode.EXERCISE_CORRECTION_NOT_EXIST ) {
+                            spinner.fail(`The exercise is not labelled as a correction so it's not possible to update it.`);
+                        }
+                    } else {
+                        spinner.fail(`Correction ${ isUpdate ? 'update' : 'link' } error: ${ error.response?.statusText }`);
+                    }
+                } else {
+                    spinner.fail(`Correction ${ isUpdate ? 'update' : 'link' } error: ${ error }`);
+                }
+            }
+
+            return false;
+        }
+    }
 }
 
 
diff --git a/NodeApp/src/shared b/NodeApp/src/shared
index 75f67b647da34337f3b220cacf78b2115d6022bc..9e3f29d2f313ef96944a199da0db39f1827c496a 160000
--- a/NodeApp/src/shared
+++ b/NodeApp/src/shared
@@ -1 +1 @@
-Subproject commit 75f67b647da34337f3b220cacf78b2115d6022bc
+Subproject commit 9e3f29d2f313ef96944a199da0db39f1827c496a
diff --git a/NodeApp/src/sharedByClients b/NodeApp/src/sharedByClients
index 098c6d20f6ed84240c086b979b56afd598fdfea4..4377a70c3c731a5426fc0d4c88c9e8858f0c5361 160000
--- a/NodeApp/src/sharedByClients
+++ b/NodeApp/src/sharedByClients
@@ -1 +1 @@
-Subproject commit 098c6d20f6ed84240c086b979b56afd598fdfea4
+Subproject commit 4377a70c3c731a5426fc0d4c88c9e8858f0c5361