rustauth_core/options/
advanced.rs1use std::future::Future;
2use std::pin::Pin;
3use std::sync::Arc;
4
5use time::Duration;
6
7use crate::utils::ip::Ipv6Subnet;
8
9use super::cookies::CookieConfig;
10
11pub type BackgroundTaskFuture = Pin<Box<dyn Future<Output = ()> + Send + 'static>>;
13
14pub trait BackgroundTaskRunner: Send + Sync + 'static {
15 fn spawn(&self, task: BackgroundTaskFuture);
16}
17
18#[derive(Clone, Default)]
19pub struct AdvancedOptions {
20 pub use_secure_cookies: Option<bool>,
21 pub cookie_prefix: Option<String>,
22 pub cross_subdomain_cookies: Option<CookieConfig>,
23 pub default_cookie_attributes: CookieAttributesOverride,
24 pub disable_csrf_check: bool,
25 pub disable_origin_check: bool,
26 pub skip_trailing_slashes: bool,
27 pub ip_address: IpAddressOptions,
28 pub background_tasks: Option<Arc<dyn BackgroundTaskRunner>>,
29 pub outbound_min_response_time: Option<Duration>,
30}
31
32impl AdvancedOptions {
33 pub fn new() -> Self {
34 Self::default()
35 }
36
37 pub fn builder() -> Self {
38 Self::new()
39 }
40
41 #[must_use]
42 pub fn use_secure_cookies(mut self, enabled: bool) -> Self {
43 self.use_secure_cookies = Some(enabled);
44 self
45 }
46
47 #[must_use]
48 pub fn cookie_prefix(mut self, prefix: impl Into<String>) -> Self {
49 self.cookie_prefix = Some(prefix.into());
50 self
51 }
52
53 #[must_use]
54 pub fn cross_subdomain_cookies(mut self, config: CookieConfig) -> Self {
55 self.cross_subdomain_cookies = Some(config);
56 self
57 }
58
59 #[must_use]
60 pub fn default_cookie_attributes(mut self, attributes: CookieAttributesOverride) -> Self {
61 self.default_cookie_attributes = attributes;
62 self
63 }
64
65 #[must_use]
66 pub fn disable_csrf_check(mut self, disabled: bool) -> Self {
67 self.disable_csrf_check = disabled;
68 self
69 }
70
71 #[must_use]
72 pub fn disable_origin_check(mut self, disabled: bool) -> Self {
73 self.disable_origin_check = disabled;
74 self
75 }
76
77 #[must_use]
78 pub fn skip_trailing_slashes(mut self, enabled: bool) -> Self {
79 self.skip_trailing_slashes = enabled;
80 self
81 }
82
83 #[must_use]
84 pub fn ip_address(mut self, ip_address: IpAddressOptions) -> Self {
85 self.ip_address = ip_address;
86 self
87 }
88
89 #[must_use]
90 pub fn background_tasks(mut self, runner: Arc<dyn BackgroundTaskRunner>) -> Self {
91 self.background_tasks = Some(runner);
92 self
93 }
94
95 #[must_use]
96 pub fn outbound_min_response_time(mut self, duration: Duration) -> Self {
97 self.outbound_min_response_time = Some(duration);
98 self
99 }
100}
101
102impl std::fmt::Debug for AdvancedOptions {
103 fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
104 formatter
105 .debug_struct("AdvancedOptions")
106 .field("use_secure_cookies", &self.use_secure_cookies)
107 .field("cookie_prefix", &self.cookie_prefix)
108 .field("cross_subdomain_cookies", &self.cross_subdomain_cookies)
109 .field("default_cookie_attributes", &self.default_cookie_attributes)
110 .field("disable_csrf_check", &self.disable_csrf_check)
111 .field("disable_origin_check", &self.disable_origin_check)
112 .field("skip_trailing_slashes", &self.skip_trailing_slashes)
113 .field("ip_address", &self.ip_address)
114 .field(
115 "background_tasks",
116 &self.background_tasks.as_ref().map(|_| "<background-tasks>"),
117 )
118 .field(
119 "outbound_min_response_time",
120 &self.outbound_min_response_time,
121 )
122 .finish()
123 }
124}
125
126#[derive(Debug, Clone, PartialEq, Eq)]
127pub struct IpAddressOptions {
128 pub headers: Vec<String>,
129 pub disable_ip_tracking: bool,
130 pub ipv6_subnet: Ipv6Subnet,
131}
132
133impl Default for IpAddressOptions {
134 fn default() -> Self {
135 Self {
136 headers: Vec::new(),
137 disable_ip_tracking: false,
138 ipv6_subnet: Ipv6Subnet::Prefix64,
139 }
140 }
141}
142
143impl IpAddressOptions {
144 pub fn new() -> Self {
145 Self::default()
146 }
147
148 pub fn builder() -> Self {
149 Self::new()
150 }
151
152 #[must_use]
153 pub fn header(mut self, header: impl Into<String>) -> Self {
154 self.headers.push(header.into());
155 self
156 }
157
158 #[must_use]
159 pub fn headers<I, S>(mut self, headers: I) -> Self
160 where
161 I: IntoIterator<Item = S>,
162 S: Into<String>,
163 {
164 self.headers = headers.into_iter().map(Into::into).collect();
165 self
166 }
167
168 #[must_use]
169 pub fn disable_ip_tracking(mut self, disabled: bool) -> Self {
170 self.disable_ip_tracking = disabled;
171 self
172 }
173
174 #[must_use]
175 pub fn ipv6_subnet(mut self, subnet: Ipv6Subnet) -> Self {
176 self.ipv6_subnet = subnet;
177 self
178 }
179}
180
181#[derive(Debug, Clone, Default, PartialEq, Eq)]
183pub struct CookieAttributesOverride {
184 pub domain: Option<String>,
185 pub path: Option<String>,
186 pub secure: Option<bool>,
187 pub http_only: Option<bool>,
188 pub same_site: Option<String>,
189 pub max_age: Option<Duration>,
190 pub partitioned: Option<bool>,
191}
192
193impl CookieAttributesOverride {
194 pub fn new() -> Self {
195 Self::default()
196 }
197
198 pub fn builder() -> Self {
199 Self::new()
200 }
201
202 #[must_use]
203 pub fn domain(mut self, domain: impl Into<String>) -> Self {
204 self.domain = Some(domain.into());
205 self
206 }
207
208 #[must_use]
209 pub fn path(mut self, path: impl Into<String>) -> Self {
210 self.path = Some(path.into());
211 self
212 }
213
214 #[must_use]
215 pub fn secure(mut self, secure: bool) -> Self {
216 self.secure = Some(secure);
217 self
218 }
219
220 #[must_use]
221 pub fn http_only(mut self, http_only: bool) -> Self {
222 self.http_only = Some(http_only);
223 self
224 }
225
226 #[must_use]
227 pub fn same_site(mut self, same_site: impl Into<String>) -> Self {
228 self.same_site = Some(same_site.into());
229 self
230 }
231
232 #[must_use]
233 pub fn max_age(mut self, max_age: Duration) -> Self {
234 self.max_age = Some(max_age);
235 self
236 }
237
238 #[must_use]
239 pub fn partitioned(mut self, partitioned: bool) -> Self {
240 self.partitioned = Some(partitioned);
241 self
242 }
243}