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 auto_sign_in_after_verification: bool,
112}
113
114impl EmailVerificationOptions {
115 pub fn new() -> Self {
116 Self::default()
117 }
118
119 pub fn builder() -> Self {
120 Self::new()
121 }
122
123 #[must_use]
124 pub fn send_verification_email<S>(mut self, sender: S) -> Self
125 where
126 S: SendVerificationEmail,
127 {
128 self.send_verification_email = Some(Arc::new(sender));
129 self
130 }
131
132 #[must_use]
133 pub fn before_email_verification<B>(mut self, callback: B) -> Self
134 where
135 B: BeforeEmailVerification,
136 {
137 self.before_email_verification = Some(Arc::new(callback));
138 self
139 }
140
141 #[must_use]
142 pub fn after_email_verification<A>(mut self, callback: A) -> Self
143 where
144 A: AfterEmailVerification,
145 {
146 self.after_email_verification = Some(Arc::new(callback));
147 self
148 }
149
150 #[must_use]
151 pub fn expires_in(mut self, expires_in: u64) -> Self {
152 self.expires_in = Some(expires_in);
153 self
154 }
155
156 #[must_use]
157 pub fn auto_sign_in_after_verification(mut self, enabled: bool) -> Self {
158 self.auto_sign_in_after_verification = enabled;
159 self
160 }
161}
162
163impl fmt::Debug for EmailVerificationOptions {
164 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
165 formatter
166 .debug_struct("EmailVerificationOptions")
167 .field(
168 "send_verification_email",
169 &self
170 .send_verification_email
171 .as_ref()
172 .map(|_| "<send-verification-email>"),
173 )
174 .field(
175 "before_email_verification",
176 &self
177 .before_email_verification
178 .as_ref()
179 .map(|_| "<before-email-verification>"),
180 )
181 .field(
182 "after_email_verification",
183 &self
184 .after_email_verification
185 .as_ref()
186 .map(|_| "<after-email-verification>"),
187 )
188 .field("expires_in", &self.expires_in)
189 .field(
190 "auto_sign_in_after_verification",
191 &self.auto_sign_in_after_verification,
192 )
193 .finish()
194 }
195}