diff --git a/TODO.md b/TODO.md
index 9cb72f33e07d5a23b1b3b42b6c165ae46d3b99a2..06d42a1da7f1dae0df14401a86aa5d62820af55d 100644
--- a/TODO.md
+++ b/TODO.md
@@ -1,5 +1,4 @@
 - Implement detailed view of Participant information
-- Password reset after account creation
 - Client side field validation
 
 - Traduction
diff --git a/client/src/components/forms-component/SubmitSuccess.tsx b/client/src/components/forms-component/SubmitSuccess.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..bcf7696c61a9b14fe1d24c1fcf1c59754a4aee09
--- /dev/null
+++ b/client/src/components/forms-component/SubmitSuccess.tsx
@@ -0,0 +1,15 @@
+import { Expandable } from "./Expandable"
+
+type Props = {
+    success: () => string | null
+}
+
+export function SubmitSuccess(props: Props) {
+    return (
+        <Expandable expanded={!!props.success()}>
+            <div class="pt-4 text-sm text-green-500 dark:text-green-400 md:text-base lg:pt-5 lg:text-lg">
+                {props.success()}
+            </div>
+        </Expandable>
+    )
+}
diff --git a/client/src/components/forms/EmailResetForm.tsx b/client/src/components/forms/EmailResetForm.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..4248fe79e1e65bbd1cdf0bce0bb6d888e6cc619a
--- /dev/null
+++ b/client/src/components/forms/EmailResetForm.tsx
@@ -0,0 +1,68 @@
+import {
+    createForm,
+    email,
+    required,
+    SubmitHandler,
+} from "@modular-forms/solid"
+import { createSignal } from "solid-js"
+import { EmailResetPayload } from "../../binding/EmailResetPayload"
+import { resetEmail } from "../../request/routes"
+import { t } from "../../stores/locale"
+import { SubmitError } from "../forms-component/SubmitError"
+import { SubmitSuccess } from "../forms-component/SubmitSuccess"
+import { TextInput } from "../forms-component/TextInput"
+
+export function EmailResetForm() {
+    const [_loginForm, { Form, Field }] = createForm<EmailResetPayload>()
+
+    const [error, setError] = createSignal<string | null>(null)
+    const [success, setSuccess] = createSignal<string | null>(null)
+
+    const handleSubmit: SubmitHandler<EmailResetPayload> = async (
+        values,
+        event,
+    ) => {
+        event.preventDefault()
+        const request = await resetEmail(values)
+        if (request.status !== 200) {
+            setError(t("loginPage.badLogin"))
+            setSuccess(null)
+        } else {
+            setError(null)
+            setSuccess(t("loginPage.resetEmailSent"))
+        }
+    }
+    return (
+        <Form class="space-y-6" onSubmit={handleSubmit}>
+            <Field
+                name="email"
+                validate={[
+                    required(t("loginPage.requiredEmail")),
+                    email(t("loginPage.invalidEmail")),
+                ]}
+            >
+                {(field, props) => (
+                    <TextInput
+                        {...props}
+                        value={field.value}
+                        error={field.error}
+                        label={t("loginPage.email")}
+                        type="email"
+                        placeholder="exemple@courriel.com"
+                        required
+                    />
+                )}
+            </Field>
+            <div>
+                <button
+                    type="submit"
+                    class="flex w-full justify-center rounded-md bg-light-highlight py-3 font-semibold text-white shadow-sm"
+                >
+                    {t("loginPage.signIn")}
+                </button>
+                <SubmitSuccess success={success} />
+                <SubmitError error={error} />
+            </div>
+        </Form>
+    )
+}
diff --git a/client/src/components/forms/LoginForm.tsx b/client/src/components/forms/LoginForm.tsx
index 8e6198f0a8d3b2adf82dfdaabd1389cadde8099b..397c1b767eef343dffe69e19b6d9a68785cd08bd 100644
--- a/client/src/components/forms/LoginForm.tsx
+++ b/client/src/components/forms/LoginForm.tsx
@@ -12,6 +12,7 @@ import { TextInput } from "../forms-component/TextInput"
 import { SubmitError } from "../forms-component/SubmitError"
 import { createSignal } from "solid-js"
 import { t } from "../../stores/locale"
+import PrefetchLink from "../PrefetchLink"
 
 export default function LoginForm() {
     const [_loginForm, { Form, Field }] = createForm<AuthPayload>()
@@ -32,61 +33,67 @@ export default function LoginForm() {
     }
 
     return (
-        <div class="mt-10 sm:mx-auto sm:w-full sm:max-w-sm">
-            <Form class="space-y-6" onSubmit={handleSubmit}>
-                <Field
-                    name="email"
-                    validate={[
-                        required(t("loginPage.requiredEmail")),
-                        email(t("loginPage.invalidEmail")),
-                    ]}
-                >
-                    {(field, props) => (
-                        <TextInput
-                            {...props}
-                            value={field.value}
-                            error={field.error}
-                            label={t("loginPage.email")}
-                            type="email"
-                            placeholder="exemple@courriel.com"
-                            required
-                        />
-                    )}
-                </Field>
+        <Form class="space-y-6" onSubmit={handleSubmit}>
+            <Field
+                name="email"
+                validate={[
+                    required(t("loginPage.requiredEmail")),
+                    email(t("loginPage.invalidEmail")),
+                ]}
+            >
+                {(field, props) => (
+                    <TextInput
+                        {...props}
+                        value={field.value}
+                        error={field.error}
+                        label={t("loginPage.email")}
+                        type="email"
+                        placeholder="exemple@courriel.com"
+                        required
+                    />
+                )}
+            </Field>
 
-                <Field
-                    name="password"
-                    validate={[
-                        required(t("loginPage.requiredPassword")),
-                        minLength(
-                            8,
-                            "You password must have 8 characters or more.",
-                        ),
-                    ]}
+            <Field
+                name="password"
+                validate={[
+                    required(t("loginPage.requiredPassword")),
+                    minLength(
+                        8,
+                        "You password must have 8 characters or more.",
+                    ),
+                ]}
+            >
+                {(field, props) => (
+                    <TextInput
+                        {...props}
+                        value={field.value}
+                        error={field.error}
+                        type="password"
+                        label={t("loginPage.password")}
+                        placeholder="********"
+                        required
+                    />
+                )}
+            </Field>
+            <PrefetchLink
+                to="/forgotten-password"
+                file="ForgottenPassword"
+                class="block"
+            >
+                <span class="text-green-500">
+                    {t("loginPage.forgotPassword")}
+                </span>
+            </PrefetchLink>
+            <div>
+                <button
+                    type="submit"
+                    class="flex w-full justify-center rounded-md bg-light-highlight py-3 font-semibold text-white shadow-sm"
                 >
-                    {(field, props) => (
-                        <TextInput
-                            {...props}
-                            value={field.value}
-                            error={field.error}
-                            type="password"
-                            label={t("loginPage.password")}
-                            placeholder="********"
-                            required
-                        />
-                    )}
-                </Field>
-
-                <div>
-                    <button
-                        type="submit"
-                        class="flex w-full justify-center rounded-md bg-light-highlight py-3 font-semibold text-white shadow-sm"
-                    >
-                        {t("loginPage.signIn")}
-                    </button>
-                    <SubmitError error={error} />
-                </div>
-            </Form>
-        </div>
+                    {t("loginPage.signIn")}
+                </button>
+                <SubmitError error={error} />
+            </div>
+        </Form>
     )
 }
diff --git a/client/src/i18n/en.ts b/client/src/i18n/en.ts
index 0e871e85f0acb69cf765a4b62b4dcbf93c88c1c7..8e8718bab3a9fcf1bbe5f969b9c78eece1dbf085 100644
--- a/client/src/i18n/en.ts
+++ b/client/src/i18n/en.ts
@@ -96,6 +96,8 @@ const loginPage = {
     email: "Email",
     password: "Password",
     signIn: "Sign in",
+    forgotPassword: "Forgot password?",
+    resetEmailSent: "An email has been sent to reset your password.",
 }
 
 const additionalInfo = {
diff --git a/client/src/i18n/fr.ts b/client/src/i18n/fr.ts
index ea6c0f9257252474b479eb706988fbc1d634651e..681f6c8c49af6a071cce794c19d4277015c816ac 100644
--- a/client/src/i18n/fr.ts
+++ b/client/src/i18n/fr.ts
@@ -96,6 +96,8 @@ const loginPage = {
     email: "Courriel",
     password: "Mot de passe",
     signIn: "Se connecter",
+    forgotPassword: "Mot de passe oublié?",
+    resetEmailSent: "Courriel de réinitialisation envoyé",
 }
 
 const additionalInfo = {
diff --git a/client/src/index.tsx b/client/src/index.tsx
index 101035db7403a5db3a78704b71cd9d42bf2c98dc..1d662c9f3979cc58eb72419f42c14f81e210c216 100644
--- a/client/src/index.tsx
+++ b/client/src/index.tsx
@@ -27,6 +27,7 @@ const Dashboard = lazy(() => import("./routes/Dashboard"))
 const AdditionalForm = lazy(() => import("./routes/AdditionalForm"))
 const ListParticipant = lazy(() => import("./routes/ListParticipant"))
 const ChangePassword = lazy(() => import("./routes/ChangePassword"))
+const ForgottenPassword = lazy(() => import("./routes/ForgottenPassword"))
 
 const app = document.getElementById("app")
 if (app) {
@@ -47,6 +48,10 @@ if (app) {
                     path="/change-password/:token?"
                     component={ChangePassword}
                 />
+                <Route
+                    path="/forgotten-password"
+                    component={ForgottenPassword}
+                />
                 <Route path="*" component={NotFound} />
             </Router>
         ),
diff --git a/client/src/request/routes.ts b/client/src/request/routes.ts
index 581276fb45afea74b85227882109c75b07992097..9f4f91f16bef30513d4a31d6e8f499b7e3e2a0ff 100644
--- a/client/src/request/routes.ts
+++ b/client/src/request/routes.ts
@@ -1,5 +1,6 @@
 import { AuthPayload } from "../binding/AuthPayload"
 import { ChangePasswordPayload } from "../binding/ChangePasswordPayload"
+import { EmailResetPayload } from "../binding/EmailResetPayload"
 import { MinimalParticipant } from "../binding/MinimalParticipant"
 import { ParticipantPreview } from "../binding/ParticipantPreview"
 import {
@@ -49,3 +50,7 @@ export async function testAuth() {
     }
     return await request.json()
 }
+
+export async function resetEmail(email: EmailResetPayload) {
+    return await fetch_post_no_token("/password", email)
+}
diff --git a/client/src/routes/ForgottenPassword.tsx b/client/src/routes/ForgottenPassword.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..fcc7e4d7e6ac738894025ca64cedca9ca5261dea
--- /dev/null
+++ b/client/src/routes/ForgottenPassword.tsx
@@ -0,0 +1,18 @@
+import FixedImage from "../components/FixedImage"
+import { EmailResetForm } from "../components/forms/EmailResetForm"
+import { t } from "../stores/locale"
+
+export default function ForgottenPassword() {
+    return (
+        <div class="flex w-full flex-col items-center justify-center">
+            <FixedImage url="/banners/documents.svg" height="32rem">
+                <h1 class="text-center font-futur text-6xl text-white">
+                    {t("loginPage.forgotPassword")}
+                </h1>
+            </FixedImage>
+            <div class="-mt-32 flex h-full w-full flex-row items-center justify-center gap-4 p-4 font-futur text-xl font-bold">
+                <EmailResetForm />
+            </div>
+        </div>
+    )
+}
diff --git a/server/.sqlx/query-01bd25a5698e76cdec3ae0eb1a638059914202a09aa606af11f38d7848f37c67.json b/server/.sqlx/query-01bd25a5698e76cdec3ae0eb1a638059914202a09aa606af11f38d7848f37c67.json
deleted file mode 100644
index 4f74f8d77594a8f983649021ed0c37be7bdfbeb5..0000000000000000000000000000000000000000
--- a/server/.sqlx/query-01bd25a5698e76cdec3ae0eb1a638059914202a09aa606af11f38d7848f37c67.json
+++ /dev/null
@@ -1,46 +0,0 @@
-{
-  "db_name": "PostgreSQL",
-  "query": "UPDATE participants SET (medical_conditions, allergies, supper, pronouns, competition, phone_number, tshirt_size, comments, emergency_contact, has_monthly_opus_card, reduced_mobility, study_proof, photo, cv)\n                = ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14) WHERE id = $15",
-  "describe": {
-    "columns": [],
-    "parameters": {
-      "Left": [
-        "Text",
-        "Text",
-        "Text",
-        "Text",
-        {
-          "Custom": {
-            "name": "competition",
-            "kind": {
-              "Enum": [
-                "none",
-                "conception_senior",
-                "conception_junior",
-                "debats_oratoires",
-                "reingenierie",
-                "genie_conseil",
-                "communication_scientifique",
-                "programmation",
-                "conception_innovatrice",
-                "cycle_superieur"
-              ]
-            }
-          }
-        },
-        "Text",
-        "Text",
-        "Text",
-        "Text",
-        "Bool",
-        "Text",
-        "Bytea",
-        "Bytea",
-        "Bytea",
-        "Uuid"
-      ]
-    },
-    "nullable": []
-  },
-  "hash": "01bd25a5698e76cdec3ae0eb1a638059914202a09aa606af11f38d7848f37c67"
-}
diff --git a/server/.sqlx/query-e08b705c8f710fe9496a9b72c258fed4cd4c7952a9c5cb2a6f8e5564758c3fce.json b/server/.sqlx/query-8e6f6c7229ba7d13f4690c70229bac29698bbccae3adfb0f2cdcdff1daa9fe15.json
similarity index 74%
rename from server/.sqlx/query-e08b705c8f710fe9496a9b72c258fed4cd4c7952a9c5cb2a6f8e5564758c3fce.json
rename to server/.sqlx/query-8e6f6c7229ba7d13f4690c70229bac29698bbccae3adfb0f2cdcdff1daa9fe15.json
index 59756034a61f8b1062a8ec64744fad4586f8cb26..8a68ae7371aa8d648e8e5f7c17fc1ebfee61d60d 100644
--- a/server/.sqlx/query-e08b705c8f710fe9496a9b72c258fed4cd4c7952a9c5cb2a6f8e5564758c3fce.json
+++ b/server/.sqlx/query-8e6f6c7229ba7d13f4690c70229bac29698bbccae3adfb0f2cdcdff1daa9fe15.json
@@ -1,6 +1,6 @@
 {
   "db_name": "PostgreSQL",
-  "query": "SELECT id, role AS \"role: Role\", university FROM participants WHERE email = $1",
+  "query": "SELECT id, role AS \"role: Role\", university AS \"university: University\" FROM participants WHERE email = $1",
   "describe": {
     "columns": [
       {
@@ -27,7 +27,7 @@
       },
       {
         "ordinal": 2,
-        "name": "university",
+        "name": "university: University",
         "type_info": "Text"
       }
     ],
@@ -42,5 +42,5 @@
       false
     ]
   },
-  "hash": "e08b705c8f710fe9496a9b72c258fed4cd4c7952a9c5cb2a6f8e5564758c3fce"
+  "hash": "8e6f6c7229ba7d13f4690c70229bac29698bbccae3adfb0f2cdcdff1daa9fe15"
 }
diff --git a/server/.sqlx/query-4ba558a81017dfe3d22e15a97f7e57e8a5404d9910102f7bd87eb9b887e97fcb.json b/server/.sqlx/query-a902b8930ff8374bde666f05bbab23a168364c617c4de636fe799cf00f8bc16b.json
similarity index 81%
rename from server/.sqlx/query-4ba558a81017dfe3d22e15a97f7e57e8a5404d9910102f7bd87eb9b887e97fcb.json
rename to server/.sqlx/query-a902b8930ff8374bde666f05bbab23a168364c617c4de636fe799cf00f8bc16b.json
index 9c528615386e95f606d73bf734a1aa0963a53f9c..a4f03b84fe355d40c4010fe45c57b713b67a1bf3 100644
--- a/server/.sqlx/query-4ba558a81017dfe3d22e15a97f7e57e8a5404d9910102f7bd87eb9b887e97fcb.json
+++ b/server/.sqlx/query-a902b8930ff8374bde666f05bbab23a168364c617c4de636fe799cf00f8bc16b.json
@@ -1,6 +1,6 @@
 {
   "db_name": "PostgreSQL",
-  "query": "SELECT id, role AS \"role: Role\", password_hash, university FROM participants WHERE email = $1",
+  "query": "SELECT id, role AS \"role: Role\", password_hash, university AS \"university: University\" FROM participants WHERE email = $1",
   "describe": {
     "columns": [
       {
@@ -32,7 +32,7 @@
       },
       {
         "ordinal": 3,
-        "name": "university",
+        "name": "university: University",
         "type_info": "Text"
       }
     ],
@@ -48,5 +48,5 @@
       false
     ]
   },
-  "hash": "4ba558a81017dfe3d22e15a97f7e57e8a5404d9910102f7bd87eb9b887e97fcb"
+  "hash": "a902b8930ff8374bde666f05bbab23a168364c617c4de636fe799cf00f8bc16b"
 }
diff --git a/server/.sqlx/query-b2cf8ace57c4a960f64b49060612f3c4918a7eb20626e5827dd2ebd0b5c65294.json b/server/.sqlx/query-b2cf8ace57c4a960f64b49060612f3c4918a7eb20626e5827dd2ebd0b5c65294.json
new file mode 100644
index 0000000000000000000000000000000000000000..ba5d2a47e5a98916db88e46c6a1362cb652a90b3
--- /dev/null
+++ b/server/.sqlx/query-b2cf8ace57c4a960f64b49060612f3c4918a7eb20626e5827dd2ebd0b5c65294.json
@@ -0,0 +1,27 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "UPDATE participants SET (medical_conditions, allergies, is_vegetarian, pronouns, phone_number, tshirt_size, comments, emergency_contact, has_monthly_opus_card, reduced_mobility, study_proof, photo, cv)\n                = ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13) WHERE id = $14",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Text",
+        "Text",
+        "Bool",
+        "Text",
+        "Text",
+        "Text",
+        "Text",
+        "Text",
+        "Bool",
+        "Text",
+        "Bytea",
+        "Bytea",
+        "Bytea",
+        "Uuid"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "b2cf8ace57c4a960f64b49060612f3c4918a7eb20626e5827dd2ebd0b5c65294"
+}
diff --git a/server/src/routes/new_participant.rs b/server/src/routes/new_participant.rs
index 8336ae983195e857fda6a00c6d8fefeed385f526..7a3f8decd55336ef12fb025f2e166874b1404e31 100644
--- a/server/src/routes/new_participant.rs
+++ b/server/src/routes/new_participant.rs
@@ -21,8 +21,7 @@ pub async fn new_participant(
         .send_email(
             "Inscription CQI/QEC 2025",
             format!(
-                r#"
-Bienvenue {} {},
+                r#"Bienvenue {} {},
 Vous avez été inscrit à la compétition CQI/QEC 2025.
 Votre courriel est : {}
 Votre mot de passe est : {}
@@ -34,8 +33,7 @@ You have been registered for the CQI/QEC 2025 competition.
 Your email is : {}
 Your password is : {}
 You can log in at the following address :
-https://cqi-qec.qc.ca/login
-        "#,
+https://cqi-qec.qc.ca/login"#,
                 &participant.first_name,
                 &participant.last_name,
                 &participant.email,