F3 — Forgejo OAuth provider #482

Closed
opened 2026-04-27 21:42:51 +00:00 by claude-desktop · 0 comments
Collaborator

As an operator, I want the "Sign in with Forgejo" button to take me through the standard OAuth dance, so that I land in the app authenticated with my Forgejo account.

Acceptance criteria

  • OAuth client registered on forge.jacquin.app (manual one-time step, printed by just oauth-register-forgejo — see F-helper).
  • Client id + secret configured via forgejo_oauth_client_id / forgejo_oauth_client_secret in config/agents.json (env override accepted).
  • GET /oauth/forgejo/init?return=<path> redirects to Forgejo's authorize URL with state (CSRF, 5-min TTL in-memory) and redirect_uri = <public_base_url>/oauth/forgejo/callback.
  • GET /oauth/forgejo/callback?code=&state= validates state, exchanges code → token (POST /login/oauth/access_token), fetches operator profile (GET /api/v1/user), upserts operator_oauth_tokens.forge_type='forgejo', calls setActiveForge('forgejo'), creates a session row, sets the cookie, 302s to return path or /.
  • Required scopes: read:repository, write:repository, write:hook.
  • Adapter helper withOperatorOAuth(forge, fn) retries once after a refresh on 401. Forgejo refresh-token flow implemented.
  • On callback error (state mismatch, exchange failure, profile fetch 4xx), redirect to /login?error=<code> with a flash message; do not leak forge response bodies.

Out of scope

  • GitHub / GitLab providers — F3-GH / F3-GL.
  • Login page UI — F1.

References

  • Spec: docs/specs/forge-auth-repo-selection.md §F3
  • Forgejo OAuth docs

Dependencies

  • Blocked by F1 (auth gate + session middleware)
  • Blocked by F2 (operator_oauth_tokens table + active-forge router)
As an operator, I want the "Sign in with Forgejo" button to take me through the standard OAuth dance, so that I land in the app authenticated with my Forgejo account. ## Acceptance criteria - [ ] OAuth client registered on `forge.jacquin.app` (manual one-time step, printed by `just oauth-register-forgejo` — see F-helper). - [ ] Client id + secret configured via `forgejo_oauth_client_id` / `forgejo_oauth_client_secret` in `config/agents.json` (env override accepted). - [ ] `GET /oauth/forgejo/init?return=<path>` redirects to Forgejo's authorize URL with `state` (CSRF, 5-min TTL in-memory) and `redirect_uri = <public_base_url>/oauth/forgejo/callback`. - [ ] `GET /oauth/forgejo/callback?code=&state=` validates state, exchanges code → token (POST `/login/oauth/access_token`), fetches operator profile (GET `/api/v1/user`), upserts `operator_oauth_tokens.forge_type='forgejo'`, calls `setActiveForge('forgejo')`, creates a session row, sets the cookie, 302s to `return` path or `/`. - [ ] Required scopes: `read:repository`, `write:repository`, `write:hook`. - [ ] Adapter helper `withOperatorOAuth(forge, fn)` retries once after a refresh on 401. Forgejo refresh-token flow implemented. - [ ] On callback error (state mismatch, exchange failure, profile fetch 4xx), redirect to `/login?error=<code>` with a flash message; do not leak forge response bodies. ## Out of scope - GitHub / GitLab providers — F3-GH / F3-GL. - Login page UI — F1. ## References - Spec: `docs/specs/forge-auth-repo-selection.md` §F3 - Forgejo OAuth docs ## Dependencies - Blocked by F1 (auth gate + session middleware) - Blocked by F2 (operator_oauth_tokens table + active-forge router)
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
charles/claude-hooks#482
No description provided.