advance 1-8 post-mvp execution batches
This commit is contained in:
@@ -4,9 +4,13 @@ use axum::extract::{Extension, State};
|
||||
use axum::http::{HeaderMap, HeaderName, HeaderValue, StatusCode};
|
||||
use axum::response::{IntoResponse, Response};
|
||||
use axum::Json;
|
||||
use base64::{engine::general_purpose::URL_SAFE_NO_PAD, Engine as _};
|
||||
use serde::Serialize;
|
||||
|
||||
const HEADER_MNOTE_WEB_OWNER: &str = "x-mnote-web-owner";
|
||||
const COOKIE_CONVEX_AUTH_JWT: &str = "__convexAuthJWT";
|
||||
const COOKIE_ACTOR_EMAIL: &str = "mnote_actor_email";
|
||||
const COOKIE_ACTOR_NAME: &str = "mnote_actor_name";
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
@@ -63,6 +67,18 @@ pub async fn refresh_session(
|
||||
fn build_session_response(state: &AppState, context: RequestContext) -> SessionResponse {
|
||||
let actor_id = context.auth.actor_id.trim();
|
||||
let has_forwarded_actor = !actor_id.is_empty() && actor_id != "anonymous";
|
||||
let actor_email = context
|
||||
.auth
|
||||
.cookie_header
|
||||
.as_deref()
|
||||
.and_then(|cookies| encoded_cookie_value(cookies, COOKIE_ACTOR_EMAIL))
|
||||
.or_else(|| jwt_cookie_claim(&context, &["email", "preferred_username"]));
|
||||
let actor_name = context
|
||||
.auth
|
||||
.cookie_header
|
||||
.as_deref()
|
||||
.and_then(|cookies| encoded_cookie_value(cookies, COOKIE_ACTOR_NAME))
|
||||
.or_else(|| jwt_cookie_claim(&context, &["name", "username"]));
|
||||
let user_id = if has_forwarded_actor {
|
||||
actor_id.to_string()
|
||||
} else {
|
||||
@@ -79,12 +95,12 @@ fn build_session_response(state: &AppState, context: RequestContext) -> SessionR
|
||||
owner: "mnote-web",
|
||||
user_id,
|
||||
email: if has_forwarded_actor {
|
||||
String::new()
|
||||
actor_email.unwrap_or_default()
|
||||
} else {
|
||||
state.config().dev_user_email.clone()
|
||||
},
|
||||
name: if has_forwarded_actor {
|
||||
actor_id.to_string()
|
||||
actor_name.unwrap_or_else(|| actor_id.to_string())
|
||||
} else {
|
||||
state.config().dev_user_name.clone()
|
||||
},
|
||||
@@ -99,6 +115,50 @@ fn build_session_response(state: &AppState, context: RequestContext) -> SessionR
|
||||
}
|
||||
}
|
||||
|
||||
fn jwt_cookie_claim(context: &RequestContext, keys: &[&str]) -> Option<String> {
|
||||
let token = context
|
||||
.auth
|
||||
.cookie_header
|
||||
.as_deref()
|
||||
.and_then(|cookies| raw_cookie_value(cookies, COOKIE_CONVEX_AUTH_JWT))?;
|
||||
let payload_segment = token.split('.').nth(1)?;
|
||||
let decoded = URL_SAFE_NO_PAD.decode(payload_segment.as_bytes()).ok()?;
|
||||
let payload: serde_json::Value = serde_json::from_slice(&decoded).ok()?;
|
||||
keys.iter().find_map(|key| {
|
||||
payload
|
||||
.get(key)
|
||||
.and_then(serde_json::Value::as_str)
|
||||
.map(str::trim)
|
||||
.filter(|value| !value.is_empty())
|
||||
.map(ToOwned::to_owned)
|
||||
})
|
||||
}
|
||||
|
||||
fn encoded_cookie_value(cookie_header: &str, name: &str) -> Option<String> {
|
||||
let encoded = raw_cookie_value(cookie_header, name)?;
|
||||
let decoded = URL_SAFE_NO_PAD.decode(encoded.as_bytes()).ok()?;
|
||||
String::from_utf8(decoded)
|
||||
.ok()
|
||||
.map(|value| value.trim().to_string())
|
||||
.filter(|value| !value.is_empty())
|
||||
}
|
||||
|
||||
fn raw_cookie_value(cookie_header: &str, name: &str) -> Option<String> {
|
||||
cookie_header.split(';').find_map(|part| {
|
||||
let (cookie_name, cookie_value) = part.trim().split_once('=')?;
|
||||
if cookie_name.trim() == name {
|
||||
let value = cookie_value.trim();
|
||||
if value.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(value.to_string())
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn owner_json<T>(payload: Json<T>) -> Response
|
||||
where
|
||||
T: Serialize,
|
||||
|
||||
Reference in New Issue
Block a user