Implement outbox for profile lookup

This commit is contained in:
Jon Staab
2026-02-26 16:27:07 -08:00
parent a2be0b9a79
commit a15372d402
11 changed files with 163 additions and 41 deletions
+22 -1
View File
@@ -35,6 +35,7 @@ pub fn router(state: AppState) -> Router {
.route("/tenant/billing", put(update_tenant_billing));
let admin_routes = Router::new()
.route("/admin/check", get(admin_check))
.route("/admin/tenants", get(admin_list_tenants))
.route(
"/admin/tenants/:pubkey",
@@ -108,7 +109,7 @@ fn extract_auth_pubkey(headers: &HeaderMap, method: &Method, uri: &Uri) -> Resul
let path = uri.path_and_query().map(|v| v.as_str()).unwrap_or(uri.path());
let url = format!("{}://{}{}", scheme, host, path);
let pubkey = verify_nip98(auth_header, &url, method.as_str())?;
Ok(pubkey.to_string())
Ok(pubkey.to_hex())
}
async fn get_tenant(
@@ -396,6 +397,26 @@ async fn admin_list_tenants(
}
}
#[derive(Debug, Serialize)]
struct AdminCheckResponse {
is_admin: bool,
}
async fn admin_check(
State(state): State<AppState>,
headers: HeaderMap,
method: Method,
uri: Uri,
) -> Response {
let pubkey = match extract_auth_pubkey(&headers, &method, &uri) {
Ok(pubkey) => pubkey,
Err(_) => return unauthorized(),
};
let is_admin = state.admin_pubkeys.contains(&pubkey);
(StatusCode::OK, Json(AdminCheckResponse { is_admin })).into_response()
}
async fn admin_get_tenant(
State(state): State<AppState>,
headers: HeaderMap,
+16 -1
View File
@@ -1,5 +1,8 @@
use std::env;
use std::path::Path;
use std::str::FromStr;
use nostr_sdk::nostr::key::PublicKey;
#[derive(Debug, Clone)]
pub struct Config {
@@ -31,7 +34,7 @@ impl Config {
let admin_pubkeys = env::var("PLATFORM_ADMIN_PUBKEYS")
.unwrap_or_default()
.split(',')
.map(|v| v.trim().to_string())
.filter_map(normalize_pubkey)
.filter(|v| !v.is_empty())
.collect::<Vec<_>>();
let zooid_api_url =
@@ -74,6 +77,18 @@ impl Config {
}
}
fn normalize_pubkey(value: &str) -> Option<String> {
let trimmed = value.trim();
if trimmed.is_empty() {
return None;
}
match PublicKey::from_str(trimmed) {
Ok(pubkey) => Some(pubkey.to_hex()),
Err(_) => Some(trimmed.to_lowercase()),
}
}
fn resolve_database_url(database_url: String) -> String {
const PREFIX: &str = "sqlite://";
if !database_url.starts_with(PREFIX) {