Skip to content

feat(auth): submit auth forms through app-owned server actions - #813

Merged
borisno2 merged 3 commits into
mainfrom
claude/auth-forms-server-actions-twiyno
Jul 24, 2026
Merged

feat(auth): submit auth forms through app-owned server actions#813
borisno2 merged 3 commits into
mainfrom
claude/auth-forms-server-actions-twiyno

Conversation

@borisno2

Copy link
Copy Markdown
Member

Summary

Convert the pre-built better-auth forms in @opensaas/stack-auth/ui from calling the browser authClient (which hit /api/auth/*) to submitting through app-owned Next.js server actions. This keeps the auth network surface server-side (no browser dependency on NEXT_PUBLIC_APP_URL, fewer origin/CORS concerns) and matches the app's existing lib/actions/* convention. Design recorded in ADR-0020.

@opensaas/stack-auth

  • SignInForm / SignUpForm / ForgotPasswordForm drop the authClient prop and take per-concern server-action props (signInAction, signUpAction, requestPasswordResetAction, optional signInSocialAction).
  • New ResetPasswordForm — token via prop (page reads searchParams.token), confirm-password mirroring sign-up, and an empty-token guard. Completes the forgot-password flow, which previously dead-ended on a missing /reset-password page.
  • Email actions return AuthActionResult and the form redirects client-side (redirectTo / onSuccess / onError preserved); social sign-in redirects server-side to the provider (OAuth navigates away).
  • Package exports the action contract types only (AuthActionResult, SignInInput, SignUpInput, RequestPasswordResetInput, ResetPasswordInput, and the action aliases); the [body.field] error cleanup stays internal to the forms.
  • createAuth auto-adds better-auth's nextCookies plugin as the last plugin, so the session cookie set inside a server action persists.
  • createClient is unchanged — still available for client-side session reading (useSession).

@opensaas/stack-cli

  • The feature-generator emits lib/actions/auth.ts + a reset-password page and wires the auth pages to actions; it no longer emits lib/auth-client.ts.

Examples

  • starter-auth, auth-demo, mcp-demo: add lib/actions/auth.ts, wire pages to actions, add reset-password pages, delete auth-client.ts. (create-opensaas-app's with-auth template regenerates from starter-auth, so it's covered automatically.)

Docs

  • ADR-0020 + Auth action glossary term in CONTEXT.md; package README.md / CLAUDE.md updated to the new API.

Why minor, not major

The form prop change is technically breaking, but the packages are pre-1.0 (0.x), where a minor may carry breaking changes by semver convention — released as minor per the requested versioning.

Test plan

  • pnpm build (all packages) green
  • @opensaas/stack-auth tests: 146 passed (incl. new cleanAuthErrorMessage unit tests)
  • pnpm lint clean (only pre-existing warnings)
  • All three examples tsc --noEmit clean after pnpm generate
  • pnpm manypkg fix + pnpm format
  • Adversarial review of the diff — no material findings (cookie persistence, server-side redirect placement, empty-token guard, and searchParams-as-Promise all confirmed correct)

🤖 Generated with Claude Code

https://claude.ai/code/session_01XdXErtDYWN5gu8vrpcU34y


Generated by Claude Code

claude added 3 commits July 24, 2026 11:44
Capture the design agreed during a grilling session before implementing:
auth forms will submit through app-owned server actions instead of the
browser auth client. Adds the "Auth action" term to CONTEXT.md and
ADR-0020 documenting the contract, the email/social redirect asymmetry,
auto-added nextCookies, and the folded-in reset-password flow.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XdXErtDYWN5gu8vrpcU34y
Replace the browser authClient with per-concern server-action props on the
pre-built auth forms, so the auth network surface stays server-side (no
/api/auth/* call from the browser) and matches the app's lib/actions/*
convention. Implements ADR-0020.

Package @opensaas/stack-auth:
- SignInForm/SignUpForm/ForgotPasswordForm drop the authClient prop and take
  server-action props (signInAction, signUpAction, requestPasswordResetAction,
  optional signInSocialAction). Email actions return an AuthActionResult and
  the form redirects client-side; social sign-in redirects server-side.
- New ResetPasswordForm (token via prop, confirm-password, empty-token guard)
  completing the previously-dead forgot-password flow.
- Export the action contract types; keep [body.field] error cleanup internal.
- createAuth auto-adds better-auth's nextCookies plugin (last) so the session
  cookie set inside a server action persists.
- createClient unchanged for client-side session reading.

Package @opensaas/stack-cli:
- feature-generator emits lib/actions/auth.ts + a reset-password page and wires
  the pages to actions; no longer emits lib/auth-client.ts.

Examples (starter-auth, auth-demo, mcp-demo): add lib/actions/auth.ts, wire the
pages to actions, add reset-password pages, delete auth-client.ts.

Docs: ADR-0020 + "Auth action" glossary term.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XdXErtDYWN5gu8vrpcU34y
Reflect the new form API in @opensaas/stack-auth's README and CLAUDE.md:
forms take server-action props (not authClient), add ResetPasswordForm,
document the nextCookies auto-wiring, and make the client-side session-hook
section self-contained now that scaffolds no longer emit lib/auth-client.ts.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XdXErtDYWN5gu8vrpcU34y
@vercel

vercel Bot commented Jul 24, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
stack-docs Ready Ready Preview, Comment Jul 24, 2026 12:07pm

@changeset-bot

changeset-bot Bot commented Jul 24, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 24dc97c

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 9 packages
Name Type
@opensaas/stack-auth Minor
@opensaas/stack-cli Minor
@opensaas/stack-core Minor
@opensaas/stack-rag Minor
@opensaas/stack-storage-s3 Minor
@opensaas/stack-storage-vercel Minor
@opensaas/stack-storage Minor
@opensaas/stack-tiptap Minor
@opensaas/stack-ui Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions

Copy link
Copy Markdown
Contributor

Coverage Report for Core Package Coverage (./packages/core)

Status Category Percentage Covered / Total
🟢 Lines 92.63% (🎯 65%) 1145 / 1236
🟢 Statements 91.11% (🎯 65%) 1221 / 1340
🟢 Functions 97.93% (🎯 62%) 190 / 194
🟢 Branches 81.91% (🎯 50%) 820 / 1001
File CoverageNo changed files found.
Generated in workflow #1519 for commit 24dc97c by the Vitest Coverage Report Action

@github-actions

Copy link
Copy Markdown
Contributor

Coverage Report for UI Package Coverage (./packages/ui)

Status Category Percentage Covered / Total
🔵 Lines 76.72% 244 / 318
🔵 Statements 76.29% 251 / 329
🔵 Functions 69.15% 74 / 107
🔵 Branches 64.25% 160 / 249
File CoverageNo changed files found.
Generated in workflow #1519 for commit 24dc97c by the Vitest Coverage Report Action

@github-actions

Copy link
Copy Markdown
Contributor

Coverage Report for CLI Package Coverage (./packages/cli)

Status Category Percentage Covered / Total
🔵 Lines 79.4% 1496 / 1884
🔵 Statements 79.1% 1556 / 1967
🔵 Functions 86.19% 206 / 239
🔵 Branches 67.31% 655 / 973
File CoverageNo changed files found.
Generated in workflow #1519 for commit 24dc97c by the Vitest Coverage Report Action

@github-actions

Copy link
Copy Markdown
Contributor

Coverage Report for Auth Package Coverage (./packages/auth)

Status Category Percentage Covered / Total
🔵 Lines 97.45% 115 / 118
🔵 Statements 97.52% 118 / 121
🔵 Functions 100% 38 / 38
🔵 Branches 92.85% 78 / 84
File CoverageNo changed files found.
Generated in workflow #1519 for commit 24dc97c by the Vitest Coverage Report Action

@github-actions

Copy link
Copy Markdown
Contributor

Coverage Report for Storage Package Coverage (./packages/storage)

Status Category Percentage Covered / Total
🔵 Lines 76.65% 197 / 257
🔵 Statements 78.13% 218 / 279
🔵 Functions 85.89% 67 / 78
🔵 Branches 72.98% 181 / 248
File CoverageNo changed files found.
Generated in workflow #1519 for commit 24dc97c by the Vitest Coverage Report Action

@github-actions

Copy link
Copy Markdown
Contributor

Coverage Report for RAG Package Coverage (./packages/rag)

Status Category Percentage Covered / Total
🔵 Lines 47.97% 355 / 740
🔵 Statements 48.14% 377 / 783
🔵 Functions 54.26% 70 / 129
🔵 Branches 42.55% 180 / 423
File CoverageNo changed files found.
Generated in workflow #1519 for commit 24dc97c by the Vitest Coverage Report Action

@github-actions

Copy link
Copy Markdown
Contributor

Coverage Report for Storage S3 Package Coverage (./packages/storage-s3)

Status Category Percentage Covered / Total
🔵 Lines 100% 40 / 40
🔵 Statements 100% 40 / 40
🔵 Functions 100% 9 / 9
🔵 Branches 100% 19 / 19
File CoverageNo changed files found.
Generated in workflow #1519 for commit 24dc97c by the Vitest Coverage Report Action

@github-actions

Copy link
Copy Markdown
Contributor

Coverage Report for Storage Vercel Package Coverage (./packages/storage-vercel)

Status Category Percentage Covered / Total
🔵 Lines 100% 68 / 68
🔵 Statements 100% 71 / 71
🔵 Functions 100% 15 / 15
🔵 Branches 97.87% 46 / 47
File CoverageNo changed files found.
Generated in workflow #1519 for commit 24dc97c by the Vitest Coverage Report Action

@borisno2
borisno2 merged commit 5a6198c into main Jul 24, 2026
6 checks passed
@borisno2
borisno2 deleted the claude/auth-forms-server-actions-twiyno branch July 24, 2026 12:35
@github-actions github-actions Bot mentioned this pull request Jul 24, 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