oauth2_passkey/config.rs
1//! Central configuration for the oauth2_passkey crate
2
3use std::sync::LazyLock;
4
5/// Route prefix for all oauth2_passkey endpoints
6///
7/// This is the main prefix under which all authentication endpoints will be mounted.
8/// Default: "/o2p"
9pub static O2P_ROUTE_PREFIX: LazyLock<String> =
10 LazyLock::new(|| std::env::var("O2P_ROUTE_PREFIX").unwrap_or_else(|_| "/o2p".to_string()));
11
12/// Signal API mode for credential synchronization with authenticators.
13///
14/// Controls which WebAuthn Signal APIs are called for credential deletion and login sync:
15/// - `"direct"`: Use `signalUnknownCredential` only (default, currently the only working API
16/// with Google Password Manager)
17/// - `"sync"`: Use `signalAllAcceptedCredentials` only (currently no effect on Chrome,
18/// may work with other authenticators)
19/// - `"direct+sync"`: Use both APIs for maximum compatibility
20///
21/// Default: "direct"
22pub static PASSKEY_SIGNAL_API_MODE: LazyLock<String> = LazyLock::new(|| {
23 let mode = std::env::var("PASSKEY_SIGNAL_API_MODE").unwrap_or_else(|_| "direct".to_string());
24 let valid_modes = ["direct", "sync", "direct+sync"];
25 if !valid_modes.contains(&mode.as_str()) {
26 tracing::warn!(
27 "Invalid PASSKEY_SIGNAL_API_MODE '{}', valid values are: {:?}. Using 'direct'.",
28 mode,
29 valid_modes
30 );
31 "direct".to_string()
32 } else {
33 mode
34 }
35});
36
37/// Demo mode flag for public demo sites
38///
39/// When enabled (`O2P_DEMO_MODE=true`):
40/// - All new users are created with admin privileges by default
41/// - Admin views mask other users' sensitive data (emails, IPs, credentials)
42/// - A placeholder user with sequence_number=1 is created at init, so all
43/// real users start from sequence_number=2 (no first-user special treatment)
44///
45/// This is a single toggle that activates all demo-specific behavior,
46/// preventing accidental misconfiguration (e.g., granting admin to all
47/// users without also enabling data masking).
48///
49/// Default: false
50pub static O2P_DEMO_MODE: LazyLock<bool> = LazyLock::new(|| {
51 std::env::var("O2P_DEMO_MODE")
52 .map(|val| val.to_lowercase() == "true")
53 .unwrap_or(false)
54});
55
56/// User ID for the demo mode placeholder user (sequence_number=1)
57///
58/// This placeholder occupies sequence_number=1 so that no real user gets
59/// the first-user special protections (immutable admin, undeletable).
60/// It is filtered from admin views and has no credentials or sessions.
61pub const DEMO_PLACEHOLDER_USER_ID: &str = "__demo_placeholder__";
62
63#[cfg(test)]
64mod tests;