fix(appview): add CorsLayer so Tauri webview can hit /api/*
The Tauri webview's origin (the Vite dev server on port 1430, or the bundled tauri:// / asset:// origin in production) is cross-origin against the AppView's listen address (port 2584). Without an `Access-Control-Allow-Origin` response header the browser blocks the fetch before `response.json()` runs and the UI surfaces the failure as a SyntaxError on /api/profile. The previous workaround (a Tauri command that returns the AppView base URL) got us to the right URL but didn't address the underlying CORS preflight failure. Add `tower_http::cors::CorsLayer` with `allow_origin(Any)` to the AppView router — the AppView's public read endpoints carry no auth cookie and the service runs adjacent to the user's own PDS rather than the open internet, so any-origin is safe. Production deployments behind a reverse proxy can tighten the allow list at the proxy.
This commit is contained in:
@@ -22,6 +22,7 @@ use axum::{
|
||||
use chrono::{DateTime, TimeZone, Utc};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::{json, Value};
|
||||
use tower_http::cors::{Any, CorsLayer};
|
||||
|
||||
use crate::state::AppState;
|
||||
|
||||
@@ -31,6 +32,21 @@ pub mod types;
|
||||
use types::{PostRow, PostRowWithIndexed, ProfileResponse, SearchResponse, TimelineResponse};
|
||||
|
||||
pub fn router(state: AppState) -> Router {
|
||||
// CORS: the Tauri webview's origin is the Vite dev server
|
||||
// (`http://127.0.0.1:1430`) in dev or the bundled `tauri://` /
|
||||
// `asset://` origin in production. Either way it's a cross-origin
|
||||
// fetch against this service's `http://127.0.0.1:2584` listen
|
||||
// address, so the browser blocks the response without an explicit
|
||||
// allow-origin header. We allow any origin — the AppView's
|
||||
// public read endpoints (`/api/...`) carry no auth cookie and
|
||||
// the AppView runs alongside the user's own PDS, not on the
|
||||
// open internet; production deployments behind a reverse proxy
|
||||
// can tighten this via the proxy itself.
|
||||
let cors = CorsLayer::new()
|
||||
.allow_origin(Any)
|
||||
.allow_methods(Any)
|
||||
.allow_headers(Any);
|
||||
|
||||
Router::new()
|
||||
.route("/", get(root))
|
||||
.route("/api/timeline/home", get(timeline_home))
|
||||
@@ -40,6 +56,7 @@ pub fn router(state: AppState) -> Router {
|
||||
.route("/api/post/*uri", get(post_by_uri))
|
||||
.route("/healthz", get(healthz))
|
||||
.route("/internal/ingest-commit", post(crate::ingest::ingest_commit))
|
||||
.layer(cors)
|
||||
.with_state(state)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user