better_auth_core/config/account.rs
1use super::*;
2/// Account-level configuration: linking, token encryption, sign-in behavior.
3#[derive(Debug, Clone)]
4#[expect(
5 clippy::struct_excessive_bools,
6 reason = "Independent configuration switches model distinct upstream behavior, rather than mutually exclusive states"
7)]
8pub struct AccountConfig {
9 pub additional_fields: crate::field_policy::FieldConfigs,
10 /// Update OAuth tokens on every sign-in (default: true)
11 pub update_account_on_sign_in: bool,
12 /// Account linking settings
13 pub account_linking: AccountLinkingConfig,
14 /// Encrypt OAuth tokens at rest (default: false)
15 pub encrypt_oauth_tokens: bool,
16 /// Store account data in an account cookie for OAuth-backed access token flows.
17 pub store_account_cookie: bool,
18 /// Override the account cookie lifetime in seconds, including fractional
19 /// and nonfinite values. Equivalent to the published account_data cookie's
20 /// maxAge attribute; takes precedence over the integer advanced override.
21 /// None inherits the session cache lifetime (or 300 seconds).
22 pub cookie_max_age: Option<f64>,
23 /// Where to persist OAuth state during the authorization flow. Automatic
24 /// selects database state with a server store, cookie state without one.
25 pub store_state_strategy: OAuthStateStrategy,
26 /// Skip state-cookie verification during callback processing.
27 ///
28 /// This is security-sensitive and should stay disabled in normal use.
29 pub skip_state_cookie_check: bool,
30}
31
32/// Settings that control how OAuth accounts are linked to existing users.
33#[derive(Debug, Clone)]
34#[expect(
35 clippy::struct_excessive_bools,
36 reason = "Independent configuration switches model distinct upstream behavior, rather than mutually exclusive states"
37)]
38pub struct AccountLinkingConfig {
39 /// Enable account linking (default: true)
40 pub enabled: bool,
41 /// Providers trusted for linking even when their email is unverified.
42 /// Empty does not bypass the provider email-verification requirement.
43 pub trusted_providers: Vec<String>,
44 /// Optional async policy replacing the static list at init and per request.
45 pub trusted_providers_resolver: Option<std::sync::Arc<dyn TrustedProvidersResolver>>,
46 /// Allow linking accounts with different emails (default: false) - SECURITY WARNING
47 pub allow_different_emails: bool,
48 /// Allow unlinking all accounts (default: false)
49 pub allow_unlinking_all: bool,
50 /// Disable implicit linking during sign-in; only explicit link-social may link.
51 pub disable_implicit_linking: bool,
52 /// Require the *existing local* account's email to be verified before a
53 /// social account may be linked to it implicitly (default: true).
54 pub require_local_email_verified: bool,
55 /// Update user info when a new account is linked (default: false)
56 pub update_user_info_on_link: bool,
57}
58
59/// Strategy for persisting OAuth state between the sign-in and callback steps.
60#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
61pub enum OAuthStateStrategy {
62 /// Select the deployment default during builder initialization. Initialized
63 /// contexts never retain this variant. Low-level uninitialized contexts
64 /// keep the historical database fallback for compatibility.
65 #[default]
66 Automatic,
67 /// Persist state in an encrypted cookie.
68 Cookie,
69 /// Persist state in the verification store plus a signed state cookie.
70 Database,
71}
72
73impl Default for AccountConfig {
74 fn default() -> Self {
75 Self {
76 additional_fields: crate::field_policy::FieldConfigs::new(),
77 update_account_on_sign_in: true,
78 account_linking: AccountLinkingConfig::default(),
79 encrypt_oauth_tokens: false,
80 store_account_cookie: false,
81 cookie_max_age: None,
82 store_state_strategy: OAuthStateStrategy::Automatic,
83 skip_state_cookie_check: false,
84 }
85 }
86}
87
88impl Default for AccountLinkingConfig {
89 fn default() -> Self {
90 Self {
91 enabled: true,
92 trusted_providers: Vec::new(),
93 trusted_providers_resolver: None,
94 allow_different_emails: false,
95 allow_unlinking_all: false,
96 disable_implicit_linking: false,
97 require_local_email_verified: true,
98 update_user_info_on_link: false,
99 }
100 }
101}