Constellation, Spacedust, Slingshot, UFOs: atproto crates and services for microcosm

refresh cookie + frame headers

Changed files
+55 -31
who-am-i
src
+55 -31
who-am-i/src/server.rs
···
extract::{FromRef, Query, State},
http::{
StatusCode,
-
header::{CONTENT_TYPE, HeaderMap, REFERER},
+
header::{CONTENT_SECURITY_POLICY, CONTENT_TYPE, HeaderMap, REFERER, X_FRAME_OPTIONS},
},
response::{IntoResponse, Json, Redirect, Response},
routing::get,
···
const DID_COOKIE_KEY: &str = "did";
+
const COOKIE_EXPIRATION: Duration = Duration::from_secs(30 * 86_400);
+
type AppEngine = Engine<Handlebars<'static>>;
-
type Rendered = RenderHtml<&'static str, AppEngine, Value>;
#[derive(Clone)]
struct AppState {
···
.unwrap();
}
-
async fn hello(State(AppState { engine, .. }): State<AppState>) -> Rendered {
-
RenderHtml("hello", engine, json!({}))
+
async fn hello(
+
State(AppState { engine, .. }): State<AppState>,
+
mut jar: SignedCookieJar,
+
) -> Response {
+
// push expiry (or clean up) the current cookie
+
if let Some(did) = jar.get(DID_COOKIE_KEY) {
+
if let Ok(did) = Did::new(did.value_trimmed().to_string()) {
+
jar = jar.add(cookie(&did));
+
} else {
+
jar = jar.remove(DID_COOKIE_KEY);
+
}
+
}
+
let frame_headers = [
+
(X_FRAME_OPTIONS, "deny"),
+
(CONTENT_SECURITY_POLICY, "frame-ancestors 'none'"),
+
];
+
(frame_headers, jar, RenderHtml("hello", engine, json!({}))).into_response()
}
async fn css() -> impl IntoResponse {
···
async fn favicon() -> impl IntoResponse {
([(CONTENT_TYPE, "image/x-icon")], FAVICON)
+
}
+
+
fn cookie(did: &Did) -> Cookie<'static> {
+
Cookie::build((DID_COOKIE_KEY, did.to_string()))
+
.http_only(true)
+
.secure(true)
+
.same_site(SameSite::None)
+
.max_age(COOKIE_EXPIRATION.try_into().unwrap())
+
.into()
}
async fn prompt(
···
if parent_origin == "null" {
return err("Referer origin is opaque", true);
}
+
+
let frame_headers = [
+
(X_FRAME_OPTIONS, format!("allow-from {parent_origin}")),
+
(
+
CONTENT_SECURITY_POLICY,
+
format!("frame-ancestors {parent_host}"),
+
),
+
];
+
if let Some(did) = jar.get(DID_COOKIE_KEY) {
let Ok(did) = Did::new(did.value_trimmed().to_string()) else {
return err("Bad cookie", false);
};
+
// push cookie expiry
+
let jar = jar.add(cookie(&did));
+
let fetch_key = resolve_handles.dispatch(
{
let oauth = oauth.clone();
···
shutdown.child_token(),
);
-
RenderHtml(
-
"prompt",
-
engine,
-
json!({
-
"did": did,
-
"fetch_key": fetch_key,
-
"parent_host": parent_host,
-
"parent_origin": parent_origin,
-
}),
-
)
-
.into_response()
+
let info = json!({
+
"did": did,
+
"fetch_key": fetch_key,
+
"parent_host": parent_host,
+
"parent_origin": parent_origin,
+
});
+
+
(frame_headers, jar, RenderHtml("prompt", engine, info)).into_response()
} else {
-
RenderHtml(
-
"prompt",
-
engine,
-
json!({
-
"parent_host": parent_host,
-
"parent_origin": parent_origin,
-
}),
-
)
-
.into_response()
+
let info = json!({
+
"parent_host": parent_host,
+
"parent_origin": parent_origin,
+
});
+
(frame_headers, RenderHtml("prompt", engine, info)).into_response()
}
}
···
}
};
-
let cookie = Cookie::build((DID_COOKIE_KEY, did.to_string()))
-
.http_only(true)
-
.secure(true)
-
.same_site(SameSite::None)
-
.max_age(std::time::Duration::from_secs(86_400).try_into().unwrap());
-
-
let jar = jar.add(cookie);
+
let jar = jar.add(cookie(&did));
let fetch_key = resolve_handles.dispatch(
{