feat(oauth): GitLab OAuth provider — GET /oauth/gitlab/{init,callback} #500
No reviewers
Labels
No labels
area:agents
area:dashboard
area:database
area:design
area:design-review
area:flows
area:infra
area:meta
area:security
area:sessions
area:webhook
area:workdir
security
type:bug
type:chore
type:meta
type:user-story
No milestone
No project
No assignees
3 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
charles/claude-hooks!500
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "dev/484"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Adds the GitLab OAuth provider (F3-GL): operator login flow against
gitlab.comor a self-hosted instance, with CSRF state validation, token persistence, and auto-refresh ahead of the 2-hour expiry.Test plan
gitlab_oauth_client_id/gitlab_oauth_client_secrettoconfig/agents.json; restart service — no crash.just oauth-register-gitlabprints registration instructions with the correct callback URI.GET /oauth/gitlab/initredirects togitlab.com/oauth/authorizewithscope=api+read_userand a randomstate.gitlab-oauth-token.json(mode 600) under~/.local/state/claude-hooks/and redirects to/app/monitor.?error=access_deniedredirects to/app/monitor?error=GitLab+authorization+denied:+....stateredirects to/app/monitor?error=Unknown+OAuth+state+....getGitLabOAuthTokenrefreshes viaPOST /oauth/tokenand writes updated file./oauth/gitlab/initand/oauth/gitlab/callbackreturn503.Closes #484
All six AC from #484 are met:
just oauth-register-gitlabprints correct instructions, config parsing rejects partial credentials,GET /oauth/gitlab/{init,callback}withapi read_userscopes, CSRF state consumed on first use, 5-min-ahead auto-refresh with token written at mode 0o600, and error-flash path mirrors F3. CI green.Nit (non-blocking):
getGitLabOAuthTokenhas no refresh-concurrency guard — two near-simultaneous calls near expiry will both attempt a refresh and the second will fail (single-use refresh token). Benign for the operator-login use case but worth a comment if this helper is later called from request-serving hot paths.Cannot squash-merge: Forgejo reports
mergeable: false(conflicts againstmain). @dev please rebasedev/484onto latestmainand push; merge will retry once conflicts are resolved.7bb3b946c3209c44dc3c