Skip to main content

doido_auth/controllers/
passwords.rs

1//! Default passwords controller (reset request + update stubs).
2
3use doido_auth_macros::auth_controller;
4use doido_controller::respond::Format;
5use doido_core::Result;
6use serde::Deserialize;
7use std::marker::PhantomData;
8
9/// Default passwords controller for [`auth_routes!`](crate::auth_routes).
10pub struct AuthPasswords<U>(PhantomData<U>);
11
12#[derive(Debug, Deserialize)]
13#[allow(dead_code)]
14pub struct PasswordResetForm {
15    pub email: String,
16}
17
18#[derive(Debug, Deserialize)]
19#[allow(dead_code)]
20pub struct PasswordUpdateForm {
21    pub password: String,
22    pub password_confirmation: String,
23    pub reset_token: String,
24}
25
26#[auth_controller]
27impl<U> AuthPasswords<U>
28where
29    U: Send + Sync + 'static,
30{
31    /// GET `{prefix}/password/new` — request-reset form (HTML mode).
32    pub async fn new(ctx: doido_controller::Context) -> doido_controller::Response {
33        ctx.render("auth/password_new", serde_json::json!({}))
34    }
35
36    /// POST `{prefix}/password` — enqueue a reset email (stub).
37    pub async fn create(ctx: doido_controller::Context) -> Result<doido_controller::Response> {
38        let json = ctx.negotiated_format() == Format::Json;
39        let _form: PasswordResetForm = if json {
40            ctx.body_json().await?
41        } else {
42            ctx.form().await?
43        };
44        if json {
45            Ok(ctx.json(serde_json::json!({ "status": "reset_email_sent" })))
46        } else {
47            Ok(ctx.render(
48                "auth/password_new",
49                serde_json::json!({ "notice": "If your email exists, reset instructions were sent." }),
50            ))
51        }
52    }
53
54    /// PATCH `{prefix}/password` — apply a reset token (stub).
55    pub async fn update(mut ctx: doido_controller::Context) -> Result<doido_controller::Response> {
56        let json = ctx.negotiated_format() == Format::Json;
57        let _form: PasswordUpdateForm = if json {
58            ctx.body_json().await?
59        } else {
60            ctx.form().await?
61        };
62        if json {
63            Ok(ctx.status(204))
64        } else {
65            Ok(ctx.redirect_to("/users/sign_in"))
66        }
67    }
68}