diff --git a/assets/styles/app.scss b/assets/styles/app.scss
index 9b4fea673e248e6f997981aeec51f9612fc9cca7..a35eb1cd9ccfe7afe7b691c2d6d0c2c53a2c4191 100644
--- a/assets/styles/app.scss
+++ b/assets/styles/app.scss
@@ -53,7 +53,6 @@ button[type=submit]{
   border-radius: 3px;
   line-height: 1.5;
   font-size: 1rem;
-  margin: 30px 0 0 0;
   padding: .5rem 1rem;
   text-align: center;
   text-transform: uppercase;
@@ -83,8 +82,6 @@ button[type=submit]{
   box-shadow: 0 0 10px rgba(0,0,0,.5);
   border-radius: 2px;
   margin-bottom: 40px;
-  align-items: center;
-  justify-content: center;
 }
 
 .list-item {
@@ -125,7 +122,6 @@ button[type=submit]{
   text-decoration: none;
   float: left;
   color: rgba(255,255,255,.75) !important;
-  font-size: 24px;
   line-height: 60px;
   background: -webkit-linear-gradient(top left, #FA772E, #FC4326);
   -webkit-background-clip: text;
diff --git a/migrations/Version20220125084520.php b/migrations/Version20220125084520.php
new file mode 100644
index 0000000000000000000000000000000000000000..6adb95ef2255e6f1db38b11d4f1b5a18be3c9a37
--- /dev/null
+++ b/migrations/Version20220125084520.php
@@ -0,0 +1,31 @@
+<?php
+
+declare(strict_types=1);
+
+namespace DoctrineMigrations;
+
+use Doctrine\DBAL\Schema\Schema;
+use Doctrine\Migrations\AbstractMigration;
+
+/**
+ * Auto-generated Migration: Please modify to your needs!
+ */
+final class Version20220125084520 extends AbstractMigration
+{
+    public function getDescription(): string
+    {
+        return '';
+    }
+
+    public function up(Schema $schema): void
+    {
+        // this up() migration is auto-generated, please modify it to your needs
+        $this->addSql('CREATE TABLE invitation_editeur_capsule (id INT AUTO_INCREMENT NOT NULL, capsule_id INT NOT NULL, email VARCHAR(255) NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE `utf8_unicode_ci` ENGINE = InnoDB');
+    }
+
+    public function down(Schema $schema): void
+    {
+        // this down() migration is auto-generated, please modify it to your needs
+        $this->addSql('DROP TABLE invitation_editeur_capsule');
+    }
+}
diff --git a/src/Builder/CapsuleBuilder.php b/src/Builder/CapsuleBuilder.php
index ae2e0aecd1816c4ec3507ae7a71dc6003a6e8110..b219d3bcab024d36e363d369c50fbf8a9c5f7d95 100644
--- a/src/Builder/CapsuleBuilder.php
+++ b/src/Builder/CapsuleBuilder.php
@@ -33,6 +33,7 @@ class CapsuleBuilder
     {
         $this->capsule->setCreationAuthor($creation_author);
         $this->hasRequiredCreationAuthor = true;
+        $this->capsule->addEditor($creation_author);
         return $this;
     }
 
diff --git a/src/Controller/CapsuleController.php b/src/Controller/CapsuleController.php
index b169c9f4fc4eaedd9d4035c34513e45f1a36d189..039087a3d5f81f33da31b630c650cd968b005a61 100644
--- a/src/Controller/CapsuleController.php
+++ b/src/Controller/CapsuleController.php
@@ -22,12 +22,18 @@ use Symfony\Contracts\Translation\TranslatorInterface;
 
 class CapsuleController extends AbstractController
 {
+    private TranslatorInterface $translator;
+
+    public function __construct(TranslatorInterface $translator)
+    {
+        $this->translator = $translator;
+    }
+
     /**
      * @Route("/my_capsules", name="capsule_list")
      * @Route("/", name="home")
      */
     public function index(
-        CapsuleRepository $capsule_repository,
         PaginatorInterface $paginator,
         Request $request
     ): Response {
@@ -37,7 +43,7 @@ class CapsuleController extends AbstractController
             return $this->redirectToRoute('app_logout');
         }
 
-        $all_capsules = $capsule_repository->findBy(['creation_author' => $current_user]);
+        $all_capsules = $current_user->getCapsules();
 
         $capsules = $paginator->paginate(
             $all_capsules,
@@ -47,6 +53,7 @@ class CapsuleController extends AbstractController
 
         return $this->render('capsule/index.html.twig', [
             'capsules' => $capsules,
+            'current_user' => $current_user,
             'legacy_url' => $this->getParameter('app.legacy_external_prefix')
         ]);
     }
@@ -109,9 +116,15 @@ class CapsuleController extends AbstractController
             return $this->redirectToRoute('app_logout');
         }
 
-        $capsule = $capsuleRepository->findOneBy(['link_path' => $path, 'creation_author' => $current_user]);
+        $capsule = $capsuleRepository->findOneBy(['link_path' => $path]);
+
         if (null === $capsule) {
-            $this->addFlash('warning', $translator->trans('capsule.edition_not_allowed'));
+            $this->addFlash('warning', $translator->trans('capsule.edit.not_found'));
+            return $this->redirectToRoute('capsule_list');
+        }
+
+        if (! $capsule->getEditors()->contains($current_user)) {
+            $this->addFlash('warning', $translator->trans('capsule.edit.not_allowed'));
             return $this->redirectToRoute('capsule_list');
         }
 
@@ -133,9 +146,7 @@ class CapsuleController extends AbstractController
      */
     public function delete(
         int $id,
-        Request $request,
-        TranslatorInterface $translator,
-        CapsuleRepository $capsule_repository
+        Request $request
     ): Response {
         $form = $this->createForm(DeleteCapsuleFormType::class);
         $form->handleRequest($request);
@@ -148,19 +159,17 @@ class CapsuleController extends AbstractController
         $entityManager = $this->getDoctrine()->getManager();
         $capsule = $entityManager->getRepository(Capsule::class)->find($id);
 
-        if (!$capsule) {
+        if (! $capsule) {
             throw $this->createNotFoundException(
                 'No capsule found for id ' . $id
             );
         }
         $capsule_name = $capsule->getName();
 
-        $do_capsule_belongs_to_user = $capsule_repository->doCapsuleBelongsToUser($capsule, $current_user);
-
-        if (! $do_capsule_belongs_to_user) {
+        if ($capsule->getCreationAuthor() !== $current_user) {
             $this->addFlash(
                 'warning',
-                $translator->trans(
+                $this->translator->trans(
                     'capsule.delete.error',
                     [
                         'capsule_name' => $capsule_name
@@ -172,12 +181,14 @@ class CapsuleController extends AbstractController
         }
 
         if ($form->isSubmitted() && $form->isValid()) {
+            $current_user->removeCapsule($capsule);
+            $capsule->removeEditor($current_user);
             $entityManager->remove($capsule);
             $entityManager->flush();
 
             $this->addFlash(
                 'success',
-                $translator->trans(
+                $this->translator->trans(
                     'capsule.delete.success',
                     [
                         'capsule_name' => $capsule_name
@@ -200,9 +211,7 @@ class CapsuleController extends AbstractController
     public function duplicate(
         int $id,
         Request $request,
-        Filesystem $file_system,
-        TranslatorInterface $translator,
-        CapsuleRepository $capsule_repository
+        Filesystem $file_system
     ): Response {
         $form = $this->createForm(DuplicateCapsuleFormType::class);
         $form->handleRequest($request);
@@ -219,11 +228,12 @@ class CapsuleController extends AbstractController
             throw new \Exception('The retrieved capsule is not an instance of Capsule.');
         }
 
+        $capsule_editors = $parent_capsule->getEditors();
 
-        if (! $capsule_repository->doCapsuleBelongsToUser($parent_capsule, $current_user)) {
+        if (! in_array($current_user, $capsule_editors->toArray())) {
             $this->addFlash(
                 'warning',
-                $translator->trans(
+                $this->translator->trans(
                     'capsule.duplicate.error',
                     [
                         'capsule_name' => $parent_capsule->getName()
@@ -239,7 +249,7 @@ class CapsuleController extends AbstractController
         if (! $parent_directory_exists) {
             $this->addFlash(
                 'warning',
-                $translator->trans(
+                $this->translator->trans(
                     'project.not_exist',
                     [
                         'capsule_name' => $parent_capsule->getName()
diff --git a/src/Controller/CapsuleEditorController.php b/src/Controller/CapsuleEditorController.php
new file mode 100644
index 0000000000000000000000000000000000000000..39af5fe0d9eed11481ea796bcce07d88f0320f19
--- /dev/null
+++ b/src/Controller/CapsuleEditorController.php
@@ -0,0 +1,219 @@
+<?php
+
+namespace App\Controller;
+
+use App\Entity\Capsule;
+use App\Entity\CapsuleEditor;
+use App\Entity\CapsulePendingEditor;
+use App\Entity\User;
+use App\Form\CapsuleEditorsFormType;
+use App\Repository\CapsulePendingEditorRepository;
+use App\Repository\CapsuleRepository;
+use App\Repository\UserRepository;
+use Doctrine\ORM\EntityManagerInterface;
+use http\Env;
+use Symfony\Bridge\Twig\Mime\TemplatedEmail;
+use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\Mailer\Exception\TransportExceptionInterface;
+use Symfony\Component\Mailer\MailerInterface;
+use Symfony\Component\Routing\Annotation\Route;
+use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
+use Symfony\Contracts\Translation\TranslatorInterface;
+
+class CapsuleEditorController extends AbstractController
+{
+    private TranslatorInterface $translator;
+    private MailerInterface $mailer;
+    private CapsulePendingEditorRepository $capsule_pending_editor_repository;
+    private EntityManagerInterface $entity_manager;
+    private UrlGeneratorInterface $urlGenerator;
+
+    public function __construct(
+        MailerInterface $mailer,
+        TranslatorInterface $translator,
+        CapsulePendingEditorRepository $capsule_pending_editor_repository,
+        EntityManagerInterface $entity_manager,
+        UrlGeneratorInterface $urlGenerator
+    ) {
+        $this->mailer = $mailer;
+        $this->translator = $translator;
+        $this->capsule_pending_editor_repository = $capsule_pending_editor_repository;
+        $this->entity_manager = $entity_manager;
+        $this->urlGenerator = $urlGenerator;
+    }
+
+    /**
+     * @Route("/capsule/{capsule_id}/editors", name="edit_capsule_editors")
+     */
+    public function editCapsuleEditors(
+        Request $request,
+        int $capsule_id,
+        CapsuleRepository $capsule_repository,
+        UserRepository $user_repository
+    ): Response {
+        $current_user = $this->getUser();
+        if (! $current_user instanceof User) {
+            return $this->redirectToRoute('app_logout');
+        }
+
+        $capsule = $capsule_repository->find($capsule_id);
+        if (! $capsule) {
+            throw $this->createNotFoundException(
+                'No capsule found for id ' . $capsule_id
+            );
+        }
+
+        $current_capsule_editors_users = $capsule->getEditors()->toArray();
+        if (! $capsule->getEditors()->contains($current_user)) {
+//            in_array($current_user, $current_capsule_editors_users)) {
+            $this->addFlash(
+                'warning',
+                $this->translator->trans(
+                    'editors.user_not_editor_error',
+                    [
+                        'capsule_name' => $capsule->getName()
+                    ]
+                )
+            );
+
+            return $this->redirectToRoute('capsule_list');
+        }
+
+        $form = $this->createForm(CapsuleEditorsFormType::class);
+        $form->handleRequest($request);
+
+        if ($form->isSubmitted() && $form->isValid()) {
+            $editor_email = $form->get('email')->getData();
+            $user_associated_with_email_address = $user_repository
+                                                ->findOneBy(['email' => $editor_email]);
+
+            if (! $user_associated_with_email_address instanceof User) {
+                $this->addPendingEditor($editor_email, $capsule, $current_user);
+            } else {
+                $this->addEditor(
+                    $editor_email,
+                    $capsule,
+                    $current_user,
+                    $user_associated_with_email_address,
+                    $current_capsule_editors_users
+                );
+            }
+
+            return $this->redirectToRoute('edit_capsule_editors', [
+                'capsule_id' => $capsule_id
+            ]);
+        }
+
+        $pending_editors = $this->capsule_pending_editor_repository->findBy(['capsule_id' => $capsule_id]);
+
+        return $this->render('capsule/editors/list_editors.html.twig', [
+            'userPermissionsCapsuleForm' => $form->createView(),
+            'capsule_name' => $capsule->getName(),
+            'editors' => $current_capsule_editors_users,
+            'pending_editors' => $pending_editors
+        ]);
+    }
+
+    private function addPendingEditor(string $editor_email, Capsule $capsule, User $current_user): void
+    {
+        $pending_editors_emails = $this->capsule_pending_editor_repository->getPendingEditorsEmails($capsule->getId());
+
+        if (in_array($editor_email, $pending_editors_emails)) {
+            $this->addFlash(
+                'warning',
+                $this->translator->trans(
+                    'editors.add.pending_editor.already_added',
+                    [
+                        'user_email' => $editor_email
+                    ]
+                )
+            );
+            return;
+        }
+
+        $pending_editor = new CapsulePendingEditor();
+        $pending_editor->setCapsuleId($capsule->getId());
+        $pending_editor->setEmail($editor_email);
+        $this->entity_manager->persist($pending_editor);
+        $this->entity_manager->flush();
+
+        $email = (new TemplatedEmail())
+            ->to($editor_email)
+            ->subject($this->translator->trans('editors.add.pending_editor.email.title'))
+            ->htmlTemplate('capsule/editors/email_pending_editor.html.twig')
+            ->context([
+                'user' => $current_user,
+                'capsule' => $capsule
+            ]);
+
+        $this->mailer->send($email);
+
+        $this->addFlash(
+            'success',
+            $this->translator->trans(
+                'editors.add.pending_editor.success',
+                [
+                    'user_email' => $editor_email
+                ]
+            )
+        );
+    }
+
+    /**
+     * @param array<User> $current_capsule_editors_users
+     * @throws TransportExceptionInterface
+     */
+    private function addEditor(
+        string $editor_email,
+        Capsule $capsule,
+        User $current_user,
+        User $user_associated_with_email_address,
+        array $current_capsule_editors_users
+    ): void {
+        if (in_array($user_associated_with_email_address, $current_capsule_editors_users)) {
+            $this->addFlash(
+                'warning',
+                $this->translator->trans(
+                    'editors.add.user.already_added',
+                    [
+                        'user_email' => $editor_email
+                    ]
+                )
+            );
+            return;
+        }
+
+        $capsule->addEditor($user_associated_with_email_address);
+        $this->entity_manager->persist($capsule);
+        $this->entity_manager->flush();
+
+        $email = (new TemplatedEmail())
+            ->to($editor_email)
+            ->subject($this->translator->trans('editors.add.user.email.title'))
+            ->htmlTemplate('capsule/editors/email_editor.html.twig')
+            ->context([
+                'user' => $current_user,
+                'capsule' => $capsule,
+                'capsule_edit_link' => $this->urlGenerator->generate(
+                    'edit_capsule',
+                    [ 'path' => $capsule->getLinkPath() ],
+                    UrlGeneratorInterface::ABSOLUTE_URL
+                )
+            ]);
+
+        $this->mailer->send($email);
+
+        $this->addFlash(
+            'success',
+            $this->translator->trans(
+                'editors.add.user.success',
+                [
+                    'capsule_name' => $capsule->getName(),
+                    'user_email' => $editor_email
+                ]
+            )
+        );
+    }
+}
diff --git a/src/Controller/RegistrationController.php b/src/Controller/RegistrationController.php
index e4f1245537cc8065dbf7a2dcb7dabd96ddd4b28d..faf3031cd5bba07f1c84c359574d3b02eadb83b8 100644
--- a/src/Controller/RegistrationController.php
+++ b/src/Controller/RegistrationController.php
@@ -2,8 +2,12 @@
 
 namespace App\Controller;
 
+use App\Entity\Capsule;
+use App\Entity\PendingEditorInvitation;
 use App\Entity\User;
 use App\Form\RegistrationFormType;
+use App\Repository\CapsuleRepository;
+use App\Repository\PendingEditorInvitationRepository;
 use App\Repository\UserRepository;
 use App\Security\EmailVerifier;
 use Doctrine\ORM\EntityManagerInterface;
@@ -12,7 +16,6 @@ use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
 use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\HttpFoundation\RequestStack;
 use Symfony\Component\HttpFoundation\Response;
-use Symfony\Component\Mime\Address;
 use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
 use Symfony\Component\Routing\Annotation\Route;
 use Symfony\Contracts\Translation\TranslatorInterface;
@@ -22,13 +25,16 @@ class RegistrationController extends AbstractController
 {
     private EmailVerifier $emailVerifier;
     private RequestStack $requestStack;
+    private EntityManagerInterface $entity_manager;
 
     public function __construct(
         EmailVerifier $emailVerifier,
-        RequestStack $requestStack
+        RequestStack $requestStack,
+        EntityManagerInterface $entity_manager
     ) {
         $this->emailVerifier = $emailVerifier;
         $this->requestStack = $requestStack;
+        $this->entity_manager = $entity_manager;
     }
 
     /**
@@ -36,8 +42,7 @@ class RegistrationController extends AbstractController
      */
     public function register(
         Request $request,
-        UserPasswordHasherInterface $userPasswordHasher,
-        EntityManagerInterface $entityManager
+        UserPasswordHasherInterface $userPasswordHasher
     ): Response {
         if ($this->getUser()) {
             return $this->redirectToRoute('capsule_list');
@@ -58,21 +63,20 @@ class RegistrationController extends AbstractController
                 )
             );
 
-            $entityManager->persist($user);
-            $entityManager->flush();
+            $this->entity_manager->persist($user);
+            $this->entity_manager->flush();
 
             // generate a signed url and email it to the user
             $this->emailVerifier->sendEmailConfirmation(
                 'app_verify_email',
-                $user,
+                $user->getId(),
+                $user->getEmail(),
                 (new TemplatedEmail())
                     ->to($user->getEmail())
                     ->subject('Please Confirm your Email')
                     ->htmlTemplate('registration/confirmation_email.html.twig')
             );
 
-            // do anything else you need here, like send an email
-            // return $this->redirectToRoute('app_login');
             $this->requestStack->getSession()->set('userid', $user->getId());
             return $this->redirectToRoute('app_register_mail_sent');
         }
@@ -88,6 +92,8 @@ class RegistrationController extends AbstractController
     public function verifyUserEmail(
         Request $request,
         UserRepository $userRepository,
+        PendingEditorInvitationRepository $pending_editor_invitation_repository,
+        CapsuleRepository $capsule_repository,
         TranslatorInterface $translator
     ): Response {
         $id = $request->get('id');
@@ -111,6 +117,12 @@ class RegistrationController extends AbstractController
             return $this->redirectToRoute('app_register');
         }
 
+        $this->addCapsuleToConfirmedPreviousPendingEditor(
+            $user,
+            $pending_editor_invitation_repository,
+            $capsule_repository
+        );
+
         $this->addFlash(
             'email_verified_success',
             $translator->trans('registration.email_verified_success')
@@ -132,4 +144,58 @@ class RegistrationController extends AbstractController
             ['user' =>  $user]
         );
     }
+
+    private function addCapsuleToConfirmedPreviousPendingEditor(
+        User $user,
+        PendingEditorInvitationRepository $pending_editor_invitation_repository,
+        CapsuleRepository $capsule_repository
+    ): void {
+        $pending_editor_invitations = $pending_editor_invitation_repository->findBy(['email' => $user->getEmail()]);
+
+        if ($pending_editor_invitations == null) {
+            return;
+        }
+
+        $capsules_ids = $this->removeInvitations($pending_editor_invitations);
+        $this->addEditorToCapsules($capsules_ids, $user, $capsule_repository);
+    }
+
+    /**
+     * @param array<PendingEditorInvitation> $pending_editor_invitations
+     * @return array<int>
+     */
+    private function removeInvitations(array $pending_editor_invitations): array
+    {
+        $capsules_ids = [];
+
+        foreach ($pending_editor_invitations as $invitation) {
+            if (! $invitation instanceof PendingEditorInvitation) {
+                return $capsules_ids;
+            }
+            $capsules_ids[] = $invitation->getCapsuleId();
+            $this->entity_manager->remove($invitation);
+        }
+
+        return $capsules_ids;
+    }
+
+    /**
+     * @param array<int> $capsules_ids
+     */
+    private function addEditorToCapsules(
+        array $capsules_ids,
+        User $user,
+        CapsuleRepository $capsule_repository
+    ): void {
+        $capsules = $capsule_repository->findBy(['id' => $capsules_ids]);
+
+        foreach ($capsules as $capsule) {
+            if (! $capsule instanceof Capsule) {
+                return;
+            }
+            $capsule->addEditor($user);
+            $this->entity_manager->persist($capsule);
+        }
+        $this->entity_manager->flush();
+    }
 }
diff --git a/src/Entity/Capsule.php b/src/Entity/Capsule.php
index 497fa3377354d73958331c735b73e236c76ffbff..4e5249f4215ec05acdd33bcf933604fc6bf5bdaa 100644
--- a/src/Entity/Capsule.php
+++ b/src/Entity/Capsule.php
@@ -32,7 +32,7 @@ class Capsule
 
     /**
      *
-     * @ORM\ManyToOne(targetEntity="App\Entity\User", inversedBy="capsulesCreated")
+     * @ORM\ManyToOne(targetEntity="App\Entity\User")
      * @ORM\JoinColumn(name="aut_crea", referencedColumnName="id", nullable=false)
      *
      */
@@ -46,7 +46,7 @@ class Capsule
 
     /**
      *
-     * @ORM\ManyToOne(targetEntity="App\Entity\User", inversedBy="capsulesEdited")
+     * @ORM\ManyToOne(targetEntity="App\Entity\User")
      * @ORM\JoinColumn(name="aut_maj", referencedColumnName="id")
      *
      */
@@ -77,6 +77,22 @@ class Capsule
      */
     private string $password;
 
+    /**
+     * @var Collection<User>
+     *
+     * @ORM\ManyToMany(targetEntity="App\Entity\User", inversedBy="capsules")
+     * @ORM\JoinTable(name="editeur_capsule",
+     *   joinColumns={@ORM\JoinColumn(name="capsule_id", referencedColumnName="id")},
+     *   inverseJoinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")}
+     * )
+     */
+    private Collection $editors;
+
+    public function __construct()
+    {
+        $this->editors = new ArrayCollection();
+    }
+
     public function getId(): int
     {
         return $this->id;
@@ -172,4 +188,25 @@ class Capsule
     {
         $this->password = $password;
     }
+
+    public function addEditor(User $editor): void
+    {
+        $editor->addCapsule($this);
+        $this->editors[] = $editor;
+    }
+
+    public function removeEditor(User $editor): Capsule
+    {
+        $editor->removeCapsule($this);
+        $this->editors->removeElement($editor);
+        return $this;
+    }
+
+    /**
+     * @return Collection<User> $editors
+     */
+    public function getEditors(): Collection
+    {
+        return $this->editors;
+    }
 }
diff --git a/src/Entity/CapsulePendingEditor.php b/src/Entity/CapsulePendingEditor.php
new file mode 100644
index 0000000000000000000000000000000000000000..6dd010a96f837a03da48c7a80119c096cfd35d9e
--- /dev/null
+++ b/src/Entity/CapsulePendingEditor.php
@@ -0,0 +1,62 @@
+<?php
+
+namespace App\Entity;
+
+use App\Repository\CapsulePendingEditorRepository;
+use Doctrine\ORM\Mapping as ORM;
+
+/**
+ * @ORM\Table(name="invitation_editeur_capsule")
+ * @ORM\Entity(repositoryClass=CapsulePendingEditorRepository::class)
+ */
+class CapsulePendingEditor
+{
+    /**
+     * @ORM\Id
+     * @ORM\GeneratedValue
+     * @ORM\Column(type="integer")
+     */
+    private int $id;
+
+    /**
+     * @ORM\Column(type="integer")
+     * @ORM\Column(name="capsule_id", type="integer", nullable=false)
+     * @ORM\ManyToOne(targetEntity="App\Entity\Capsule", inversedBy="id")
+     * @ORM\JoinColumn(name="capsule_id", referencedColumnName="id")
+     */
+    private int $capsule_id;
+
+    /**
+     * @ORM\Column(name="email", type="string", length=255, nullable=false)
+     */
+    private string $email;
+
+    public function getId(): int
+    {
+        return $this->id;
+    }
+
+    public function getCapsuleId(): int
+    {
+        return $this->capsule_id;
+    }
+
+    public function setCapsuleId(int $capsule_id): self
+    {
+        $this->capsule_id = $capsule_id;
+
+        return $this;
+    }
+
+    public function getEmail(): string
+    {
+        return $this->email;
+    }
+
+    public function setEmail(string $email): self
+    {
+        $this->email = $email;
+
+        return $this;
+    }
+}
diff --git a/src/Entity/PendingEditorInvitation.php b/src/Entity/PendingEditorInvitation.php
new file mode 100644
index 0000000000000000000000000000000000000000..b0bb5da206b3214717712efe4baf401eb146e43d
--- /dev/null
+++ b/src/Entity/PendingEditorInvitation.php
@@ -0,0 +1,61 @@
+<?php
+
+namespace App\Entity;
+
+use App\Repository\PendingEditorInvitationRepository;
+use Doctrine\ORM\Mapping as ORM;
+
+/**
+ * @ORM\Table(name="invitation_editeur_capsule")
+ * @ORM\Entity(repositoryClass=PendingEditorInvitationRepository::class)
+ */
+class PendingEditorInvitation
+{
+    /**
+     * @ORM\Id
+     * @ORM\GeneratedValue
+     * @ORM\Column(type="integer")
+     */
+    private int $id;
+
+    /**
+     * @ORM\Column(name="capsule_id", type="integer", nullable=false)
+     * @ORM\ManyToOne(targetEntity="App\Entity\Capsule", inversedBy="id")
+     * @ORM\JoinColumn(name="capsule_id", referencedColumnName="id")
+     */
+    private int $capsule_id;
+
+    /**
+     * @ORM\Column(type="string", length=255)
+     */
+    private string $email;
+
+    public function getId(): int
+    {
+        return $this->id;
+    }
+
+    public function getCapsuleId(): int
+    {
+        return $this->capsule_id;
+    }
+
+    public function setCapsuleId(int $capsule_id): self
+    {
+        $this->capsule_id = $capsule_id;
+
+        return $this;
+    }
+
+    public function getEmail(): string
+    {
+        return $this->email;
+    }
+
+    public function setEmail(string $email): self
+    {
+        $this->email = $email;
+
+        return $this;
+    }
+}
diff --git a/src/Entity/User.php b/src/Entity/User.php
index 0eca9ce6ecedb6fcbdc340ccc8de8cc85dad9d09..5e2fa78e79170b4c426426ee972c89725c669432 100644
--- a/src/Entity/User.php
+++ b/src/Entity/User.php
@@ -3,6 +3,8 @@
 namespace App\Entity;
 
 use App\Repository\UserRepository;
+use Doctrine\Common\Collections\ArrayCollection;
+use Doctrine\Common\Collections\Collection;
 use Doctrine\ORM\Mapping as ORM;
 use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
 use Symfony\Component\Security\Core\User\LegacyPasswordAuthenticatedUserInterface;
@@ -81,6 +83,17 @@ class User implements UserInterface, LegacyPasswordAuthenticatedUserInterface
      */
     private string $salt;
 
+    /**
+     * @var Collection<Capsule>
+     * @ORM\ManyToMany(targetEntity="App\Entity\Capsule", mappedBy="editors")
+     */
+    private Collection $capsules;
+
+    public function __construct()
+    {
+        $this->capsules = new ArrayCollection();
+    }
+
     public function getId(): int
     {
         return $this->id;
@@ -211,4 +224,28 @@ class User implements UserInterface, LegacyPasswordAuthenticatedUserInterface
     {
         $this->salt = $salt;
     }
+
+    public function getFullName(): string
+    {
+        return $this->firstName . " " . $this->lastName;
+    }
+
+    /**
+     * @return Collection<Capsule>
+     */
+    public function getCapsules(): Collection
+    {
+        return $this->capsules;
+    }
+
+    public function addCapsule(Capsule $capsule): void
+    {
+        $this->capsules[] = $capsule;
+    }
+
+    public function removeCapsule(Capsule $capsule): User
+    {
+        $this->capsules->removeElement($capsule);
+        return $this;
+    }
 }
diff --git a/src/Form/CapsuleEditorsFormType.php b/src/Form/CapsuleEditorsFormType.php
new file mode 100644
index 0000000000000000000000000000000000000000..c6ccec919dc8206875622a423caea472607784b7
--- /dev/null
+++ b/src/Form/CapsuleEditorsFormType.php
@@ -0,0 +1,41 @@
+<?php
+
+namespace App\Form;
+
+use App\Entity\User;
+use Symfony\Component\Form\AbstractType;
+use Symfony\Component\Form\Extension\Core\Type\EmailType;
+use Symfony\Component\Form\Extension\Core\Type\PasswordType;
+use Symfony\Component\Form\Extension\Core\Type\SubmitType;
+use Symfony\Component\Form\Extension\Core\Type\TextType;
+use Symfony\Component\Form\FormBuilderInterface;
+use Symfony\Component\OptionsResolver\OptionsResolver;
+use Symfony\Component\Security\Core\Validator\Constraints\UserPassword;
+use Symfony\Component\Validator\Constraints\NotBlank;
+
+class CapsuleEditorsFormType extends AbstractType
+{
+    public function buildForm(FormBuilderInterface $builder, array $options): void
+    {
+        $builder
+            ->add(
+                'email',
+                EmailType::class,
+                [
+                    'constraints' => [new NotBlank(['message' => 'email.not_blank'])],
+                    'label' => 'editors.add_email_address',
+                    'empty_data' => ''
+                ]
+            )
+            ->add(
+                'validate',
+                SubmitType::class,
+                ['label' => 'general.validate']
+            );
+    }
+
+    public function configureOptions(OptionsResolver $resolver): void
+    {
+        $resolver->setDefaults([]);
+    }
+}
diff --git a/src/Repository/CapsulePendingEditorRepository.php b/src/Repository/CapsulePendingEditorRepository.php
new file mode 100644
index 0000000000000000000000000000000000000000..1504d2e8f9065246a327cfc2069f9abf50a34080
--- /dev/null
+++ b/src/Repository/CapsulePendingEditorRepository.php
@@ -0,0 +1,43 @@
+<?php
+
+namespace App\Repository;
+
+use App\Entity\CapsulePendingEditor;
+use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
+use Doctrine\Persistence\ManagerRegistry;
+
+/**
+ * @method CapsulePendingEditor|null find($id, $lockMode = null, $lockVersion = null)
+ * @method CapsulePendingEditor|null findOneBy(array $criteria, array $orderBy = null)
+ * @method CapsulePendingEditor[]    findAll()
+ * @method CapsulePendingEditor[]    findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
+ */
+class CapsulePendingEditorRepository extends ServiceEntityRepository
+{
+    public function __construct(ManagerRegistry $registry)
+    {
+        parent::__construct($registry, CapsulePendingEditor::class);
+    }
+
+    /**
+     * @return array<string>
+     */
+    public function getPendingEditorsEmails(int $capsule_id): array
+    {
+        $editors_emails_result = $this->createQueryBuilder('c')
+            ->select('c.email')
+            ->andWhere('c.capsule_id = :val')
+            ->setParameter('val', $capsule_id)
+            ->getQuery()
+            ->getResult()
+            ;
+
+        $editors_emails = [];
+
+        foreach ($editors_emails_result as $editor_email_result) {
+            $editors_emails[] = $editor_email_result['email'];
+        }
+
+        return $editors_emails;
+    }
+}
diff --git a/src/Repository/CapsuleRepository.php b/src/Repository/CapsuleRepository.php
index 7e5cd9f9e9820c23e9b5eda5685c5c3772130af8..97f8c23b7d7b22057dd08aca2f00a24193597bd0 100644
--- a/src/Repository/CapsuleRepository.php
+++ b/src/Repository/CapsuleRepository.php
@@ -21,11 +21,4 @@ class CapsuleRepository extends ServiceEntityRepository
     {
         parent::__construct($registry, Capsule::class);
     }
-
-    public function doCapsuleBelongsToUser(Capsule $capsule, User $user): bool
-    {
-        return
-            $capsule->getCreationAuthor() === $user ||
-            $capsule->getUpdateAuthor() === $user;
-    }
 }
diff --git a/src/Repository/PendingEditorInvitationRepository.php b/src/Repository/PendingEditorInvitationRepository.php
new file mode 100644
index 0000000000000000000000000000000000000000..e891144dd03e5b31229c3707ea86c82f6bca48a8
--- /dev/null
+++ b/src/Repository/PendingEditorInvitationRepository.php
@@ -0,0 +1,62 @@
+<?php
+
+namespace App\Repository;
+
+use App\Entity\PendingEditorInvitation;
+use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
+use Doctrine\Persistence\ManagerRegistry;
+
+/**
+ * @method PendingEditorInvitation|null find($id, $lockMode = null, $lockVersion = null)
+ * @method PendingEditorInvitation|null findOneBy(array $criteria, array $orderBy = null)
+ * @method PendingEditorInvitation[]    findAll()
+ * @method PendingEditorInvitation[]    findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
+ */
+class PendingEditorInvitationRepository extends ServiceEntityRepository
+{
+    public function __construct(ManagerRegistry $registry)
+    {
+        parent::__construct($registry, PendingEditorInvitation::class);
+    }
+
+    /**
+     * @return array<PendingEditorInvitation>
+     */
+    public function getInvitationByCapsule(int $capsule_id): array
+    {
+        $query = $this->createQueryBuilder('i')
+            ->where("i.capsuleId like :capId")
+            ->setParameter("capId", $capsule_id)
+            ->getQuery();
+        return $query->getArrayResult();
+    }
+
+    // /**
+    //  * @return PendingEditorInvitation[] Returns an array of PendingEditorInvitation objects
+    //  */
+    /*
+    public function findByExampleField($value)
+    {
+        return $this->createQueryBuilder('p')
+            ->andWhere('p.exampleField = :val')
+            ->setParameter('val', $value)
+            ->orderBy('p.id', 'ASC')
+            ->setMaxResults(10)
+            ->getQuery()
+            ->getResult()
+        ;
+    }
+    */
+
+    /*
+    public function findOneBySomeField($value): ?PendingEditorInvitation
+    {
+        return $this->createQueryBuilder('p')
+            ->andWhere('p.exampleField = :val')
+            ->setParameter('val', $value)
+            ->getQuery()
+            ->getOneOrNullResult()
+        ;
+    }
+    */
+}
diff --git a/src/Repository/UserRepository.php b/src/Repository/UserRepository.php
index 28987a479e6a77f48bec686763edb56a22379b37..147f8c5c26d5ab001ea4d65733de9cf19b9aebd3 100644
--- a/src/Repository/UserRepository.php
+++ b/src/Repository/UserRepository.php
@@ -4,6 +4,8 @@ namespace App\Repository;
 
 use App\Entity\User;
 use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
+use Doctrine\DBAL\Exception;
+use Doctrine\DBAL\Exception\DatabaseObjectNotFoundException;
 use Doctrine\Persistence\ManagerRegistry;
 use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
 use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
@@ -57,4 +59,17 @@ class UserRepository extends ServiceEntityRepository implements PasswordUpgrader
             ->getOneOrNullResult()
             ;
     }
+
+    /**
+     * @param array<int> $user_ids
+     * @return array<User>
+     */
+    public function getUsersFromIds(array $user_ids): array
+    {
+        return $this->createQueryBuilder('u')
+            ->andWhere('u.id in (:ids)')
+            ->setParameter('ids', $user_ids)
+            ->getQuery()
+            ->getResult();
+    }
 }
diff --git a/src/Security/EmailVerifier.php b/src/Security/EmailVerifier.php
index 84ee1dfdb13b02b19d1677a83d1c0a6552b4c118..ea4389fcac727b3d0ffa02f431f47845f93c0382 100644
--- a/src/Security/EmailVerifier.php
+++ b/src/Security/EmailVerifier.php
@@ -28,14 +28,15 @@ class EmailVerifier
 
     public function sendEmailConfirmation(
         string $verifyEmailRouteName,
-        User $user,
+        int $user_id,
+        string $email_address,
         TemplatedEmail $email
     ): void {
         $signatureComponents = $this->verifyEmailHelper->generateSignature(
             $verifyEmailRouteName,
-            (string) $user->getId(),
-            $user->getEmail(),
-            ['id' => $user->getId()]
+            (string) $user_id,
+            $email_address,
+            ['id' => $user_id]
         );
 
         $context = $email->getContext();
diff --git a/templates/capsule/editors/email_editor.html.twig b/templates/capsule/editors/email_editor.html.twig
new file mode 100644
index 0000000000000000000000000000000000000000..02ed4041f2a601d1ea83b922e33bb678c672cef9
--- /dev/null
+++ b/templates/capsule/editors/email_editor.html.twig
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <meta charset="UTF-8">
+        <title>
+            {{ 'editors.add.user.email.title'|trans }}
+        </title>
+    </head>
+
+    <body>
+        <div class="container d-flex flex-row justify-content-center">
+            <div class="col-6">
+                <p class="alert">
+                    {{ 'editors.add.user.email.text'|trans(
+                        {'%user_name%': user.getFullName(), '%capsule_name%': capsule.getName()}) }}
+                    <a href="{{ capsule_edit_link }}">
+                        {{ 'editors.add.user.email.link'|trans }}
+                    </a>
+                </p>
+
+                <p>{{ 'general.greeting'|trans }}</p>
+            </div>
+        </div>
+    </body>
+</html>
\ No newline at end of file
diff --git a/templates/capsule/editors/email_pending_editor.html.twig b/templates/capsule/editors/email_pending_editor.html.twig
new file mode 100644
index 0000000000000000000000000000000000000000..8fcaa41b6ec8a88002effd775fbedf3f38ec32fd
--- /dev/null
+++ b/templates/capsule/editors/email_pending_editor.html.twig
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="UTF-8">
+    <title>
+        {{ 'editors.add.pending_editor.email.title'|trans }}
+    </title>
+</head>
+
+<body>
+<div class="container d-flex flex-row justify-content-center">
+    <div class="col-6">
+        <p class="alert">
+            {{ 'editors.add.pending_editor.email.text'|trans({'%user_name%': user.getFullName(), '%capsule_name%': capsule.getName()}) }} :
+
+            <a href="{{ 'editors.add.pending_editor.email.link'|trans }}">
+                {{ 'editors.add.pending_editor.email.link_name'|trans }}
+            </a>
+        </p>
+
+        <p>{{ 'general.greeting'|trans }}</p>
+    </div>
+</div>
+</body>
+</html>
\ No newline at end of file
diff --git a/templates/capsule/editors/list_editors.html.twig b/templates/capsule/editors/list_editors.html.twig
new file mode 100644
index 0000000000000000000000000000000000000000..31e7e6627efd798d1b19c863bac93ea06d7584cd
--- /dev/null
+++ b/templates/capsule/editors/list_editors.html.twig
@@ -0,0 +1,68 @@
+{% extends 'layout.html.twig' %}
+
+{% block title %}
+    {{ 'editors.title'|trans }}
+    -
+    {{ parent() }}
+{% endblock %}
+
+{% block body %}
+
+    <div>
+        <div class="row w-100 gx-0">
+            <div class="row-title-box">
+                <h3 class="row-title">
+                    {{ 'editors.title_name'|trans({'%capsule_name%': capsule_name}) }}
+                </h3>
+            </div>
+        </div>
+
+        {% for flashWarning in app.flashes('warning') %}
+            <div class="text-center alert alert-warning col-5 mx-auto my-5 mt-2" role="alert">
+                {{ flashWarning }}
+            </div>
+        {% endfor %}
+
+        {% for flashSuccess in app.flashes('success') %}
+            <div class="text-center alert alert-success col-5 mx-auto my-5 mt-2" role="alert">
+                {{ flashSuccess }}
+            </div>
+        {% endfor %}
+
+        <div class="d-flex flex-md-row flex-column justify-content-center">
+            <div class="d-flex flex-column justify-content-center ms-md-5 ms-0 order-md-2 mb-4 col-sm-8 col-md-6 col-lg-5 col-xl-4">
+                {{ form_start(userPermissionsCapsuleForm, {'attr': {novalidate: 'novalidate'}}) }}
+                {{ form_row(userPermissionsCapsuleForm.email, {'row_attr': {'class' : 'm-auto mb-4'}})  }}
+                {{ form_row(userPermissionsCapsuleForm.validate) }}
+                {{ form_end(userPermissionsCapsuleForm) }}
+            </div>
+
+            <div class="d-flex flex-row pe-md-5 pb-3 fw-normal me-0 me-md-5">
+                <div class="pe-3 pe-md-4 text-nowrap">
+                    <h5>
+                        {{ 'editors.current_editors_title'|trans }}
+                    </h5>
+                    <ul class="ps-0">
+                    {% for editor in editors %}
+                        <li class="text-capitalize text-secondary list-unstyled p-1">
+                            {{ editor.getFirstName()  }} {{ editor.getLastName() }}
+                        </li>
+                    {% endfor %}
+                    </ul>
+                    <h5>
+                        {{ 'editors.pending_editors_title'|trans }}
+                    </h5>
+                    <ul class="ps-1">
+                    {% for pending_editor in pending_editors %}
+                        <li class="text-secondary list-unstyled p-1">
+                            {{ pending_editor.getEmail() }}
+                        </li>
+                    {% endfor %}
+                    </ul>
+                </div>
+            </div>
+
+        </div>
+    </div>
+
+{%  endblock %}
\ No newline at end of file
diff --git a/templates/capsule/index.html.twig b/templates/capsule/index.html.twig
index c18fa5a17306da3c14718cc9a186e3e0704b011e..64c31b6c823d34e31fbe30f5e34c7f138cd64267 100644
--- a/templates/capsule/index.html.twig
+++ b/templates/capsule/index.html.twig
@@ -8,20 +8,23 @@
 
 {% block body %}
     <div class="row gx-0">
-        <div class="row-title-box">
-            <h3 class="row-title">
+        <div class="row-title-box d-flex justify-content-between align-items-center">
+            <h2 class="row-title">
                 {{ 'capsule.title'|trans }}
-            </h3>
+            </h2>
+            <form class="d-none d-md-flex">
+                <button id="btn-orange" formaction="/create">
+                    + {{ 'capsule.create_capsule'|trans }}
+                </button>
+            </form>
         </div>
     </div>
-<div class="mt-4">
-    <div class="d-flex justify-content-center align-items-center">
-        <form>
-            <button id="btn-orange" formaction="/create">
-               + {{ 'capsule.create_capsule'|trans }}
-            </button>
-        </form>
-    </div>
+
+    <form class="d-md-none d-flex justify-content-center align-items-center">
+        <button id="btn-orange" formaction="/create">
+           + {{ 'capsule.create_capsule'|trans }}
+        </button>
+    </form>
 
     {% for flashWarning in app.flashes('warning') %}
         <div class="text-center alert alert-warning col-5 mx-auto my-5" role="alert">
@@ -37,9 +40,9 @@
 
 </div>
 
-    <div class="capsules-list d-flex flex-column m-6">
+    <div class="d-flex flex-column align-items-center mt-4 mb-4">
         {% for capsule in capsules %}
-        <div class="capsule-item pb-4 m-5">
+        <div class="capsule-item pb-4 col-12 col-lg-10 col-xl-8">
             <div class="d-flex flex-column flex-md-row justify-content-center align-items-center mt-sm-4">
                 <div class="list-item">
                     <a href="/capsule/preview/{{ capsule.getLinkPath() }}" class="capsule-title">
@@ -64,7 +67,7 @@
                     <i class="fa-thin fa-gears"></i>
 
                     <div class="list-item text-nowrap">
-                        <a href="" class="links text-decoration-none">
+                        <a href="/capsule/{{ capsule.getId() }}/editors" class="links text-decoration-none">
                             <i class="fas fa-cog m-2"></i>
                             {{ 'capsule.edit_permissions.link'|trans }}
                         </a>
@@ -75,12 +78,16 @@
                             {{ 'capsule.duplicate.link'|trans }}
                         </a>
                     </div>
+
+                    {% if capsule.getCreationauthor() is same as current_user %}
                     <div class="list-item text-nowrap">
                         <a href="/capsule/delete/{{ capsule.getId() }}" class="links text-decoration-none">
                             <i class="fas fa-trash m-2"></i>
                             {{ 'capsule.delete.link'|trans }}
                         </a>
                     </div>
+                    {% endif %}
+
                     <a href="capsule/edit/{{ capsule.getLinkPath() }}" class="list-item text-nowrap lh-md">
                         <button class="standard-button p-2">
                             {{ 'capsule.edit.link'|trans }}
diff --git a/templates/layout.html.twig b/templates/layout.html.twig
index bec0bce48dfa091ed8c509a023908b09a45e174a..deb0ae75ea6f813f39bca214619befa203c58f9c 100644
--- a/templates/layout.html.twig
+++ b/templates/layout.html.twig
@@ -18,7 +18,7 @@
 
 </head>
 
-<body class="container col-10 col-md-8 col-lg-6 m-auto">
+<body class="container col-10 col-md-8 m-auto">
 <div class="position-relative d-flex flex-row align-items-center justify-content-center mb-5">
   <a href="/my_capsules" class="align-self-center">
     <img id="header-memorekall-logo" class="memorekall-logo" src="{{ asset('build/images/MemoRekall.png') }}">
diff --git a/templates/registration/register.html.twig b/templates/registration/register.html.twig
index 45e7b0fdd73cf56386a7f22154511129a1796d82..c7096b6cec7044037752f1031d66aa96f4485cfb 100644
--- a/templates/registration/register.html.twig
+++ b/templates/registration/register.html.twig
@@ -11,14 +11,14 @@
     {% endfor %}
 
     {{ form_start(registrationForm, {'attr': {novalidate: 'novalidate', 'class': 'd-flex flex-column justify-content-center'}}) }}
-    {{ form_row(registrationForm.firstName, {'row_attr': {'class' : 'form-group d-flex flex-column m-auto mb-4 col-6'}})  }}
-    {{ form_row(registrationForm.lastName, {'row_attr': {'class' : 'form-group d-flex flex-column m-auto mb-4 col-6'}}) }}
-    {{ form_row(registrationForm.email, {'row_attr': {'class' : 'form-group d-flex flex-column m-auto mb-4 col-6'}}) }}
-    {{ form_row(registrationForm.plainPassword.first, {'row_attr': {'class' : 'form-group d-flex flex-column m-auto mb-4 col-6'}}) }}
-    {{ form_row(registrationForm.plainPassword.second, {'row_attr': {'class' : 'form-group d-flex flex-column m-auto mb-4 col-6'}}) }}
-    {{ form_row(registrationForm.captcha, {'row_attr': {'class' : 'form-group d-flex flex-column m-auto mb-5 col-6'}}) }}
+    {{ form_row(registrationForm.firstName, {'row_attr': {'class' : 'form-group d-flex flex-column m-auto mb-4 col-12 col-sm-10 col-md-9 col-lg-8 col-xl-7 col-xxl-5'}})  }}
+    {{ form_row(registrationForm.lastName, {'row_attr': {'class' : 'form-group d-flex flex-column m-auto mb-4 col-12 col-sm-10 col-md-9 col-lg-8 col-xl-7 col-xxl-5'}}) }}
+    {{ form_row(registrationForm.email, {'row_attr': {'class' : 'form-group d-flex flex-column m-auto mb-4 col-12 col-sm-10 col-md-9 col-lg-8 col-xl-7 col-xxl-5'}}) }}
+    {{ form_row(registrationForm.plainPassword.first, {'row_attr': {'class' : 'form-group d-flex flex-column m-auto mb-4 col-12 col-sm-10 col-md-9 col-lg-8 col-xl-7 col-xxl-5'}}) }}
+    {{ form_row(registrationForm.plainPassword.second, {'row_attr': {'class' : 'form-group d-flex flex-column m-auto mb-4 col-12 col-sm-10 col-md-9 col-lg-8 col-xl-7 col-xxl-5'}}) }}
+    {{ form_row(registrationForm.captcha, {'row_attr': {'class' : 'form-group d-flex flex-column m-auto mb-5 col-12 col-sm-10 col-md-9 col-lg-8 col-xl-7 col-xxl-5'}}) }}
     {{ form_row(registrationForm.agreeTerms, {'row_attr': {'class' : 'form-group d-flex flex-column m-auto mb-4 col-auto justify-content-center'}, 'label_attr': { 'class' : 'ms-3'}}) }}
-    {{ form_row(registrationForm.submit, {'row_attr': {'class' : 'form-group d-flex flex-column m-auto mb-5 col-2'}}) }}
+    {{ form_row(registrationForm.submit, {'row_attr': {'class' : 'form-group d-flex flex-column m-auto mb-5'}}) }}
     {{ form_end(registrationForm) }}
   </div>
 {% endblock %}
diff --git a/templates/security/login.html.twig b/templates/security/login.html.twig
index f86f18bd8a255236519ecd33e2fce7ad5ca36e53..aff2910422d3ff81631e8d00161287fd617f286e 100644
--- a/templates/security/login.html.twig
+++ b/templates/security/login.html.twig
@@ -5,21 +5,21 @@
 {% endblock %}
 
 {% block body %}
-<form method="post" class="d-flex flex-column justify-content-center">
     {% if error %}
         <div class="alert alert-danger col-6 m-auto">{{ error.messageKey|trans(error.messageData, 'security') }}</div>
     {% endif %}
     {% for flashMessage in app.flashes('email_verified_success') %}
-      <div class="text-center alert alert-warning col-6 m-auto" role="alert" >{{ flashMessage }}</div>
+        <div class="text-center alert alert-warning col-6 m-auto" role="alert" >{{ flashMessage }}</div>
     {% endfor %}
 
-    <div class="form-group d-flex flex-column m-auto mb-4 mt-4 col-6">
+<form method="post" class="d-flex flex-column justify-content-center">
+    <div class="form-group d-flex flex-column m-auto mb-4 mt-4 col-12 col-sm-10 col-md-9 col-lg-8 col-xl-7 col-xxl-5">
         <label for="inputEmail" class="form-label">
             {{ 'general.email'|trans }}
         </label>
         <input type="email" value="{{ last_username }}" name="email" id="inputEmail" class="form-control" autocomplete="email" required autofocus>
     </div>
-    <div class="form-group d-flex flex-column m-auto mb-4 col-6">
+    <div class="form-group d-flex flex-column m-auto mb-4 col-12 col-sm-10 col-md-9 col-lg-8 col-xl-7 col-xxl-5">
         <label for="inputPassword" class="form-label">
             {{ 'general.password'|trans }}
         </label>
@@ -45,7 +45,7 @@
         {{ 'login.forgot_password_link'|trans }}
     </a>
 
-    <button class="btn btn-primary col-2 m-auto mt-4" type="submit">
+    <button class="btn btn-primary m-auto mt-4" type="submit">
         {{ 'login.log_in'|trans }}
     </button>
 </form>
diff --git a/tests/functional/CapsuleControllerTest.php b/tests/functional/CapsuleControllerTest.php
index 829b95310ee6c89478e601472e62bacc31dfbe87..96c813689e90cac2d62731df13d7defe7f4e2ce2 100644
--- a/tests/functional/CapsuleControllerTest.php
+++ b/tests/functional/CapsuleControllerTest.php
@@ -106,8 +106,6 @@ class CapsuleControllerTest extends WebTestCase
         $client = static::createClient();
         $client->loginUser($this->verified_user);
 
-
-
         $client->request('GET', '/capsule/preview/' . $this->created_capsule->getLinkPath());
         $this->assertResponseIsSuccessful('The preview should be allowed for none authenticated user');
     }
@@ -128,8 +126,11 @@ class CapsuleControllerTest extends WebTestCase
         $client = static::createClient();
 
         $client->request('GET', '/capsule/edit/' . $this->created_capsule->getLinkPath());
-        $this->assertResponseRedirects('/login', 302, 'An unauthenticated user '
-            . 'should no access to capsule edition and should be redirected to the login page');
+        $this->assertResponseRedirects(
+            '/login',
+            302,
+            'An unauthenticated user should no access to capsule edition and should be redirected to the login page'
+        );
     }
 
     public function testLoggedUserShouldAccessToItsCapsuleEdition(): void
@@ -138,7 +139,8 @@ class CapsuleControllerTest extends WebTestCase
         $client->loginUser($this->verified_user);
 
         $client->request('GET', '/capsule/edit/' . $this->created_capsule->getLinkPath());
-        $this->assertResponseIsSuccessful('An authenticated user should be able to access to the edition of its '
-            . ' capsules');
+        $this->assertResponseIsSuccessful(
+            'An authenticated user should be able to access to the edition of its capsules'
+        );
     }
 }
diff --git a/tests/functional/CapsuleEditorControllerTest.php b/tests/functional/CapsuleEditorControllerTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..2be2f65302c2b9a781fe24ccd080fe31dbc97f08
--- /dev/null
+++ b/tests/functional/CapsuleEditorControllerTest.php
@@ -0,0 +1,225 @@
+<?php
+
+namespace App\Tests\functional;
+
+use App\Entity\Capsule;
+use App\Entity\User;
+use App\Repository\CapsuleRepository;
+use App\Repository\UserRepository;
+use Doctrine\Persistence\ObjectManager;
+use Symfony\Bundle\FrameworkBundle\KernelBrowser;
+use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
+
+class CapsuleEditorControllerTest extends WebTestCase
+{
+    private KernelBrowser $client;
+    private ObjectManager $object_manager;
+    private User $user_author;
+    private User $editor_non_author;
+    private UserRepository $user_repository; /** @phpstan-ignore-line */
+    private CapsuleRepository $capsule_repository; /** @phpstan-ignore-line */
+    private Capsule $capsule;
+
+    protected function setUp(): void
+    {
+        self::ensureKernelShutdown();
+
+        $this->client = static::createClient();
+
+        $this->object_manager = $this->client->getContainer()
+            ->get('doctrine')
+            ->getManager();
+
+
+        $this->user_repository = $this->object_manager->getRepository(User::class);
+        $this->capsule_repository = $this->object_manager->getRepository(Capsule::class);
+
+        $this->setUsers();
+        $this->setCapsule();
+    }
+
+    protected function tearDown(): void
+    {
+        parent::tearDown();
+        self::ensureKernelShutdown();
+    }
+
+    public function testAuthorShouldBeAbleToDeleteACapsule(): void
+    {
+        $this->client->loginUser($this->user_author);
+        $this->client->request('GET', '/capsule/delete/' . $this->capsule->getId());
+
+        $this->assertResponseIsSuccessful();
+    }
+
+    public function testEditorNonAuthorShouldNotBeAbleToDeleteACapsule(): void
+    {
+        $this->client->loginUser($this->editor_non_author);
+        $this->client->request('GET', '/capsule/delete/' . $this->capsule->getId());
+
+        $this->assertResponseRedirects('/my_capsules', 302);
+    }
+
+    public function testAuthorShouldBeAbleToAddANewEditorForACapsule(): void
+    {
+        $uri = '/capsule/' . $this->capsule->getId() . '/editors';
+        $this->client->loginUser($this->user_author);
+        $crawler = $this->client->request('GET', $uri);
+
+        $this->assertResponseIsSuccessful();
+
+        $this->client->enableProfiler();
+        $submit_button = $crawler->selectButton('Validate');
+        $form = $submit_button->form();
+        $form['capsule_editors_form[email]'] = $this->editor_non_author->getEmail();
+        $this->client->submit($form);
+
+        $this->assertResponseRedirects($uri, 302);
+        $this->client->followRedirect();
+        $this->assertResponseIsSuccessful($uri);
+
+        $capsule_refreshed = $this->capsule_repository->findOneBy(['id' => $this->capsule->getId()]);
+        if (! $capsule_refreshed instanceof Capsule) {
+            throw new \Exception("Capsule does not exist.");
+        }
+
+        $editor = $this->user_repository->findOneBy(['id' => $this->editor_non_author->getId()]);
+        $this->assertSame($editor, $capsule_refreshed->getEditors()->last());
+    }
+
+    public function testEditorShouldBeAbleToAccessTheCapsuleEditorsPage(): void
+    {
+        $this->capsule->addEditor($this->editor_non_author);
+        $uri = '/capsule/' . $this->capsule->getId() . '/editors';
+        $this->client->loginUser($this->editor_non_author);
+
+        $this->client->request('GET', $uri);
+
+        $this->assertResponseIsSuccessful();
+    }
+
+    public function testNonRegisteredUserAddedAsEditorShouldReceiveAnEmail(): void
+    {
+        $uri = '/capsule/' . $this->capsule->getId() . '/editors';
+        $this->client->loginUser($this->user_author);
+        $crawler = $this->client->request('GET', $uri);
+
+        $this->assertResponseIsSuccessful();
+
+        $this->client->enableProfiler();
+        $submit_button = $crawler->selectButton('Validate');
+        $non_registered_user_email = "non_registered_user@email.fr";
+        $form = $submit_button->form();
+        $form['capsule_editors_form[email]'] = $non_registered_user_email;
+        $this->client->submit($form);
+
+        $this->assertResponseRedirects($uri, 302);
+
+        $this->assertEmailCount(1);
+        $emailMessage = $this->getMailerMessage(0);
+
+        if (null === $emailMessage) {
+            throw new \Exception("Email message could not be found");
+        }
+
+        $this->assertEmailAddressContains(
+            $emailMessage,
+            'To',
+            $non_registered_user_email
+        );
+
+        $this->client->followRedirect();
+        $this->assertResponseIsSuccessful($uri);
+    }
+
+    public function testRegisteredUserShouldReceiveAnEmailWithCapsuleEditionLink(): void
+    {
+        $uri = '/capsule/' . $this->capsule->getId() . '/editors';
+        $this->client->loginUser($this->user_author);
+        $crawler = $this->client->request('GET', $uri);
+
+        $this->assertResponseIsSuccessful();
+
+        $this->client->enableProfiler();
+        $submit_button = $crawler->selectButton('Validate');
+        $form = $submit_button->form();
+        $form['capsule_editors_form[email]'] = $this->editor_non_author->getEmail();
+        $this->client->submit($form);
+
+        $this->assertResponseRedirects($uri, 302);
+
+        $this->assertEmailCount(1);
+        $emailMessage = $this->getMailerMessage(0);
+
+        if (null === $emailMessage) {
+            throw new \Exception("Email message could not be found");
+        }
+
+        $this->assertEmailAddressContains(
+            $emailMessage,
+            'To',
+            $this->editor_non_author->getEmail()
+        );
+
+        $this->client->followRedirect();
+        $this->assertResponseIsSuccessful($uri);
+    }
+
+    public function testAlreadyAddedEditorShouldNotReceiveAnEmail(): void
+    {
+        $this->capsule->addEditor($this->editor_non_author);
+        $this->object_manager->persist($this->capsule);
+        $this->object_manager->flush();
+
+        $this->assertContains($this->editor_non_author, $this->capsule->getEditors()->toArray());
+        $uri = '/capsule/' . $this->capsule->getId() . '/editors';
+        $this->client->loginUser($this->user_author);
+        $crawler = $this->client->request('GET', $uri);
+
+        $this->assertResponseIsSuccessful();
+
+        $this->client->enableProfiler();
+        $submit_button = $crawler->selectButton('Validate');
+        $form = $submit_button->form();
+        $form['capsule_editors_form[email]'] = $this->editor_non_author->getEmail();
+        $this->client->submit($form);
+
+        $this->assertEmailCount(0);
+        $this->assertResponseRedirects($uri, 302);
+
+        $this->client->followRedirect();
+        $this->assertResponseIsSuccessful($uri);
+    }
+
+    private function setUsers(): void
+    {
+        $verified_user_1 = $this->user_repository
+            ->findOneBy(['email' => 'defaultUser@localhost.com']);
+
+        if (! $verified_user_1 instanceof User) {
+            throw new \Exception("User does not exist.");
+        }
+
+        $this->user_author = $verified_user_1;
+
+        $verified_user_2 = $this->user_repository
+            ->findOneBy(['email' => 'defaultUser2@localhost.com']);
+
+        if (! $verified_user_2 instanceof User) {
+            throw new \Exception("User does not exist.");
+        }
+
+        $this->editor_non_author = $verified_user_2;
+    }
+
+    private function setCapsule(): void
+    {
+        $capsule = $this->capsule_repository->findOneBy(['name' => 'Pomme']);
+
+        if (! $capsule instanceof Capsule) {
+            throw new \Exception("Capsule does not exist.");
+        }
+
+        $this->capsule = $capsule;
+    }
+}
diff --git a/translations/messages.en.yaml b/translations/messages.en.yaml
index b6e3029b3d13c41d03059eed90d7f7ca774c477f..7e70101b17d492bd2f9a35ec93529ef8a64f811c 100644
--- a/translations/messages.en.yaml
+++ b/translations/messages.en.yaml
@@ -62,13 +62,14 @@ capsule:
   video_url: Youtube or Vimeo video URL
   created_success: Capsule capsule_name was created successfully
   no_edition_access: No edition access
-  edition_not_allowed: You are not allowed to edit this capsule
   contact_capsule_author_for_access: Please contact the author to gain access the edition mode
   not_found: The project doesn't exist
   edit_permissions:
     link: Edit permissions
   edit:
     link: Edit capsule
+    not_allowed: You are not allowed to edit this capsule
+    not_found: The capsule was not found
   duplicate:
     link: Duplicate capsule
     title: Duplicate capsule
@@ -106,4 +107,32 @@ user:
     change_password: Change password
     updated_success: The password has been updated
   edit_profile: Edit my profile
-  edit_password: Edit my password
\ No newline at end of file
+  edit_password: Edit my password
+
+editors:
+    title: Editors
+    title_name: Editors of capsule %capsule_name%
+    add_email_address: Add new editor with email address
+    current_editors_title: Current editors
+    pending_editors_title: Pending editors
+    user_not_editor_error: You are not editor of the capsule
+    add:
+      pending_editor:
+        success: The user user_email has been added to pending editor list.
+          He will receive an email to invite him register on MemoRekall and to inform him he has been added as an editor of this capsule.
+        already_added: The user user_email has already been added to pending editor list
+        email:
+          title: Invitation to edit a MemoRekall capsule
+          text: You have been added by %user_name% as editor of the capsule "%capsule_name%".
+            In order to access and edit it, you first need to register on MemoRekall. Please follow this link to
+          link: https://project.memorekall.com/register/
+          link_name: register
+      user:
+        success: The user user_email is now an editor of the capsule capsule_name.
+          He will receive an email to inform him he has been added as an editor of this capsule.
+        already_added: The user user_email is already an editor of this capsule
+        email:
+          title: New capsule on your list
+          text: You have been add by %user_name% as editor of the capsule "%capsule_name%".
+            You can now access and edit it. You will find the capsule in your capsule list.
+          link: Go to capsule edition page
diff --git a/translations/messages.fr.yaml b/translations/messages.fr.yaml
index 9fff9516c6726f3625dc8882cd317b063f54b269..3745a308579bd51b55da0808b7aa80e92e1c7468 100644
--- a/translations/messages.fr.yaml
+++ b/translations/messages.fr.yaml
@@ -60,12 +60,13 @@ capsule:
   video_url: URL de la video Youtube ou Vimeo
   created_success: La capsule capsule_name a été créée
   no_edition_access: Pas d'accès au mode édition
-  edition_not_allowed: Vous n'êtes pas autorisé a modifier cette capsule
   contact_capsule_author_for_access: Veuillez contacter l'auteur de la capsule pour lui demander son accès en mode édition
   edit_permissions:
     link: Modifier les permissions
   edit:
     link: Modifier la capsule
+    not_allowed: Vous n'êtes pas autorisé a modifier cette capsule
+    not_found: La capsule n'existe pas
   duplicate:
     link: Dupliquer la capsule
     title: Dupliquer la capsule
@@ -104,4 +105,32 @@ user:
     change_password: Changer mon mot de passe
     updated_success: Votre mot de passe a bien été modifié
   edit_profile: Modifier mon mot de passe
-  edit_password: Modifier mon mot de passe
\ No newline at end of file
+  edit_password: Modifier mon mot de passe
+
+editors:
+    title: Editeurs d'une capsule
+    title_name: Editeurs de la capsule %capsule_name%
+    add_email_address: Ajouter un nouvel editeur avec son adresse e-mail
+    current_editors_title: Editeurs actuels
+    pending_editors_title: Editeurs en attente de confirmation
+    user_not_editor_error: Vous n'êtes pas éditeur de la capsule
+    add:
+      pending_editor:
+        success: L'utilisateur user_email a bien été ajouté à la liste des editeurs en attente
+          Il recevera un e-mail l'invitant à créer un compte MemoRekall et l'informant qu'il a été ajouté en tant qu'éditeur de la capsule.
+        already_added: L'utilisateur user_email a déjà été ajouté à la liste des éditeurs en attente
+        email:
+          title: Invitation pour éditer une capsule sur MemoRekall
+          text: Vous avez été ajouté par %user_name% en tant qu'éditeur de la capsule %capsule_name%.
+            Avant de pouvoir y accéder et la modifier, vous devez d'abord créer un compte sur MemoRekall. Veuillez suivre ce lien pour
+          link: https://project.memorekall.com/register/
+          link_name: créer votre compte
+      user:
+        success: L'utilisateur user_email est maintenant éditeur de la capsule capsule_name.
+          Il recevera un e-mail l'informant qu'il a été ajouté en tant qu'éditeur de la capsule.
+        already_added: L'utilisateur user_email est déjà editeur de la capsule
+        email:
+          title: Nouvelle capsule dans votre liste
+          text: Vous avez été ajouté par %user_name% en tant qu'éditeur de la capsule "%capsule_name%".
+            Vous pouvez maintenant y accéder et l'éditer. Vous la retrouverez dans la liste de vos capsules.
+          link: Se rendre sur la page d'édition de la capsule
\ No newline at end of file