Add prosekit rich-text field, Gitea repo embeds, automation KV read endpoint; fix apex/www session-cookie mismatch on /auth/callback
Deploy / deploy (push) Successful in 29s

- type: prosekit requirement kind, backed by public/prosekit-editor.js
  (ProseMirror via prosekit, loaded from esm.sh, no bundler) - mirrors
  its HTML into a paired hidden input so it reuses the existing
  RwSignal/on:input wiring.
- Pasting a project.uhhm.no/<owner>/<repo> URL in the editor embeds a
  repo card, resolved server-side via a new /gitea-repo handler
  (content::gitea_repo_handler) so the browser never needs Gitea API
  CORS.
- New /automation/kv/{bucket} handler, bearer-token gated
  (AUTOMATION_READ_TOKEN), for backing automations (n8n) to read a
  NATS KV bucket without a browser session.
- Fix: a login started on one of apex/www set its session cookie
  there, but Kanidm's redirect_uri is fixed to PUBLIC_URL - landing
  the callback on a different, empty session ("no login in
  progress"). Caddy now redirects www -> apex so every visit stays on
  one canonical host.
This commit is contained in:
Bendik Aagaard Lynghaug
2026-08-05 13:45:56 +02:00
parent 18025bf870
commit 44c8c9d410
6 changed files with 405 additions and 9 deletions
+4
View File
@@ -28,6 +28,7 @@ async fn main() -> anyhow::Result<()> {
let content_repo = std::env::var("CONTENT_REPO")
.unwrap_or_else(|_| "https://project.uhhm.no/uhhm/questions".to_string());
let content_branch = std::env::var("CONTENT_BRANCH").unwrap_or_else(|_| "main".to_string());
let gitea_base = content::gitea_api_base(&content_repo)?;
let questions = content::load_questions_from_gitea(&content_repo, &content_branch, "questions").await?;
tracing::info!(count = questions.len(), repo = %content_repo, branch = %content_branch, "loaded content");
let questions = Arc::new(arc_swap::ArcSwap::from_pointee(questions));
@@ -70,6 +71,7 @@ async fn main() -> anyhow::Result<()> {
nats,
jetstream,
questions,
gitea_base,
oidc: oidc_state,
garage,
};
@@ -122,6 +124,8 @@ async fn main() -> anyhow::Result<()> {
.route("/auth/logout", get(oidc::logout))
.route("/api/{*fn_name}", any(server_fn_handler))
.route("/upload", post(upload::upload))
.route("/gitea-repo", get(content::gitea_repo_handler))
.route("/automation/kv/{bucket}", get(content::automation_kv_handler))
.nest_service("/pkg", ServeDir::new(pkg_dir))
.nest_service("/fonts", ServeDir::new(fonts_dir))
.route_service("/favicon.svg", ServeFile::new(favicon_path))