rustauth_core/options/
password.rs1use std::fmt;
2use std::sync::Arc;
3
4use http::Request;
5
6use time::Duration;
7
8use crate::auth::email_password::{PasswordHashFn, PasswordVerifyFn};
9use crate::db::User;
10use crate::error::RustAuthError;
11use crate::outbound::OutboundSendFuture;
12
13#[derive(Debug, Clone, PartialEq, Eq)]
15pub struct PasswordResetPayload {
16 pub user: User,
17}
18
19#[derive(Debug, Clone, PartialEq, Eq)]
21pub struct PasswordResetEmail {
22 pub user: User,
23 pub url: String,
24 pub token: String,
25}
26
27pub trait SendResetPassword: Send + Sync + 'static {
32 fn send_reset_password(
33 &self,
34 payload: PasswordResetEmail,
35 request: Option<&Request<Vec<u8>>>,
36 ) -> OutboundSendFuture;
37}
38
39impl<F> SendResetPassword for F
40where
41 F: for<'a> Fn(PasswordResetEmail, Option<&'a Request<Vec<u8>>>) -> OutboundSendFuture
42 + Send
43 + Sync
44 + 'static,
45{
46 fn send_reset_password(
47 &self,
48 payload: PasswordResetEmail,
49 request: Option<&Request<Vec<u8>>>,
50 ) -> OutboundSendFuture {
51 self(payload, request)
52 }
53}
54
55pub trait OnPasswordReset: Send + Sync + 'static {
57 fn on_password_reset(
58 &self,
59 payload: PasswordResetPayload,
60 request: Option<&Request<Vec<u8>>>,
61 ) -> Result<(), RustAuthError>;
62}
63
64impl<F> OnPasswordReset for F
65where
66 F: for<'a> Fn(PasswordResetPayload, Option<&'a Request<Vec<u8>>>) -> Result<(), RustAuthError>
67 + Send
68 + Sync
69 + 'static,
70{
71 fn on_password_reset(
72 &self,
73 payload: PasswordResetPayload,
74 request: Option<&Request<Vec<u8>>>,
75 ) -> Result<(), RustAuthError> {
76 self(payload, request)
77 }
78}
79
80#[derive(Clone)]
82pub struct PasswordOptions {
83 pub min_password_length: usize,
84 pub max_password_length: usize,
85 pub send_reset_password: Option<Arc<dyn SendResetPassword>>,
86 pub reset_password_token_expires_in: Option<Duration>,
87 pub on_password_reset: Option<Arc<dyn OnPasswordReset>>,
88 pub revoke_sessions_on_password_reset: bool,
89 pub hash_password: Option<PasswordHashFn>,
90 pub verify_password: Option<PasswordVerifyFn>,
91}
92
93impl Default for PasswordOptions {
94 fn default() -> Self {
95 Self {
96 min_password_length: 8,
97 max_password_length: 128,
98 send_reset_password: None,
99 reset_password_token_expires_in: None,
100 on_password_reset: None,
101 revoke_sessions_on_password_reset: false,
102 hash_password: None,
103 verify_password: None,
104 }
105 }
106}
107
108impl PasswordOptions {
109 pub fn new() -> Self {
110 Self::default()
111 }
112
113 pub fn builder() -> Self {
114 Self::new()
115 }
116
117 #[must_use]
118 pub fn min_password_length(mut self, length: usize) -> Self {
119 self.min_password_length = length;
120 self
121 }
122
123 #[must_use]
124 pub fn max_password_length(mut self, length: usize) -> Self {
125 self.max_password_length = length;
126 self
127 }
128
129 #[must_use]
130 pub fn send_reset_password<S>(mut self, sender: S) -> Self
131 where
132 S: SendResetPassword,
133 {
134 self.send_reset_password = Some(Arc::new(sender));
135 self
136 }
137
138 #[must_use]
139 pub fn reset_password_token_expires_in(mut self, expires_in: Duration) -> Self {
140 self.reset_password_token_expires_in = Some(expires_in);
141 self
142 }
143
144 #[must_use]
145 pub fn on_password_reset<P>(mut self, handler: P) -> Self
146 where
147 P: OnPasswordReset,
148 {
149 self.on_password_reset = Some(Arc::new(handler));
150 self
151 }
152
153 #[must_use]
154 pub fn revoke_sessions_on_password_reset(mut self, enabled: bool) -> Self {
155 self.revoke_sessions_on_password_reset = enabled;
156 self
157 }
158
159 #[must_use]
160 pub fn hash_password(mut self, hash: PasswordHashFn) -> Self {
161 self.hash_password = Some(hash);
162 self
163 }
164
165 #[must_use]
166 pub fn verify_password(mut self, verify: PasswordVerifyFn) -> Self {
167 self.verify_password = Some(verify);
168 self
169 }
170}
171
172impl fmt::Debug for PasswordOptions {
173 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
174 formatter
175 .debug_struct("PasswordOptions")
176 .field("min_password_length", &self.min_password_length)
177 .field("max_password_length", &self.max_password_length)
178 .field(
179 "send_reset_password",
180 &self
181 .send_reset_password
182 .as_ref()
183 .map(|_| "<send-reset-password>"),
184 )
185 .field(
186 "reset_password_token_expires_in",
187 &self.reset_password_token_expires_in,
188 )
189 .field(
190 "on_password_reset",
191 &self
192 .on_password_reset
193 .as_ref()
194 .map(|_| "<on-password-reset>"),
195 )
196 .field(
197 "revoke_sessions_on_password_reset",
198 &self.revoke_sessions_on_password_reset,
199 )
200 .finish()
201 }
202}