use tako_rs_core::types::Request;
#[derive(Clone, Copy, Debug)]
pub enum SameSite {
Strict,
Lax,
None,
}
impl SameSite {
fn as_str(self) -> &'static str {
match self {
SameSite::Strict => "Strict",
SameSite::Lax => "Lax",
SameSite::None => "None",
}
}
}
pub(crate) fn generate_session_id() -> String {
uuid::Uuid::new_v4().simple().to_string()
}
pub(crate) fn extract_cookie_value<'a>(req: &'a Request, cookie_name: &str) -> Option<&'a str> {
req
.headers()
.get(http::header::COOKIE)
.and_then(|v| v.to_str().ok())
.and_then(|cookies| {
cookies.split(';').find_map(|pair| {
let pair = pair.trim();
let (name, value) = pair.split_once('=')?;
if name.trim() == cookie_name {
Some(value.trim())
} else {
None
}
})
})
}
#[allow(clippy::too_many_arguments)]
pub(crate) fn build_cookie(
cookie_name: &str,
sid: &str,
path: &str,
domain: Option<&str>,
ttl_secs: u64,
secure: bool,
http_only: bool,
same_site: SameSite,
) -> String {
let mut s = format!("{cookie_name}={sid}; Path={path}");
if let Some(d) = domain {
s.push_str("; Domain=");
s.push_str(d);
}
s.push_str(&format!("; Max-Age={ttl_secs}"));
if http_only {
s.push_str("; HttpOnly");
}
if secure {
s.push_str("; Secure");
}
s.push_str("; SameSite=");
s.push_str(same_site.as_str());
s
}
pub(crate) fn build_expired_cookie(
cookie_name: &str,
path: &str,
domain: Option<&str>,
secure: bool,
http_only: bool,
same_site: SameSite,
) -> String {
let mut s = format!("{cookie_name}=; Path={path}");
if let Some(d) = domain {
s.push_str("; Domain=");
s.push_str(d);
}
s.push_str("; Max-Age=0; Expires=Thu, 01 Jan 1970 00:00:00 GMT");
if http_only {
s.push_str("; HttpOnly");
}
if secure {
s.push_str("; Secure");
}
s.push_str("; SameSite=");
s.push_str(same_site.as_str());
s
}