Skip to main content

openauth_plugins/last_login_method/
config.rs

1use std::sync::Arc;
2
3use super::resolve::LoginMethodContext;
4
5pub const DEFAULT_COOKIE_NAME: &str = "better-auth.last_used_login_method";
6pub const DEFAULT_COOKIE_MAX_AGE: u64 = 60 * 60 * 24 * 30;
7pub const DEFAULT_DATABASE_FIELD_NAME: &str = "last_login_method";
8
9type LoginMethodResolver =
10    Arc<dyn Fn(&LoginMethodContext) -> Option<String> + Send + Sync + 'static>;
11
12/// Configuration for tracking the most recent successful login method.
13#[derive(Clone, Default)]
14pub struct LastLoginMethodOptions {
15    pub cookie_name: Option<String>,
16    pub max_age: Option<u64>,
17    pub resolver: Option<LoginMethodResolver>,
18    pub store_in_database: bool,
19    pub database_field_name: Option<String>,
20}
21
22impl LastLoginMethodOptions {
23    pub fn cookie_name(mut self, cookie_name: impl Into<String>) -> Self {
24        self.cookie_name = Some(cookie_name.into());
25        self
26    }
27
28    pub fn max_age(mut self, max_age: u64) -> Self {
29        self.max_age = Some(max_age);
30        self
31    }
32
33    pub fn with_resolver<F>(mut self, resolver: F) -> Self
34    where
35        F: Fn(&LoginMethodContext) -> Option<String> + Send + Sync + 'static,
36    {
37        self.resolver = Some(Arc::new(resolver));
38        self
39    }
40
41    pub fn store_in_database(mut self, store_in_database: bool) -> Self {
42        self.store_in_database = store_in_database;
43        self
44    }
45
46    pub fn database_field_name(mut self, field_name: impl Into<String>) -> Self {
47        self.database_field_name = Some(field_name.into());
48        self
49    }
50
51    pub fn effective_cookie_name(&self) -> &str {
52        self.cookie_name.as_deref().unwrap_or(DEFAULT_COOKIE_NAME)
53    }
54
55    pub fn effective_max_age(&self) -> u64 {
56        self.max_age.unwrap_or(DEFAULT_COOKIE_MAX_AGE)
57    }
58
59    pub fn effective_database_field_name(&self) -> &str {
60        self.database_field_name
61            .as_deref()
62            .unwrap_or(DEFAULT_DATABASE_FIELD_NAME)
63    }
64
65    pub fn resolve_login_method(&self, context: &LoginMethodContext) -> Option<String> {
66        self.resolver
67            .as_ref()
68            .and_then(|resolver| resolver(context))
69            .or_else(|| super::resolve::default_login_method(context))
70    }
71}