diff --git a/migrations/Version20220307154836.php b/migrations/Version20220307154836.php
new file mode 100644
index 0000000000000000000000000000000000000000..ac675b329b4a4552cf34075703db1bc7e089494e
--- /dev/null
+++ b/migrations/Version20220307154836.php
@@ -0,0 +1,37 @@
+<?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 Version20220307154836 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 `pending_email_address` (id INT AUTO_INCREMENT NOT NULL, user INT NOT NULL, email VARCHAR(255) NOT NULL, INDEX IDX_621FD0118D93D649 (user), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE `utf8_unicode_ci` ENGINE = InnoDB');
+        $this->addSql('ALTER TABLE `pending_email_address` ADD CONSTRAINT FK_621FD0118D93D649 FOREIGN KEY (user) REFERENCES `user` (id)');
+    }
+
+    public function down(Schema $schema): void
+    {
+        // this down() migration is auto-generated, please modify it to your needs
+        $this->addSql('DROP TABLE `pending_email_address`');
+        $this->addSql('ALTER TABLE capsule CHANGE nom nom VARCHAR(255) NOT NULL COLLATE `utf8_unicode_ci`, CHANGE link link VARCHAR(255) NOT NULL COLLATE `utf8_unicode_ci`, CHANGE edition_link edition_link VARCHAR(255) NOT NULL COLLATE `utf8_unicode_ci`, CHANGE password password VARCHAR(50) NOT NULL COLLATE `utf8_unicode_ci`');
+        $this->addSql('ALTER TABLE `group` CHANGE name name VARCHAR(255) NOT NULL COLLATE `utf8_unicode_ci`');
+        $this->addSql('ALTER TABLE invitation_editeur_capsule CHANGE email email VARCHAR(255) NOT NULL COLLATE `utf8_unicode_ci`');
+        $this->addSql('ALTER TABLE reset_password_request CHANGE selector selector VARCHAR(20) NOT NULL COLLATE `utf8_unicode_ci`, CHANGE hashed_token hashed_token VARCHAR(100) NOT NULL COLLATE `utf8_unicode_ci`');
+        $this->addSql('ALTER TABLE `user` CHANGE email email VARCHAR(255) NOT NULL COLLATE `utf8_unicode_ci`, CHANGE email_canonical email_canonical VARCHAR(255) NOT NULL COLLATE `utf8_unicode_ci`, CHANGE name name VARCHAR(255) NOT NULL COLLATE `utf8_unicode_ci`, CHANGE firstname firstname VARCHAR(255) NOT NULL COLLATE `utf8_unicode_ci`, CHANGE username username VARCHAR(255) NOT NULL COLLATE `utf8_unicode_ci`, CHANGE username_canonical username_canonical VARCHAR(255) NOT NULL COLLATE `utf8_unicode_ci`, CHANGE roles roles LONGTEXT NOT NULL COLLATE `utf8_unicode_ci` COMMENT \'(DC2Type:json)\', CHANGE password password VARCHAR(255) NOT NULL COLLATE `utf8_unicode_ci`, CHANGE salt salt VARCHAR(255) NOT NULL COLLATE `utf8_unicode_ci`');
+    }
+}
diff --git a/src/Controller/CapsuleEditorController.php b/src/Controller/CapsuleEditorController.php
index 6b08bbcbecb0eaa7f098600e2e17fa56a4f86750..0cc7c3de8b75de491138d3b38e1fcf4252f17827 100755
--- a/src/Controller/CapsuleEditorController.php
+++ b/src/Controller/CapsuleEditorController.php
@@ -278,9 +278,6 @@ class CapsuleEditorController extends AbstractController
         int $capsule_id,
         Request $request
     ): Response {
-        $form = $this->createForm(RemoveEditorFormType::class);
-        $form->handleRequest($request);
-
         $capsule = $this->capsule_repository->findOneBy(['id' => $capsule_id]);
         if (! $capsule instanceof Capsule) {
             throw new \Exception('The retrieved capsule is not an instance of Capsule.');
@@ -289,6 +286,9 @@ class CapsuleEditorController extends AbstractController
         $pending_editor_invitation = $this->capsule_pending_editor_invitation_repository
                                             ->findOneBy(['id' => $pending_editor_invitation_id]);
 
+        $form = $this->createForm(RemoveEditorFormType::class);
+        $form->handleRequest($request);
+
         if (! $pending_editor_invitation instanceof PendingEditorInvitation) {
             $this->addFlash(
                 'warning',
diff --git a/src/Controller/RegistrationController.php b/src/Controller/RegistrationController.php
index 4155bb7e618a1911940add7a8a17a066a05719f8..e6410636e992e254eae341243c741209ad1e4129 100755
--- a/src/Controller/RegistrationController.php
+++ b/src/Controller/RegistrationController.php
@@ -69,7 +69,7 @@ class RegistrationController extends AbstractController
         }
 
         return $this->renderForm('registration/register.html.twig', [
-            'registrationForm' => $form,
+            'registrationForm' => $form
         ]);
     }
 
@@ -92,7 +92,7 @@ class RegistrationController extends AbstractController
         try {
             $this->email_verifier->handleEmailConfirmation($request, $user);
         } catch (VerifyEmailExceptionInterface $exception) {
-            $this->addFlash('verify_email_error', $exception->getReason());
+            $this->addFlash('error', $exception->getReason());
 
             return $this->redirectToRoute('app_register');
         }
diff --git a/src/Controller/ResetPasswordController.php b/src/Controller/ResetPasswordController.php
index 7169714865de8548846371b272e0a61d08617644..a58c51a80a2cbf43725301164807baafaf8b95ef 100755
--- a/src/Controller/ResetPasswordController.php
+++ b/src/Controller/ResetPasswordController.php
@@ -43,7 +43,7 @@ class ResetPasswordController extends AbstractController
         }
 
         return $this->renderForm('reset_password/request.html.twig', [
-            'requestForm' => $form,
+            'requestForm' => $form
         ]);
     }
 
@@ -118,7 +118,7 @@ class ResetPasswordController extends AbstractController
         }
 
         return $this->renderForm('reset_password/reset.html.twig', [
-            'resetForm' => $form,
+            'resetForm' => $form
         ]);
     }
 
diff --git a/src/Controller/UserController.php b/src/Controller/UserController.php
index 52c454c658b8d020c01beba889593f520518ba45..89f7ecae410d7d489d8749a1800b67f471fa688b 100755
--- a/src/Controller/UserController.php
+++ b/src/Controller/UserController.php
@@ -2,13 +2,18 @@
 
 namespace App\Controller;
 
+use App\Entity\PendingEmailAddress;
 use App\Entity\User;
 use App\Form\EditPasswordFormType;
 use App\Form\EditUserProfileFormType;
+use App\Repository\PendingEmailAddressRepository;
 use Doctrine\ORM\EntityManagerInterface;
+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\MailerInterface;
+use Symfony\Component\Mime\Address;
 use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
 use Symfony\Component\Routing\Annotation\Route;
 use Symfony\Contracts\Translation\TranslatorInterface;
@@ -17,7 +22,8 @@ class UserController extends AbstractController
 {
     public function __construct(
         private EntityManagerInterface $entity_manager,
-        private TranslatorInterface $translator
+        private TranslatorInterface $translator,
+        private PendingEmailAddressRepository $pending_email_address_repository
     ) {
     }
 
@@ -36,26 +42,65 @@ class UserController extends AbstractController
     }
 
     #[Route('/edit_profile', name:'edit_profile')]
-    public function editProfile(Request $request): Response
-    {
+    public function editProfile(
+        Request $request,
+        MailerInterface $mailer
+    ): Response {
         $current_user = $this->getUser();
 
         if (! $current_user instanceof User) {
             return $this->redirectToRoute('app_logout');
         }
 
-        $form = $this->createForm(EditUserProfileFormType::class, $current_user);
+        $last_pending_email_address = $this->pending_email_address_repository->findOneBy(
+            ['user' => $current_user->getId()]
+        );
+        if ($last_pending_email_address !== null) {
+            $this->entity_manager->remove($last_pending_email_address);
+        }
 
-        $form->setData($current_user);
+        $form = $this->createForm(
+            EditUserProfileFormType::class,
+            $current_user,
+            ['current_email_address' => $current_user->getEmail()]
+        );
         $form->handleRequest($request);
 
         if ($form->isSubmitted() && $form->isValid()) {
+            if ($current_user->getEmail() !== $form->get('email')->getData()) {
+                $pending_email_address = new PendingEmailAddress();
+                $pending_email_address->setEmail($form->get('email')->getData());
+                $pending_email_address->setUser($current_user);
+                $this->entity_manager->persist($pending_email_address);
+                $this->entity_manager->flush();
+
+                $email = (new TemplatedEmail())
+                    ->to(new Address($pending_email_address->getEmail()))
+                    ->subject($this->translator->trans('user.edit.email.title'))
+                    ->htmlTemplate('user/update_email.html.twig')
+                    ->context([
+                        'expiration_date' => new \DateTime('+1 day')
+                    ]);
+                $mailer->send($email);
+
+                $this->addFlash(
+                    'warning',
+                    $this->translator->trans('user.profile.updated.warning', [
+                        'new_email_address' => $form->get('email')->getData()
+                    ])
+                );
+
+                return $this->render('user/edit_email_address.html.twig', [
+                    'new_email_address' => $form->get('email')->getData()
+                ]);
+            }
+
             $this->entity_manager->persist($current_user);
             $this->entity_manager->flush();
 
             $this->addFlash(
-                'profile_updated_success',
-                $this->translator->trans('user.profile.updated_success')
+                'success',
+                $this->translator->trans('user.profile.updated.success')
             );
 
             return $this->redirectToRoute('show_profile');
@@ -69,7 +114,7 @@ class UserController extends AbstractController
     #[Route('/edit_password', name:'edit_password')]
     public function editPassword(
         Request $request,
-        UserPasswordHasherInterface $user_password_hasher,
+        UserPasswordHasherInterface $user_password_hasher
     ): Response {
         $form = $this->createForm(EditPasswordFormType::class);
         $form->handleRequest($request);
@@ -98,4 +143,33 @@ class UserController extends AbstractController
             'editPasswordForm' => $form
         ]);
     }
+
+    #[Route('/edit/email', name:'verify_new_email_address')]
+    public function verifyNewEmailAddress(): Response
+    {
+        $current_user = $this->getUser();
+        if (! $current_user instanceof User) {
+            return $this->redirectToRoute('app_logout');
+        }
+
+        $pending_email_address = $this->pending_email_address_repository->findOneBy(['user' => $current_user->getId()]);
+        if (! $pending_email_address instanceof PendingEmailAddress) {
+            throw new \Exception('Pending email address not found');
+        }
+
+        $current_user->setEmail($pending_email_address->getEmail());
+        $this->entity_manager->persist($current_user);
+        $this->entity_manager->remove($pending_email_address);
+        $this->entity_manager->flush();
+
+        $this->addFlash(
+            'success',
+            $this->translator->trans(
+                'user.edit.email.success',
+                ['new_email_address' => $pending_email_address->getEmail()]
+            )
+        );
+
+        return $this->redirectToRoute('show_profile');
+    }
 }
diff --git a/src/Entity/PendingEmailAddress.php b/src/Entity/PendingEmailAddress.php
new file mode 100644
index 0000000000000000000000000000000000000000..3a29a2209c9673880354bf20bd5f39b00c5d19cd
--- /dev/null
+++ b/src/Entity/PendingEmailAddress.php
@@ -0,0 +1,47 @@
+<?php
+
+namespace App\Entity;
+
+use App\Repository\PendingEmailAddressRepository;
+use Doctrine\ORM\Mapping as ORM;
+use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
+use Symfony\Component\Validator\Constraints as Assert;
+
+#[ORM\Entity(repositoryClass:PendingEmailAddressRepository::class)]
+#[ORM\Table(name:'`pending_email_address`')]
+#[UniqueEntity(fields: ['user', 'email'], message: 'pending_email_address.email.unique', errorPath: 'email')]
+class PendingEmailAddress
+{
+    #[ORM\Id]
+    #[ORM\GeneratedValue]
+    #[ORM\Column(type:'integer')]
+    private int $id;
+
+    #[ORM\ManyToOne(targetEntity:User::class)]
+    #[ORM\JoinColumn(name:'user', referencedColumnName:'id', nullable:false)]
+    private User $user;
+
+    #[Assert\Email(message: 'email.valid')]
+    #[ORM\Column(type:'string', length:255)]
+    private string $email;
+
+    public function getUser(): User
+    {
+        return $this->user;
+    }
+
+    public function setUser(User $user): void
+    {
+        $this->user = $user;
+    }
+
+    public function getEmail(): string
+    {
+        return $this->email;
+    }
+
+    public function setEmail(string $email): void
+    {
+        $this->email = $email;
+    }
+}
diff --git a/src/Form/EditUserProfileFormType.php b/src/Form/EditUserProfileFormType.php
index 637d12bdd87d4175bb1358b739fa0e6b51b0ec18..a13cd5b8a7d2d3cb5cd1f9b8d67ad0251d08b3f2 100755
--- a/src/Form/EditUserProfileFormType.php
+++ b/src/Form/EditUserProfileFormType.php
@@ -3,6 +3,8 @@
 namespace App\Form;
 
 use App\Entity\User;
+use App\Repository\PendingEmailAddressRepository;
+use App\Repository\UserRepository;
 use Symfony\Component\Form\AbstractType;
 use Symfony\Component\Form\Extension\Core\Type\EmailType;
 use Symfony\Component\Form\Extension\Core\Type\PasswordType;
@@ -12,11 +14,27 @@ use Symfony\Component\Form\FormBuilderInterface;
 use Symfony\Component\OptionsResolver\OptionsResolver;
 use Symfony\Component\Security\Core\Validator\Constraints\UserPassword;
 use Symfony\Component\Validator\Constraints\NotBlank;
+use Symfony\Component\Validator\Constraints as Assert;
+use Symfony\Component\Validator\Context\ExecutionContextInterface;
 
 class EditUserProfileFormType extends AbstractType
 {
+    private UserRepository $user_repository;
+    private PendingEmailAddressRepository $pending_email_address_repository;
+
+    public function __construct(
+        UserRepository $user_repository,
+        PendingEmailAddressRepository $pending_email_address_repository
+    ) {
+        $this->user_repository = $user_repository;
+        $this->pending_email_address_repository = $pending_email_address_repository;
+    }
+
     public function buildForm(FormBuilderInterface $builder, array $options): void
     {
+        $user_repository = $this->user_repository;
+        $pending_email_address_repository = $this->pending_email_address_repository;
+
         $builder
             ->add(
                 'firstName',
@@ -40,9 +58,36 @@ class EditUserProfileFormType extends AbstractType
                 'email',
                 EmailType::class,
                 [
-                    'constraints' => [new NotBlank(['message' => 'email.not_blank'])],
+                    'data' => $options['current_email_address'],
+                    'constraints' => [
+                        new NotBlank(['message' => 'email.not_blank']),
+                        new Assert\Email(),
+                        new Assert\Callback(
+                            ['callback' => static function (
+                                string $value,
+                                ExecutionContextInterface $context
+                            ) use (
+                                $options,
+                                $user_repository,
+                                $pending_email_address_repository
+                            ) {
+                                if (
+                                    $value !== $options['current_email_address'] &&
+                                    ($user_repository->emailExists($value) ||
+                                        $pending_email_address_repository->emailIsReserved($value))
+                                ) {
+                                    $context
+                                        ->buildViolation(message: 'user.email.unique')
+                                        ->addViolation()
+                                    ;
+                                }
+                            }
+                            ]
+                        )
+                    ],
                     'label' => 'general.email',
-                    'empty_data' => ''
+                    'empty_data' => '',
+                    'mapped' => false
                 ]
             )
             ->add(
@@ -70,6 +115,9 @@ class EditUserProfileFormType extends AbstractType
     {
         $resolver->setDefaults([
             'data_class' => User::class,
-        ]);
+            'current_email_address' => '',
+            'users_emails' => [],
+            'pending_emails' => []
+            ]);
     }
 }
diff --git a/src/Repository/PendingEmailAddressRepository.php b/src/Repository/PendingEmailAddressRepository.php
new file mode 100644
index 0000000000000000000000000000000000000000..19e82ea794616a42fd03cd84b55c4de1a7b5d63a
--- /dev/null
+++ b/src/Repository/PendingEmailAddressRepository.php
@@ -0,0 +1,42 @@
+<?php
+
+namespace App\Repository;
+
+use App\Entity\PendingEmailAddress;
+use App\Entity\User;
+use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
+use Doctrine\Persistence\ManagerRegistry;
+
+/**
+ * @method PendingEmailAddress|null find($id, $lockMode = null, $lockVersion = null)
+ * @method PendingEmailAddress|null findOneBy(array $criteria, array $orderBy = null)
+ * @method PendingEmailAddress[]    findAll()
+ * @method PendingEmailAddress[]    findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
+ * @template PendingEmailAddress of object
+ */
+class PendingEmailAddressRepository extends ServiceEntityRepository
+{
+    public function __construct(ManagerRegistry $registry)
+    {
+        parent::__construct($registry, PendingEmailAddress::class);
+    }
+
+    public function findOneByEmail(string $value): ?User
+    {
+        return $this->createQueryBuilder('u')
+            ->andWhere('u.email = :val')
+            ->setParameter('val', $value)
+            ->getQuery()
+            ->getOneOrNullResult()
+            ;
+    }
+
+    public function emailIsReserved(string $email): bool
+    {
+        return $this->createQueryBuilder('p')
+                ->andWhere('p.email = :email')
+                ->setParameter('email', $email)
+                ->getQuery()
+                ->getOneOrNullResult() !== null;
+    }
+}
diff --git a/src/Repository/UserRepository.php b/src/Repository/UserRepository.php
index 147f8c5c26d5ab001ea4d65733de9cf19b9aebd3..8996ca410a19256346f161694cafce5067b65d3e 100755
--- a/src/Repository/UserRepository.php
+++ b/src/Repository/UserRepository.php
@@ -4,8 +4,6 @@ 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;
@@ -72,4 +70,13 @@ class UserRepository extends ServiceEntityRepository implements PasswordUpgrader
             ->getQuery()
             ->getResult();
     }
+
+    public function emailExists(string $email): bool
+    {
+        return $this->createQueryBuilder('r')
+                ->andWhere('r.email = :email')
+                ->setParameter('email', $email)
+                ->getQuery()
+                ->getOneOrNullResult() !== null;
+    }
 }
diff --git a/src/Security/EmailVerifier.php b/src/Security/EmailVerifier.php
index ea4389fcac727b3d0ffa02f431f47845f93c0382..aa910c7e1edf292eca79ed7463cdc9ff38ea9379 100755
--- a/src/Security/EmailVerifier.php
+++ b/src/Security/EmailVerifier.php
@@ -27,13 +27,13 @@ class EmailVerifier
     }
 
     public function sendEmailConfirmation(
-        string $verifyEmailRouteName,
+        string $verify_email_route_name,
         int $user_id,
         string $email_address,
         TemplatedEmail $email
     ): void {
         $signatureComponents = $this->verifyEmailHelper->generateSignature(
-            $verifyEmailRouteName,
+            $verify_email_route_name,
             (string) $user_id,
             $email_address,
             ['id' => $user_id]
diff --git a/templates/capsule/editors/list_editors.html.twig b/templates/capsule/editors/list_editors.html.twig
index 4a04b8997e0c998d9bb57eb18d6e6baf8c91c020..0b71139fb3a355c7088c6e6ea959357c2dc45914 100644
--- a/templates/capsule/editors/list_editors.html.twig
+++ b/templates/capsule/editors/list_editors.html.twig
@@ -18,13 +18,13 @@
         </div>
 
         {% for flashWarning in app.flashes('warning') %}
-            <div class="text-center alert alert-warning col-5 mx-auto my-5 mt-2" role="alert">
+            <div class="text-center alert alert-warning col-11 col-md-10 col-lg-9 col-xl-8 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">
+            <div class="text-center alert alert-success col-11 col-md-10 col-lg-9 col-xl-8 mx-auto my-5 mt-2" role="alert">
                 {{ flashSuccess }}
             </div>
         {% endfor %}
diff --git a/templates/capsule/groups/capsule_groups.html.twig b/templates/capsule/groups/capsule_groups.html.twig
index 5129485dccce24ff3c8181cdfa6f98efc7461908..ad38080a086ba9178f00752cbd144c58053aef3c 100644
--- a/templates/capsule/groups/capsule_groups.html.twig
+++ b/templates/capsule/groups/capsule_groups.html.twig
@@ -18,13 +18,13 @@
         </div>
 
         {% for flashWarning in app.flashes('warning') %}
-            <div class="text-center alert alert-warning col-5 mx-auto my-5 mt-2" role="alert">
+            <div class="text-center alert alert-warning col-11 col-md-10 col-lg-9 col-xl-8 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">
+            <div class="text-center alert alert-success col-11 col-md-10 col-lg-9 col-xl-8 mx-auto my-5 mt-2" role="alert">
                 {{ flashSuccess }}
             </div>
         {% endfor %}
diff --git a/templates/capsule/groups/user_groups.html.twig b/templates/capsule/groups/user_groups.html.twig
index d0737cc1dd680adfb544ed8164cb5b06877b2922..808b416dd7f22040826f594ff249afb6cb725fb6 100644
--- a/templates/capsule/groups/user_groups.html.twig
+++ b/templates/capsule/groups/user_groups.html.twig
@@ -17,13 +17,13 @@
         </div>
 
         {% for flashWarning in app.flashes('warning') %}
-            <div class="text-center alert alert-warning col-5 mx-auto my-5 mt-2" role="alert">
+            <div class="text-center alert alert-warning col-11 col-md-10 col-lg-9 col-xl-8 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">
+            <div class="text-center alert alert-success col-11 col-md-10 col-lg-9 col-xl-8 mx-auto my-5 mt-2" role="alert">
                 {{ flashSuccess }}
             </div>
         {% endfor %}
diff --git a/templates/capsule/index.html.twig b/templates/capsule/index.html.twig
index 5c47a37681b8d7f75caa82c8f17321344afd3025..59b64dbb425eb630fd4ab7dc3bcc59b88974d6ff 100644
--- a/templates/capsule/index.html.twig
+++ b/templates/capsule/index.html.twig
@@ -34,13 +34,13 @@
     </div>
 
     {% for flashWarning in app.flashes('warning') %}
-        <div class="text-center alert alert-warning col-5 mx-auto my-5" role="alert">
+        <div class="text-center alert alert-warning col-11 col-md-10 col-lg-9 col-xl-8 mx-auto my-5" role="alert">
             {{ flashWarning }}
         </div>
     {% endfor %}
 
     {% for flashSuccess in app.flashes('success') %}
-        <div class="text-center alert alert-success col-5 mx-auto my-5" role="alert">
+        <div class="text-center alert alert-success col-11 col-md-10 col-lg-9 col-xl-8 mx-auto my-5" role="alert">
             {{ flashSuccess }}
         </div>
     {% endfor %}
diff --git a/templates/legacy/legacy.html.twig b/templates/legacy/legacy.html.twig
index 2bf7dbff33604db8efb47927cc9ace0ebe255cf6..8d4d49edc75d8e73e079d838e895ddc18c38ce1d 100644
--- a/templates/legacy/legacy.html.twig
+++ b/templates/legacy/legacy.html.twig
@@ -1,21 +1,14 @@
 {% extends 'layout.html.twig' %}
 
-
-
 {% block body %}
   
  		<iframe src="{{ url }}"
 				style="width:100%;height:100%;top:0;left:0;position:absolute"
-				{# width="1200"
-				height="600" #}
-
 				frameborder="0"
 				webkitallowfullscreen
 				mozallowfullscreen
 				allowfullscreen>
 		</iframe>
 
-
-
 {% endblock %}
 
diff --git a/templates/registration/register.html.twig b/templates/registration/register.html.twig
index 3f9b4c0bbb3a2729667eb6f563ba0a38c0c7f360..99d5864530a878b05bb61cf9f2bcee6d7bbfa18e 100644
--- a/templates/registration/register.html.twig
+++ b/templates/registration/register.html.twig
@@ -6,8 +6,10 @@
 
 {% block body %}
   <div class="mt-4">
-    {% for flashError in app.flashes('verify_email_error') %}
-      <div class="alert alert-danger col-6 mx-auto my-5 h1" role="alert">{{ flashError }}</div>
+    {% for flashError in app.flashes('error') %}
+      <div class="alert alert-danger col-11 col-md-10 col-lg-9 col-xl-8 mx-auto my-5 h1" role="alert">
+          {{ flashError }}
+      </div>
     {% endfor %}
 
     {{ form_start(registrationForm, {'attr': {novalidate: 'novalidate', 'class': 'd-flex flex-column justify-content-center'}}) }}
diff --git a/templates/user/edit_email_address.html.twig b/templates/user/edit_email_address.html.twig
new file mode 100644
index 0000000000000000000000000000000000000000..a3017afedbc6e31f977ba10c7500e4d93edf7f7c
--- /dev/null
+++ b/templates/user/edit_email_address.html.twig
@@ -0,0 +1,21 @@
+{% extends 'layout.html.twig' %}
+
+{% block title %}
+    {{ 'user.edit_email_address'|trans }}
+{% endblock %}
+
+{% block body %}
+    <div class="row gx-0">
+        <div class="row-title-box">
+            <h3 class="row-title">
+                {{ 'user.edit_email_address'|trans }}
+            </h3>
+        </div>
+    </div>
+
+    {% for flashWarning in app.flashes('warning') %}
+        <div class="text-center alert alert-warning col-11 col-md-10 col-lg-9 col-xl-8 mx-auto my-5" role="alert">
+            {{ flashWarning }}
+        </div>
+    {% endfor %}
+{% endblock %}
\ No newline at end of file
diff --git a/templates/user/edit_profile.html.twig b/templates/user/edit_profile.html.twig
index 57a83762c698e8447599f715fe2c8edc904b1fc3..d916e3c64bb9c12a9afb2e11de4498a47ebdf755 100644
--- a/templates/user/edit_profile.html.twig
+++ b/templates/user/edit_profile.html.twig
@@ -23,5 +23,4 @@
         {{ form_row(editUserProfileForm.update, {'row_attr': {'class' : 'form-group d-flex flex-column m-auto mb-4 col-2'}}) }}
         {{ form_end(editUserProfileForm) }}
     </div>
-
 {% endblock %}
\ No newline at end of file
diff --git a/templates/user/profile.html.twig b/templates/user/profile.html.twig
index a02eef8a508eff07569d36094696c98db223f43f..d6e80801ccecf76763cd89894490417248212004 100644
--- a/templates/user/profile.html.twig
+++ b/templates/user/profile.html.twig
@@ -13,12 +13,18 @@
         </div>
     </div>
 
-    {% for flashSuccess in app.flashes('profile_updated_success') %}
-        <div class="text-center alert alert-success col-5 mx-auto my-5" role="alert">
+    {% for flashSuccess in app.flashes('success') %}
+        <div class="text-center alert alert-success col-11 col-md-10 col-lg-9 col-xl-8 mx-auto mt-0 mb-4" role="alert">
             {{ flashSuccess }}
         </div>
     {% endfor %}
 
+    {% for flashWarning in app.flashes('warning') %}
+        <div class="text-center alert alert-warning col-11 col-md-10 col-lg-9 col-xl-8 mx-auto mt-0 mb-4" role="alert">
+            {{ flashWarning }}
+        </div>
+    {% endfor %}
+
     <div class="d-flex flex-column flex-md-row justify-content-center align-items-center">
         <div class="profile-block d-flex flex-row ps-3 ps-md-5 pe-3 pe-md-5 pt-4 pb-3 fw-normal me-0 me-md-5">
             <div class="pe-3 pe-md-4 text-nowrap">
diff --git a/templates/user/update_email.html.twig b/templates/user/update_email.html.twig
new file mode 100644
index 0000000000000000000000000000000000000000..0f092ca27a0b78c7811360894e53620ba7e8bdd3
--- /dev/null
+++ b/templates/user/update_email.html.twig
@@ -0,0 +1,15 @@
+<h1>
+    {{ 'user.edit.email.title'|trans }}
+</h1>
+
+<p>
+    {{ 'user.edit.email.text'|trans }}:
+    <br><br>
+    <a href="{{ url('verify_new_email_address') }}">
+        {{ 'user.edit.email.confirm_email'|trans }}
+    </a>
+</p>
+
+<p>
+    {{ 'general.greeting'|trans }}
+</p>
diff --git a/tests/functional/UserControllerTest.php b/tests/functional/UserControllerTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..427ed8353895dbfabab2e80bd1782f8f74e214c2
--- /dev/null
+++ b/tests/functional/UserControllerTest.php
@@ -0,0 +1,67 @@
+<?php
+
+namespace App\Tests\functional;
+
+use App\Entity\User;
+use Exception;
+use Symfony\Bundle\FrameworkBundle\KernelBrowser;
+use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
+
+class UserControllerTest extends WebTestCase
+{
+    private KernelBrowser $client;
+    private User $verified_user;
+
+    protected function setUp(): void
+    {
+        self::ensureKernelShutdown();
+        $this->client = static::createClient();
+
+        $object_manager = $this->client->getContainer()
+            ->get('doctrine')
+            ->getManager();
+
+        $verified_user = $object_manager
+            ->getRepository(User::class)
+            ->findOneBy(['email' => 'defaultUser@localhost.com']);
+
+        if (! $verified_user instanceof User) {
+            throw new \Exception("User does not exist.");
+        }
+
+        $this->verified_user = $verified_user;
+    }
+
+    public function testWhenUserUpdateEmailHeReceivesAConfirmationLinkByEMail(): void
+    {
+        $new_email_address = 'defaultuser@localhost.test';
+        $this->client->loginUser($this->verified_user);
+        $crawler = $this->client->request('GET', '/edit_profile');
+
+        $this->assertResponseIsSuccessful();
+        $this->client->enableProfiler();
+
+        $submit = $crawler->selectButton('Update');
+        $form = $submit->form();
+        $form['edit_user_profile_form[email]'] = $new_email_address;
+        $form['edit_user_profile_form[current_password]'] = "password";
+        $this->client->submit($form);
+
+        $this->assertEmailCount(
+            1,
+            null,
+            'Once the user update his email, the system should send him a confirmation link by email'
+        );
+        $emailMessage = $this->getMailerMessage(0);
+
+        if (null === $emailMessage) {
+            throw new Exception("Email message could not be found");
+        }
+
+        $this->assertEmailAddressContains(
+            $emailMessage,
+            'To',
+            $new_email_address
+        );
+    }
+}
diff --git a/translations/messages.en.yaml b/translations/messages.en.yaml
index 9b2e68d9d6f9be9aa298936367f51412c3dd0f62..d3c7ea7f6b92117497cd48a3c04e9677a5dcf01b 100644
--- a/translations/messages.en.yaml
+++ b/translations/messages.en.yaml
@@ -107,7 +107,10 @@ user:
     title: My profile
     edit: Edit profile
     update: Update
-    updated_success: The profile has been updated
+    updated:
+      success: The profile has been updated
+      warning: In order to update your current email address related to your Memorekall account with the new email address new_email_address,
+        please confirm this change following the link your received by email.
   password:
     edit: Edit password
     current: Current password
@@ -115,6 +118,13 @@ user:
     updated_success: The password has been updated
   edit_profile: Edit my profile
   edit_password: Edit my password
+  edit_email_address: Edit my email address
+  edit:
+    email:
+      title: Hi! Please confirm your email
+      text: Please click the following link to update your user account and for now on use this email address
+      confirm_email: Confirm my email
+      success: Your MemoRekall account is now related to your new email address new_email_address
 
 editors:
     title: Editors
@@ -190,4 +200,8 @@ groups:
     success: Group group_name removed successfully
   filter:
     label: Filter by group
-    no_filter: Show all
\ No newline at end of file
+    no_filter: Show all
+
+pending_email_address:
+  email:
+    unique:
\ No newline at end of file
diff --git a/translations/messages.fr.yaml b/translations/messages.fr.yaml
index 55f20cea6a443e77c30b740689f2b7fbcb91b0fc..ec1f912892ae88eb561e4de71aa25173c2d3b213 100644
--- a/translations/messages.fr.yaml
+++ b/translations/messages.fr.yaml
@@ -106,7 +106,9 @@ user:
     title: Mon profil
     edit: Modifier mon profil
     update: Mettre à jour
-    updated_success: Votre profil a bien été mis à jour
+    updated:
+      success: Votre profil a bien été mis à jour
+      warning: Veuillez confirmer le changement d'adresse e-mail en activant le lien que vous avez reçu par mail à l'adresse new_email_address. L'adresse e-amil reliée à votre compte Memorekall sera alors mise à jour avec la nouvelle new_email_address.
   password:
     edit: Modifier mon mot de passe
     current: Mot de passe actuel
@@ -114,6 +116,13 @@ user:
     updated_success: Votre mot de passe a bien été modifié
   edit_profile: Modifier mon mot de passe
   edit_password: Modifier mon mot de passe
+  edit_email_address: Modifier mon adresse e-mail
+  edit:
+    email:
+      title: Bonjour ! Veuillez confirmer votre adresse email
+      text: Veuillez cliquer sur le lien suivant pour mettre à jour votre profil utilisateur et utiliser dorénavant cette adresse e-mail.
+      confirm_email: Confirmer mon adresse e-mail
+      success: Votre compte MemoRekall est dorénavant relié à cette nouvelle adresse e-mail new_email_address
 
 editors:
     title: Editeurs d'une capsule
diff --git a/translations/validators.en.yaml b/translations/validators.en.yaml
index 0b5aa0fde3be903238c1f689641011a2b4d17311..9fc33d66473360bc5ebbd0da5f7ded8066775290 100644
--- a/translations/validators.en.yaml
+++ b/translations/validators.en.yaml
@@ -27,4 +27,12 @@ capsule:
 group:
   name:
     not_blank: Please enter a group name
-    unique: There is already a group with this name
\ No newline at end of file
+    unique: There is already a group with this name
+
+user:
+  email:
+    unique: Email address already used
+
+pending_email_address:
+  email:
+    unique: Currently waiting for validation to use this new email address for your account
\ No newline at end of file
diff --git a/translations/validators.fr.yaml b/translations/validators.fr.yaml
index 90ce8ff4ed786c94b1923bac182f3ff2b7f99d1c..56d0c6a066164f197b673a09b530c7eabcfd84a1 100644
--- a/translations/validators.fr.yaml
+++ b/translations/validators.fr.yaml
@@ -27,4 +27,12 @@ capsule:
 group:
   name:
     not_blank: Veuillez saisir le nom du groupe
-    unique: Il existe déjà un groupe avec ce nom
\ No newline at end of file
+    unique: Il existe déjà un groupe avec ce nom
+
+user:
+  email:
+    unique: Il existe déjà un compte relié à cette adresse e-mail
+
+pending_email_address:
+  email:
+    unique: Cette adresse e-mail est en attente de validation pour votre compte
\ No newline at end of file