1use time::Duration;
2
3#[derive(Debug, Clone)]
5pub struct AuthConfig {
6 pub secret: String,
8 pub session_ttl: Duration,
10 pub verification_ttl: Duration,
12 pub reset_ttl: Duration,
14 pub token_length: usize,
16 pub email: EmailConfig,
18 pub cookie: CookieConfig,
20 pub oauth: OAuthConfig,
22}
23
24#[derive(Debug, Clone)]
26pub struct EmailConfig {
27 pub send_verification_on_signup: bool,
29 pub require_verification_to_login: bool,
31 pub auto_sign_in_after_signup: bool,
33 pub auto_sign_in_after_verification: bool,
35}
36
37#[derive(Debug, Clone)]
39pub struct CookieConfig {
40 pub name: String,
42 pub http_only: bool,
44 pub secure: bool,
46 pub same_site: SameSite,
48 pub path: String,
50 pub domain: Option<String>,
52}
53
54#[derive(Debug, Clone, Copy, PartialEq, Eq)]
56pub enum SameSite {
57 Strict,
59 Lax,
61 None,
63}
64
65#[derive(Debug, Clone)]
67pub struct OAuthConfig {
68 pub providers: Vec<OAuthProviderEntry>,
70 pub allow_implicit_account_linking: bool,
72 pub success_redirect: Option<String>,
74 pub error_redirect: Option<String>,
76}
77
78#[derive(Debug, Clone)]
80pub struct OAuthProviderEntry {
81 pub provider_id: String,
83 pub client_id: String,
85 pub client_secret: String,
87 pub redirect_url: String,
89 pub auth_url: Option<String>,
91 pub token_url: Option<String>,
93 pub userinfo_url: Option<String>,
95}
96
97impl Default for OAuthConfig {
98 fn default() -> Self {
99 Self {
100 providers: vec![],
101 allow_implicit_account_linking: true,
102 success_redirect: None,
103 error_redirect: None,
104 }
105 }
106}
107
108impl Default for AuthConfig {
109 fn default() -> Self {
110 Self {
111 secret: String::new(),
112 session_ttl: Duration::days(30),
113 verification_ttl: Duration::hours(1),
114 reset_ttl: Duration::hours(1),
115 token_length: 32,
116 email: EmailConfig::default(),
117 cookie: CookieConfig::default(),
118 oauth: OAuthConfig::default(),
119 }
120 }
121}
122
123impl Default for EmailConfig {
124 fn default() -> Self {
125 Self {
126 send_verification_on_signup: true,
127 require_verification_to_login: false,
128 auto_sign_in_after_signup: true,
129 auto_sign_in_after_verification: false,
130 }
131 }
132}
133
134impl Default for CookieConfig {
135 fn default() -> Self {
136 Self {
137 name: "rs_auth_session".to_string(),
138 http_only: true,
139 secure: true,
140 same_site: SameSite::Lax,
141 path: "/".to_string(),
142 domain: None,
143 }
144 }
145}
146
147#[cfg(test)]
148mod tests {
149 use super::*;
150
151 #[test]
152 fn default_config_has_sane_values() {
153 let config = AuthConfig::default();
154
155 assert_eq!(
156 config.session_ttl,
157 Duration::days(30),
158 "session_ttl should be 30 days"
159 );
160 assert_eq!(config.token_length, 32, "token_length should be 32");
161 assert_eq!(
162 config.cookie.name, "rs_auth_session",
163 "cookie name should be 'rs_auth_session'"
164 );
165 assert_eq!(
166 config.verification_ttl,
167 Duration::hours(1),
168 "verification_ttl should be 1 hour"
169 );
170 assert_eq!(
171 config.reset_ttl,
172 Duration::hours(1),
173 "reset_ttl should be 1 hour"
174 );
175 assert!(config.cookie.http_only, "cookie should be http_only");
176 assert!(config.cookie.secure, "cookie should be secure");
177 assert_eq!(
178 config.cookie.same_site,
179 SameSite::Lax,
180 "cookie same_site should be Lax"
181 );
182 assert_eq!(config.cookie.path, "/", "cookie path should be '/'");
183 assert_eq!(config.cookie.domain, None, "cookie domain should be None");
184 }
185}