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