better_auth_core/session/
response.rs1use super::SessionManager;
2use crate::{AuthRequest, AuthResponse, AuthResult, AuthSchema};
3
4impl<S: AuthSchema> SessionManager<S> {
5 pub fn finish_response(
7 &self,
8 req: &AuthRequest,
9 response: &mut AuthResponse,
10 ) -> AuthResult<()> {
11 let endpoint_headers = std::mem::take(&mut response.headers);
12 response.headers = req.take_response_headers()?;
13 response.headers.merge(endpoint_headers);
14 let session_cookie = response
15 .headers
16 .get_all("set-cookie")
17 .filter_map(|value| cookie::Cookie::parse(value.as_str()).ok())
18 .filter(|cookie| {
19 cookie.name()
20 == self
21 .config
22 .auth_cookie("session_token", Default::default())
23 .name
24 })
25 .last()
26 .filter(|cookie| {
27 !cookie.value().is_empty()
28 && cookie.max_age().is_none_or(|age| age.whole_seconds() != 0)
29 })
30 .map(|cookie| cookie.value().to_string());
31 if let Some(signed_token) = session_cookie
32 && self.config.session.bearer.is_some()
33 {
34 let signed_token = percent_encoding::percent_decode_str(&signed_token)
35 .decode_utf8()
36 .map_err(|error| {
37 crate::AuthError::internal(format!("Decoding session cookie: {error}"))
38 })?;
39 let _ = response
40 .headers
41 .insert("set-auth-token", signed_token.into_owned());
42 let mut exposed: Vec<_> = response
43 .headers
44 .get("access-control-expose-headers")
45 .map(|header| {
46 header
47 .split(',')
48 .map(str::trim)
49 .filter(|value| !value.is_empty())
50 .map(str::to_string)
51 .collect()
52 })
53 .unwrap_or_default();
54 if !exposed
55 .iter()
56 .any(|name| name.eq_ignore_ascii_case("set-auth-token"))
57 {
58 exposed.push("set-auth-token".into());
59 }
60 let _ = response
61 .headers
62 .insert("access-control-expose-headers", exposed.join(", "));
63 }
64 if req.path().ends_with("/get-session") {
65 let _ = response.headers.insert("Cache-Control", "no-store");
66 let _ = response.headers.insert("Pragma", "no-cache");
67 }
68 Ok(())
69 }
70}