rustauth_plugins/email_otp/
mod.rs1mod change_email;
4mod endpoints;
5mod errors;
6mod helpers;
7mod hooks;
8mod otp;
9mod password;
10mod registry;
11mod response;
12mod schema;
13mod server;
14mod types;
15
16pub use types::{
17 ChangeEmailOptions, EmailOtpEncryptor, EmailOtpGenerator, EmailOtpHasher, EmailOtpOptions,
18 EmailOtpOptionsBuilder, EmailOtpPayload, EmailOtpType, OtpStorage, ResendStrategy,
19 SendEmailOtp,
20};
21
22use rustauth_core::error::RustAuthError;
23use rustauth_core::options::RateLimitRule;
24use rustauth_core::plugin::{AuthPlugin, PluginRateLimitRule};
25
26pub const UPSTREAM_PLUGIN_ID: &str = "email-otp";
27
28pub fn email_otp(options: EmailOtpOptions) -> Result<AuthPlugin, RustAuthError> {
30 options.validate()?;
31 Ok(build_email_otp_plugin(options))
32}
33
34fn build_email_otp_plugin(options: EmailOtpOptions) -> AuthPlugin {
35 let rate_limit = options.rate_limit.clone().unwrap_or(RateLimitRule {
36 window: time::Duration::seconds(60),
37 max: 3,
38 });
39 let hook_options = std::sync::Arc::new(options.clone());
40 let plugin = errors::error_codes().fold(
41 registry::register(
42 AuthPlugin::new(UPSTREAM_PLUGIN_ID).with_version(crate::VERSION),
43 options,
44 ),
45 AuthPlugin::with_error_code,
46 );
47 let plugin = if hook_options.send_verification_on_sign_up
48 && !hook_options.override_default_email_verification
49 {
50 plugin.with_async_after_hook("/sign-up/email", {
51 let options = std::sync::Arc::clone(&hook_options);
52 move |context, request, response| {
53 let options = std::sync::Arc::clone(&options);
54 Box::pin(async move {
55 hooks::send_verification_after_sign_up(context, request, response, options)
56 .await
57 })
58 }
59 })
60 } else {
61 plugin
62 };
63 let plugin = if hook_options.override_default_email_verification {
64 plugin.with_async_after_hook("/send-verification-email", {
65 let options = std::sync::Arc::clone(&hook_options);
66 move |context, request, response| {
67 let options = std::sync::Arc::clone(&options);
68 Box::pin(async move {
69 hooks::override_send_verification_email(context, request, response, options)
70 .await
71 })
72 }
73 })
74 } else {
75 plugin
76 };
77 registry::paths()
78 .iter()
79 .fold(plugin, |plugin: AuthPlugin, path| {
80 plugin.with_rate_limit(PluginRateLimitRule::new(*path, rate_limit.clone()))
81 })
82}