tangled
alpha
login
or
join now
bad-example.com
/
microcosm-links
7
fork
atom
APIs for links and references in the ATmosphere
7
fork
atom
overview
issues
pulls
pipelines
refresh cookie + frame headers
bad-example.com
8 months ago
2e5e17ad
a9240e8e
+55
-31
1 changed file
expand all
collapse all
unified
split
who-am-i
src
server.rs
+55
-31
who-am-i/src/server.rs
···
4
extract::{FromRef, Query, State},
5
http::{
6
StatusCode,
7
-
header::{CONTENT_TYPE, HeaderMap, REFERER},
8
},
9
response::{IntoResponse, Json, Redirect, Response},
10
routing::get,
···
29
30
const DID_COOKIE_KEY: &str = "did";
31
0
0
32
type AppEngine = Engine<Handlebars<'static>>;
33
-
type Rendered = RenderHtml<&'static str, AppEngine, Value>;
34
35
#[derive(Clone)]
36
struct AppState {
···
96
.unwrap();
97
}
98
99
-
async fn hello(State(AppState { engine, .. }): State<AppState>) -> Rendered {
100
-
RenderHtml("hello", engine, json!({}))
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
101
}
102
103
async fn css() -> impl IntoResponse {
···
110
111
async fn favicon() -> impl IntoResponse {
112
([(CONTENT_TYPE, "image/x-icon")], FAVICON)
0
0
0
0
0
0
0
0
0
113
}
114
115
async fn prompt(
···
149
if parent_origin == "null" {
150
return err("Referer origin is opaque", true);
151
}
0
0
0
0
0
0
0
0
0
152
if let Some(did) = jar.get(DID_COOKIE_KEY) {
153
let Ok(did) = Did::new(did.value_trimmed().to_string()) else {
154
return err("Bad cookie", false);
155
};
156
0
0
0
157
let fetch_key = resolve_handles.dispatch(
158
{
159
let oauth = oauth.clone();
···
163
shutdown.child_token(),
164
);
165
166
-
RenderHtml(
167
-
"prompt",
168
-
engine,
169
-
json!({
170
-
"did": did,
171
-
"fetch_key": fetch_key,
172
-
"parent_host": parent_host,
173
-
"parent_origin": parent_origin,
174
-
}),
175
-
)
176
-
.into_response()
177
} else {
178
-
RenderHtml(
179
-
"prompt",
180
-
engine,
181
-
json!({
182
-
"parent_host": parent_host,
183
-
"parent_origin": parent_origin,
184
-
}),
185
-
)
186
-
.into_response()
187
}
188
}
189
···
316
}
317
};
318
319
-
let cookie = Cookie::build((DID_COOKIE_KEY, did.to_string()))
320
-
.http_only(true)
321
-
.secure(true)
322
-
.same_site(SameSite::None)
323
-
.max_age(std::time::Duration::from_secs(86_400).try_into().unwrap());
324
-
325
-
let jar = jar.add(cookie);
326
327
let fetch_key = resolve_handles.dispatch(
328
{
···
4
extract::{FromRef, Query, State},
5
http::{
6
StatusCode,
7
+
header::{CONTENT_SECURITY_POLICY, CONTENT_TYPE, HeaderMap, REFERER, X_FRAME_OPTIONS},
8
},
9
response::{IntoResponse, Json, Redirect, Response},
10
routing::get,
···
29
30
const DID_COOKIE_KEY: &str = "did";
31
32
+
const COOKIE_EXPIRATION: Duration = Duration::from_secs(30 * 86_400);
33
+
34
type AppEngine = Engine<Handlebars<'static>>;
0
35
36
#[derive(Clone)]
37
struct AppState {
···
97
.unwrap();
98
}
99
100
+
async fn hello(
101
+
State(AppState { engine, .. }): State<AppState>,
102
+
mut jar: SignedCookieJar,
103
+
) -> Response {
104
+
// push expiry (or clean up) the current cookie
105
+
if let Some(did) = jar.get(DID_COOKIE_KEY) {
106
+
if let Ok(did) = Did::new(did.value_trimmed().to_string()) {
107
+
jar = jar.add(cookie(&did));
108
+
} else {
109
+
jar = jar.remove(DID_COOKIE_KEY);
110
+
}
111
+
}
112
+
let frame_headers = [
113
+
(X_FRAME_OPTIONS, "deny"),
114
+
(CONTENT_SECURITY_POLICY, "frame-ancestors 'none'"),
115
+
];
116
+
(frame_headers, jar, RenderHtml("hello", engine, json!({}))).into_response()
117
}
118
119
async fn css() -> impl IntoResponse {
···
126
127
async fn favicon() -> impl IntoResponse {
128
([(CONTENT_TYPE, "image/x-icon")], FAVICON)
129
+
}
130
+
131
+
fn cookie(did: &Did) -> Cookie<'static> {
132
+
Cookie::build((DID_COOKIE_KEY, did.to_string()))
133
+
.http_only(true)
134
+
.secure(true)
135
+
.same_site(SameSite::None)
136
+
.max_age(COOKIE_EXPIRATION.try_into().unwrap())
137
+
.into()
138
}
139
140
async fn prompt(
···
174
if parent_origin == "null" {
175
return err("Referer origin is opaque", true);
176
}
177
+
178
+
let frame_headers = [
179
+
(X_FRAME_OPTIONS, format!("allow-from {parent_origin}")),
180
+
(
181
+
CONTENT_SECURITY_POLICY,
182
+
format!("frame-ancestors {parent_host}"),
183
+
),
184
+
];
185
+
186
if let Some(did) = jar.get(DID_COOKIE_KEY) {
187
let Ok(did) = Did::new(did.value_trimmed().to_string()) else {
188
return err("Bad cookie", false);
189
};
190
191
+
// push cookie expiry
192
+
let jar = jar.add(cookie(&did));
193
+
194
let fetch_key = resolve_handles.dispatch(
195
{
196
let oauth = oauth.clone();
···
200
shutdown.child_token(),
201
);
202
203
+
let info = json!({
204
+
"did": did,
205
+
"fetch_key": fetch_key,
206
+
"parent_host": parent_host,
207
+
"parent_origin": parent_origin,
208
+
});
209
+
210
+
(frame_headers, jar, RenderHtml("prompt", engine, info)).into_response()
0
0
0
211
} else {
212
+
let info = json!({
213
+
"parent_host": parent_host,
214
+
"parent_origin": parent_origin,
215
+
});
216
+
(frame_headers, RenderHtml("prompt", engine, info)).into_response()
0
0
0
0
217
}
218
}
219
···
346
}
347
};
348
349
+
let jar = jar.add(cookie(&did));
0
0
0
0
0
0
350
351
let fetch_key = resolve_handles.dispatch(
352
{