rustauth_core/options/
email_verification.rs1use std::fmt;
2use std::sync::Arc;
3
4use http::Request;
5
6use time::Duration;
7
8use crate::db::User;
9use crate::error::RustAuthError;
10use crate::outbound::OutboundSendFuture;
11
12#[derive(Debug, Clone, PartialEq, Eq)]
14pub struct VerificationEmail {
15 pub user: User,
16 pub url: String,
17 pub token: String,
18}
19
20pub trait SendVerificationEmail: Send + Sync + 'static {
25 fn send_verification_email(
26 &self,
27 email: VerificationEmail,
28 request: Option<&Request<Vec<u8>>>,
29 ) -> OutboundSendFuture;
30}
31
32impl<F> SendVerificationEmail for F
33where
34 F: for<'a> Fn(VerificationEmail, Option<&'a Request<Vec<u8>>>) -> OutboundSendFuture
35 + Send
36 + Sync
37 + 'static,
38{
39 fn send_verification_email(
40 &self,
41 email: VerificationEmail,
42 request: Option<&Request<Vec<u8>>>,
43 ) -> OutboundSendFuture {
44 self(email, request)
45 }
46}
47
48#[derive(Debug, Clone, PartialEq, Eq)]
50pub struct EmailVerificationCallbackPayload {
51 pub user: User,
52}
53
54pub trait BeforeEmailVerification: Send + Sync + 'static {
56 fn before_email_verification(
57 &self,
58 payload: EmailVerificationCallbackPayload,
59 request: Option<&Request<Vec<u8>>>,
60 ) -> Result<(), RustAuthError>;
61}
62
63impl<F> BeforeEmailVerification for F
64where
65 F: for<'a> Fn(
66 EmailVerificationCallbackPayload,
67 Option<&'a Request<Vec<u8>>>,
68 ) -> Result<(), RustAuthError>
69 + Send
70 + Sync
71 + 'static,
72{
73 fn before_email_verification(
74 &self,
75 payload: EmailVerificationCallbackPayload,
76 request: Option<&Request<Vec<u8>>>,
77 ) -> Result<(), RustAuthError> {
78 self(payload, request)
79 }
80}
81
82pub trait AfterEmailVerification: Send + Sync + 'static {
84 fn after_email_verification(
85 &self,
86 payload: EmailVerificationCallbackPayload,
87 request: Option<&Request<Vec<u8>>>,
88 ) -> Result<(), RustAuthError>;
89}
90
91impl<F> AfterEmailVerification for F
92where
93 F: for<'a> Fn(
94 EmailVerificationCallbackPayload,
95 Option<&'a Request<Vec<u8>>>,
96 ) -> Result<(), RustAuthError>
97 + Send
98 + Sync
99 + 'static,
100{
101 fn after_email_verification(
102 &self,
103 payload: EmailVerificationCallbackPayload,
104 request: Option<&Request<Vec<u8>>>,
105 ) -> Result<(), RustAuthError> {
106 self(payload, request)
107 }
108}
109
110#[derive(Clone, Default)]
112pub struct EmailVerificationOptions {
113 pub send_verification_email: Option<Arc<dyn SendVerificationEmail>>,
114 pub before_email_verification: Option<Arc<dyn BeforeEmailVerification>>,
115 pub after_email_verification: Option<Arc<dyn AfterEmailVerification>>,
116 pub expires_in: Option<Duration>,
117 pub send_on_sign_up: bool,
118 pub send_on_sign_in: bool,
119 pub auto_sign_in_after_verification: bool,
120}
121
122impl EmailVerificationOptions {
123 pub fn new() -> Self {
124 Self::default()
125 }
126
127 pub fn builder() -> Self {
128 Self::new()
129 }
130
131 #[must_use]
132 pub fn send_verification_email<S>(mut self, sender: S) -> Self
133 where
134 S: SendVerificationEmail,
135 {
136 self.send_verification_email = Some(Arc::new(sender));
137 self
138 }
139
140 #[must_use]
141 pub fn before_email_verification<B>(mut self, callback: B) -> Self
142 where
143 B: BeforeEmailVerification,
144 {
145 self.before_email_verification = Some(Arc::new(callback));
146 self
147 }
148
149 #[must_use]
150 pub fn after_email_verification<A>(mut self, callback: A) -> Self
151 where
152 A: AfterEmailVerification,
153 {
154 self.after_email_verification = Some(Arc::new(callback));
155 self
156 }
157
158 #[must_use]
159 pub fn expires_in(mut self, expires_in: Duration) -> Self {
160 self.expires_in = Some(expires_in);
161 self
162 }
163
164 #[must_use]
165 pub fn send_on_sign_up(mut self, enabled: bool) -> Self {
166 self.send_on_sign_up = enabled;
167 self
168 }
169
170 #[must_use]
171 pub fn send_on_sign_in(mut self, enabled: bool) -> Self {
172 self.send_on_sign_in = enabled;
173 self
174 }
175
176 #[must_use]
177 pub fn auto_sign_in_after_verification(mut self, enabled: bool) -> Self {
178 self.auto_sign_in_after_verification = enabled;
179 self
180 }
181}
182
183impl fmt::Debug for EmailVerificationOptions {
184 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
185 formatter
186 .debug_struct("EmailVerificationOptions")
187 .field(
188 "send_verification_email",
189 &self
190 .send_verification_email
191 .as_ref()
192 .map(|_| "<send-verification-email>"),
193 )
194 .field(
195 "before_email_verification",
196 &self
197 .before_email_verification
198 .as_ref()
199 .map(|_| "<before-email-verification>"),
200 )
201 .field(
202 "after_email_verification",
203 &self
204 .after_email_verification
205 .as_ref()
206 .map(|_| "<after-email-verification>"),
207 )
208 .field("expires_in", &self.expires_in)
209 .field("send_on_sign_up", &self.send_on_sign_up)
210 .field("send_on_sign_in", &self.send_on_sign_in)
211 .field(
212 "auto_sign_in_after_verification",
213 &self.auto_sign_in_after_verification,
214 )
215 .finish()
216 }
217}