Skip to content

Add API token generation to the account settings page - #451

Open
l3x4 wants to merge 3 commits into
mainfrom
feature/api-token-management-ui
Open

Add API token generation to the account settings page#451
l3x4 wants to merge 3 commits into
mainfrom
feature/api-token-management-ui

Conversation

@l3x4

@l3x4 l3x4 commented Aug 25, 2026

Copy link
Copy Markdown

Closes #450

What

An API token section on the account page (/users/edit):

  • Shows whether a token exists (from api_token_digest? — nothing derived from the digest is ever displayed).
  • Generate API token — or Regenerate with a turbo_confirm warning that the old token stops working — POSTs to a new session-authenticated Users::ApiTokensController#create, which calls the existing User#regenerate_api_token!.
  • The new token is shown once, in a highlighted copy-friendly block with a "save it now" notice, plus a short hint about Authorization: Bearer <token> against /api/v1/.

Security notes

  • The plaintext token lives only in the single response render (@api_token ivar) — it is never placed in the flash, session, cookies, params, or logs, and never persisted beyond its digest.
  • Action is authenticated (AuthenticatedController) and authorized (UserPolicy#regenerate_token?).
  • No changes to the API itself — digest storage and PATCH /api/v1/api_token untouched.

Tests

255 runs, 0 failures, 0 errors (full suite). New coverage: unauthenticated POST rejected; authenticated POST rotates the digest and shows the one-time token exactly once with the warning copy; regeneration invalidates the previous token; the edit page never displays a token on a plain visit. Locales added in both en and nb. Rubocop clean.


PR generated by Claude on behalf of @l3x4.

l3x4 and others added 2 commits August 25, 2026 15:09
Users previously needed Rails console access to obtain an API token
(issue #450). The account page now shows whether a token exists and
offers a generate/regenerate button posting to a new session-
authenticated Users::ApiTokensController. The plaintext token is
rendered exactly once via an ivar into the registrations edit view
(422 status so Turbo accepts the render) and is never placed in
flash, params, or session — only its SHA256 digest is persisted.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Covers the auth redirect for unauthenticated posts, the one-time
token display (exactly once, with warning copy), digest rotation
invalidating the previous token, and that a plain visit to the
account page never reveals a token.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@l3x4 l3x4 self-assigned this Aug 25, 2026
Rendering the edit view with :unprocessable_entity was a workaround
for Turbo's form-response contract (non-redirect HTML needs a 4xx),
which mislabels a successful generation as a client error. The token
section now lives in a partial and the controller replaces it via
turbo_stream with an honest 200; the plaintext token still exists
only in this single response.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@l3x4

l3x4 commented Aug 25, 2026

Copy link
Copy Markdown
Author

Reworked the success response after review feedback: the original render :edit, status: :unprocessable_entity was a workaround for Turbo's form-response contract and mislabeled success as a client error. The token section is now a partial (users/api_tokens/_section) and the controller responds with a turbo_stream.replace at an honest 200 OK — matching the idiom used across the app's other controllers. Token-handling invariant unchanged: plaintext exists only in the single response. Full suite still 255 runs, 0 failures.

Comment generated by Claude.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

No way to obtain an API token without Rails console access

1 participant