Skip to content

feat(auth): brand the NextAuth signout confirmation page - #5390

Open
IamCoder18 wants to merge 1 commit into
Kilo-Org:mainfrom
IamCoder18:feat/auth-branded-signout
Open

feat(auth): brand the NextAuth signout confirmation page#5390
IamCoder18 wants to merge 1 commit into
Kilo-Org:mainfrom
IamCoder18:feat/auth-branded-signout

Conversation

@IamCoder18

@IamCoder18 IamCoder18 commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Summary

GET /api/auth/signout was rendering NextAuth's built-in, unstyled confirmation page because authOptions.pages only overrode signIn and error, so the signout flow looked off-brand while the rest of the app uses kilo-design tokens and AuthPageLayout. Worse, the in-app signout entry points (sidebar dropdown, device-auth flow) bypassed the confirmation entirely by calling signOut({ callbackUrl }) from next-auth/react, which POSTs /api/auth/signout and follows the returned redirect without rendering a confirmation page.

This change adds a branded /users/sign_out page that reuses AuthPageLayout, the existing Card/Button primitives, and the same revoke-web-session + signOut({ callbackUrl }) flow used elsewhere. The page reads callbackUrl from the query string, restricts it to same-origin paths, and falls back to /profile when absent. NextAuth pages.signOut is pointed at it, so any external/manual GET /api/auth/signout lands on the branded page. The sidebar and device-auth signout entry points are updated to navigate to /users/sign_out?callbackUrl=... instead of calling signOut directly, so they share the same confirmation UI. The profile "sign out browser sessions" dialog is left calling signOut directly because that flow runs a server-side tRPC mutation that already rotates the user's web-session pepper — routing through a Cancel-capable confirmation page afterwards would let the user dismiss it with a stale NextAuth cookie. The dev "nuke" action (apps/web/src/components/dev/actions.ts) is updated to point at /users/sign_out?callbackUrl=/profile directly because NextAuth's pages.signOut redirect drops the original query string (see node_modules/next-auth/src/core/index.ts:199).

Verification

  • Manually load http://localhost:<port>/users/sign_out and confirm it renders inside AuthPageLayout with brand tokens, the "Sign out" button calls signOut({ callbackUrl }), and "Cancel" returns to the previous page.
  • Manually load http://localhost:<port>/users/sign_out?callbackUrl=/profile and confirm signOut lands on /profile.
  • Manually load http://localhost:<port>/api/auth/signout?callbackUrl=/profile and confirm it redirects to the branded page and lands on /profile after confirmation.
  • From the sidebar user dropdown, click "Sign out", confirm the branded page appears, click "Sign out", and confirm the user is signed out and lands on /.
  • From the profile "sign out browser sessions" dialog, confirm, and confirm the user is signed out and lands on /users/sign_in without a second confirmation step.
  • Run the dev "nuke" action from the dev panel and confirm the user is routed through the branded page to /profile.

Visual Changes

Before After
Plain NextAuth default confirmation page on GET /api/auth/signout; sidebar/device-auth signout skipped confirmation entirely. Branded /users/sign_out page reused by pages.signOut, the sidebar dropdown, and the device-auth flow.

@kilo-code-bot

kilo-code-bot Bot commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Executive Summary

Incremental change restores a direct signOut() after pepper rotation, so the leftover NextAuth cookie warning is resolved.

Files Reviewed (1 files)
  • apps/web/src/components/profile/SignOutBrowserSessionsDialog.tsx
Previous Review Summary (commit 3e60c57)

Current summary above is authoritative. Previous snapshots are kept for context only.

Previous review (commit 3e60c57)

Status: 1 Issue Found | Recommendation: Address before merge

Executive Summary

Sign-out-all-browser-sessions already rotates the web-session pepper, then routes through a second Cancel-capable confirmation page and can leave this tab with a stale NextAuth cookie.

Overview

Severity Count
CRITICAL 0
WARNING 1
SUGGESTION 0
Issue Details (click to expand)

WARNING

File Line Issue
apps/web/src/components/profile/SignOutBrowserSessionsDialog.tsx 28 After signOutBrowserSessions rotates web_session_pepper, this flow pushes /users/sign_out instead of calling signOut(). Cancel cannot undo the revoke and leaves a leftover NextAuth cookie.
Files Reviewed (6 files)
  • apps/web/src/app/(app)/components/SidebarUserFooter.tsx - 0 issues
  • apps/web/src/app/device-auth/DeviceAuthClient.tsx - 0 issues
  • apps/web/src/app/users/sign_out/page.tsx - 0 issues
  • apps/web/src/components/dev/actions.ts - 0 issues
  • apps/web/src/components/profile/SignOutBrowserSessionsDialog.tsx - 1 issue
  • apps/web/src/lib/user/server.ts - 0 issues

Fix these issues in Kilo Cloud


Reviewed by grok-4.6 · Input: 29.4K · Output: 5.7K · Cached: 144.9K

Review guidance: REVIEW.md from base branch main

NextAuth rendered its own unstyled confirmation page on GET
/api/auth/signout because authOptions.pages only overrode signIn and
error, so the signout flow looked off-brand even though the rest of
the app uses kilo-design tokens and AuthPageLayout.

Worse, every in-app signout entry point (sidebar dropdown, profile
sign-out-browser-sessions dialog, device-auth flow) bypassed any
confirmation by calling signOut({ callbackUrl }) from
next-auth/react, which POSTs /api/auth/signout and follows the
returned redirect directly.

Add a /users/sign_out page that reuses AuthPageLayout, the existing
Card and Button primitives, and the same revoke-web-session +
signOut({ callbackUrl }) flow used elsewhere. The page reads
callbackUrl from the query string, restricts it to same-origin paths,
and falls back to /profile when absent.

Point NextAuth pages.signOut at it, so any external or manual GET
/api/auth/signout lands on the branded page, and route the in-app
signout entry points through /users/sign_out?callbackUrl=... so they
share the same confirmation UI. Update the dev 'nuke' action to
target /users/sign_out?callbackUrl=/profile directly because
NextAuth's pages.signOut redirect drops the original query string
(see node_modules/next-auth/src/core/index.ts:199).
@IamCoder18
IamCoder18 force-pushed the feat/auth-branded-signout branch from 3e60c57 to ce447d3 Compare August 20, 2026 04:22
@emilieschario

Copy link
Copy Markdown
Contributor

We do need you to do PR review before you ask for a review o f this PR. Give there are no pictures, it's unlikely a human did review. I'm going to close this. Feel free to reopen it if you bring it to review standards

@IamCoder18

IamCoder18 commented Aug 20, 2026

Copy link
Copy Markdown
Contributor Author

We do need you to do PR review before you ask for a review o f this PR. Give there are no pictures, it's unlikely a human did review. I'm going to close this. Feel free to reopen it if you bring it to review standards

Hey @emilieschario.

I do manually review every diff before opening PRs, in accordance with the guidelines. Unfortunately, I did upload a screenshot when I tested it, but it got removed when my agent fixed a formatting issue in the PR description.
You can also see the screenshot in the 2nd to last revision of the contents, before it was overwritten.

I apologize, and it won't happen again.

Here is said screenshot:

sign_out_page

Would it be possible to get this reopened, or would you prefer I open a new PR?

@emilieschario emilieschario reopened this Aug 20, 2026
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.

2 participants