1use crate::config::AuthConfig;
7use crate::error::AuthResult;
8use crate::hooks::RequestHookContext;
9use crate::schema::AuthSchema;
10use crate::types::{
11 CreateAccount, CreateSession, CreateUser, CreateVerification, UpdateAccount, UpdateUser,
12 UpdateVerification,
13};
14use async_trait::async_trait;
15
16#[derive(Debug, Clone, Copy, PartialEq, Eq)]
18pub enum HookControl {
19 Continue,
20 Cancel,
21}
22
23impl HookControl {
24 #[must_use]
25 pub const fn is_cancelled(self) -> bool {
26 matches!(self, Self::Cancel)
27 }
28}
29
30pub trait HookBackend: Send + Sync + 'static {
32 type Connection: Send + Sync;
34 type Transaction: Send + Sync;
36}
37
38pub struct DatabaseHookContext<'a, B: HookBackend> {
40 pub config: &'a AuthConfig,
41 pub db: &'a B::Connection,
42 pub tx: Option<&'a B::Transaction>,
45 pub request: Option<RequestHookContext>,
46}
47
48impl<B: HookBackend> std::fmt::Debug for DatabaseHookContext<'_, B> {
49 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
50 f.debug_struct("DatabaseHookContext")
51 .finish_non_exhaustive()
52 }
53}
54
55#[async_trait]
61pub trait DatabaseHooks<S: AuthSchema, B: HookBackend>: Send + Sync {
62 async fn before_create_user(
63 &self,
64 _user: &mut CreateUser,
65 _ctx: &DatabaseHookContext<'_, B>,
66 ) -> AuthResult<HookControl> {
67 Ok(HookControl::Continue)
68 }
69
70 async fn after_create_user(
71 &self,
72 _user: &S::User,
73 _ctx: &DatabaseHookContext<'_, B>,
74 ) -> AuthResult<()> {
75 Ok(())
76 }
77
78 async fn before_update_user(
79 &self,
80 _id: &str,
81 _update: &mut UpdateUser,
82 _ctx: &DatabaseHookContext<'_, B>,
83 ) -> AuthResult<HookControl> {
84 Ok(HookControl::Continue)
85 }
86
87 async fn after_update_user(
88 &self,
89 _user: &S::User,
90 _ctx: &DatabaseHookContext<'_, B>,
91 ) -> AuthResult<()> {
92 Ok(())
93 }
94
95 async fn before_delete_user(
96 &self,
97 _user: &S::User,
98 _ctx: &DatabaseHookContext<'_, B>,
99 ) -> AuthResult<HookControl> {
100 Ok(HookControl::Continue)
101 }
102
103 async fn after_delete_user(
104 &self,
105 _user: &S::User,
106 _ctx: &DatabaseHookContext<'_, B>,
107 ) -> AuthResult<()> {
108 Ok(())
109 }
110
111 async fn before_create_session(
112 &self,
113 _session: &mut CreateSession,
114 _ctx: &DatabaseHookContext<'_, B>,
115 ) -> AuthResult<HookControl> {
116 Ok(HookControl::Continue)
117 }
118
119 async fn after_create_session(
120 &self,
121 _session: &S::Session,
122 _ctx: &DatabaseHookContext<'_, B>,
123 ) -> AuthResult<()> {
124 Ok(())
125 }
126
127 async fn before_update_session(
128 &self,
129 _token: &str,
130 _fields: &mut crate::field_policy::FieldValues,
131 _ctx: &DatabaseHookContext<'_, B>,
132 ) -> AuthResult<HookControl> {
133 Ok(HookControl::Continue)
134 }
135
136 async fn after_update_session_missing(
139 &self,
140 _token: &str,
141 _ctx: &DatabaseHookContext<'_, B>,
142 ) -> AuthResult<()> {
143 Ok(())
144 }
145
146 async fn after_update_session(
147 &self,
148 _session: &S::Session,
149 _ctx: &DatabaseHookContext<'_, B>,
150 ) -> AuthResult<()> {
151 Ok(())
152 }
153
154 async fn before_delete_session(
155 &self,
156 _session: &S::Session,
157 _ctx: &DatabaseHookContext<'_, B>,
158 ) -> AuthResult<HookControl> {
159 Ok(HookControl::Continue)
160 }
161
162 async fn after_delete_session(
163 &self,
164 _session: &S::Session,
165 _ctx: &DatabaseHookContext<'_, B>,
166 ) -> AuthResult<()> {
167 Ok(())
168 }
169
170 async fn before_create_account(
171 &self,
172 _account: &mut CreateAccount,
173 _ctx: &DatabaseHookContext<'_, B>,
174 ) -> AuthResult<HookControl> {
175 Ok(HookControl::Continue)
176 }
177
178 async fn after_create_account(
179 &self,
180 _account: &S::Account,
181 _ctx: &DatabaseHookContext<'_, B>,
182 ) -> AuthResult<()> {
183 Ok(())
184 }
185
186 async fn before_update_account(
187 &self,
188 _id: &str,
189 _update: &mut UpdateAccount,
190 _ctx: &DatabaseHookContext<'_, B>,
191 ) -> AuthResult<HookControl> {
192 Ok(HookControl::Continue)
193 }
194
195 async fn after_update_account(
196 &self,
197 _account: &S::Account,
198 _ctx: &DatabaseHookContext<'_, B>,
199 ) -> AuthResult<()> {
200 Ok(())
201 }
202
203 async fn before_delete_account(
204 &self,
205 _account: &S::Account,
206 _ctx: &DatabaseHookContext<'_, B>,
207 ) -> AuthResult<HookControl> {
208 Ok(HookControl::Continue)
209 }
210
211 async fn after_delete_account(
212 &self,
213 _account: &S::Account,
214 _ctx: &DatabaseHookContext<'_, B>,
215 ) -> AuthResult<()> {
216 Ok(())
217 }
218
219 async fn before_create_verification(
220 &self,
221 _verification: &mut CreateVerification,
222 _ctx: &DatabaseHookContext<'_, B>,
223 ) -> AuthResult<HookControl> {
224 Ok(HookControl::Continue)
225 }
226
227 async fn before_create_verification_record(
230 &self,
231 candidate: &mut crate::verification::VerificationCreation,
232 ctx: &DatabaseHookContext<'_, B>,
233 ) -> AuthResult<HookControl> {
234 let mut data = candidate.data();
235 let control = self.before_create_verification(&mut data, ctx).await?;
236 candidate.identifier = data.identifier;
237 candidate.value = data.value;
238 candidate.expires_at = data.expires_at;
239 Ok(control)
240 }
241
242 async fn after_create_verification_record(
245 &self,
246 snapshot: &crate::verification::VerificationSnapshot,
247 ctx: &DatabaseHookContext<'_, B>,
248 ) -> AuthResult<()> {
249 if let Some(model) = snapshot.original_model::<S::Verification>() {
250 self.after_create_verification(model, ctx).await?;
251 }
252 Ok(())
253 }
254
255 async fn after_create_verification(
256 &self,
257 _verification: &S::Verification,
258 _ctx: &DatabaseHookContext<'_, B>,
259 ) -> AuthResult<()> {
260 Ok(())
261 }
262
263 async fn before_delete_verification(
264 &self,
265 _verification: &S::Verification,
266 _ctx: &DatabaseHookContext<'_, B>,
267 ) -> AuthResult<HookControl> {
268 Ok(HookControl::Continue)
269 }
270
271 async fn before_update_verification(
272 &self,
273 _id: &str,
274 _update: &mut UpdateVerification,
275 _ctx: &DatabaseHookContext<'_, B>,
276 ) -> AuthResult<HookControl> {
277 Ok(HookControl::Continue)
278 }
279
280 async fn after_update_verification(
281 &self,
282 _verification: &S::Verification,
283 _ctx: &DatabaseHookContext<'_, B>,
284 ) -> AuthResult<()> {
285 Ok(())
286 }
287
288 async fn after_update_verification_record(
291 &self,
292 snapshot: Option<&crate::verification::VerificationSnapshot>,
293 ctx: &DatabaseHookContext<'_, B>,
294 ) -> AuthResult<()> {
295 if let Some(model) = snapshot.and_then(|value| value.original_model::<S::Verification>()) {
296 self.after_update_verification(model, ctx).await?;
297 }
298 Ok(())
299 }
300
301 async fn after_delete_verification(
302 &self,
303 _verification: &S::Verification,
304 _ctx: &DatabaseHookContext<'_, B>,
305 ) -> AuthResult<()> {
306 Ok(())
307 }
308}