tide_flash/
cookies.rs

1use http_types::cookies::SameSite;
2use tide::http::cookies::Cookie;
3
4use crate::{Flash, FlashMessage, FlashStore};
5
6#[derive(Debug)]
7pub struct CookieConfig {
8    pub max_age: time::Duration,
9    pub site: SameSite,
10    pub http_only: bool,
11    pub path: String,
12}
13
14impl Default for CookieConfig {
15    fn default() -> Self {
16        Self {
17            max_age: time::Duration::seconds(60),
18            site: SameSite::Lax,
19            http_only: true,
20            path: String::from("/"),
21        }
22    }
23}
24
25#[derive(Debug)]
26pub struct CookieStore {
27    pub config: CookieConfig,
28}
29
30impl Default for CookieStore {
31    fn default() -> Self {
32        Self {
33            config: CookieConfig::default(),
34        }
35    }
36}
37
38impl FlashStore for CookieStore {
39    fn load<State>(&self, req: &tide::Request<State>) -> Option<Vec<FlashMessage>> {
40        match req.cookie("_flash") {
41            None => None,
42            Some(cookie) => {
43                let messages: Vec<FlashMessage> =
44                    serde_json::from_str(cookie.value()).unwrap_or_default();
45                Some(messages)
46            }
47        }
48    }
49
50    fn insert(&self, res: &mut tide::Response) {
51        if let Some(flash) = res.ext::<Flash>() {
52            res.insert_cookie(
53                Cookie::build(
54                    "_flash",
55                    serde_json::to_string(&flash.messages).unwrap_or_default(),
56                )
57                .max_age(self.config.max_age)
58                .same_site(self.config.site)
59                .http_only(self.config.http_only)
60                .path(self.config.path.clone())
61                .finish(),
62            );
63        }
64    }
65
66    fn clear(&self, res: &mut tide::Response) {
67        res.insert_cookie(
68            Cookie::build("_flash", "")
69                .max_age(time::Duration::seconds(0))
70                .same_site(self.config.site)
71                .http_only(self.config.http_only)
72                .path(self.config.path.clone())
73                .finish(),
74        );
75    }
76}