Skip to content

Make app.auth.provider a required discriminated union: waspAuth() or an external provider manifest - #4726

Draft
FranjoMindek wants to merge 1 commit into
franjo/auth2-2-auth-contractfrom
franjo/auth2-3-spec-provider-union
Draft

Make app.auth.provider a required discriminated union: waspAuth() or an external provider manifest#4726
FranjoMindek wants to merge 1 commit into
franjo/auth2-2-auth-contractfrom
franjo/auth2-3-spec-provider-union

Conversation

@FranjoMindek

Copy link
Copy Markdown
Contributor

Description

Stack 3/7. The semantic heart of the feature: app.auth.provider becomes a required discriminated union — waspAuth({ methods, onAuthSucceededRedirectTo, ...hooks }) for Wasp's own auth, or an external provider manifest (produced by an adapter package's spec helper or customAuthProvider()).

  • Public spec surface (@wasp.sh/spec): the union, waspAuth(), defineAuthProviderManifest() with validation invariants, customAuthProvider(). Everything that only makes sense when Wasp runs signup/login (methods, hooks, success redirect) moves off Auth into waspAuth(), so none of it can leak into an external-provider app.
  • Manifest fields, final from birth: id, server (package entry or user-code module ref), routes, capabilities (open string set), env (server+client var requirements with docs), userSignupFields, setupFn, options, contractVersion.
  • Haskell IR: AuthProvider = WaspAuthProvider WaspAuthConfig | ExternalAuthProvider ExternalAuthProviderSpec, hand-written kind-discriminated JSON codecs, HasCustomEvaluation, accessor shims so the generator compiles unchanged.
  • Mechanical migration of every spec in the repo to waspAuth() (kitchen-sink, tutorials, waspello, websockets, ask-the-documents, the basic starter, and all four auth example apps) — this is exactly the migration the union imposes on users.
  • Docs API markdown snapshots regenerated (new Auth + Experimental sections).

The generator does not consume external manifests yet: they are legal but inert until stacks 4-6. Mapper acceptance of server: { package } entries is likewise latent until 6/7.

Review guidance: spend the effort on waspSpec.ts, constructors.ts and Auth.hs (~800 lines); the per-app waspAuth() wraps are mechanical and identical.

Type of change

  • 🔧 Just code/docs improvement
  • 🐞 Bug fix
  • 🚀 New/improved feature
  • 💥 Breaking change

Checklist

  • I tested my change in a Wasp app to verify that it works as intended.

  • 🧪 Tests and apps:

    • I added unit tests for my change.
    • (if you fixed a bug) I added a regression test for the bug I fixed.
    • (if you added/updated a feature) I added/updated e2e tests in examples/kitchen-sink/e2e-tests.
    • (if you added/updated a feature) I updated the starter templates in waspc/data/Cli/templates, as needed.
    • (if you added/updated a feature) I updated the example apps in examples/, as needed.
      • (if you updated examples/tutorials) I updated the tutorial in the docs (and vice versa).
  • 📜 Documentation:

    • (if you added/updated a feature) I added/updated the documentation in web/docs/.
  • 🆕 Changelog: (if change is more than just code/docs improvement)

    • I updated waspc/ChangeLog.md with a user-friendly description of the change.
    • (if you did a breaking change) I added a step to the current migration guide in web/docs/migration-guides/.
    • I bumped the version in waspc/waspc.cabal to reflect the changes I introduced.

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Aug 14, 2026

Copy link
Copy Markdown

Deploying wasp-docs-on-main with  Cloudflare Pages  Cloudflare Pages

Latest commit: ed34ccc
Status: ✅  Deploy successful!
Preview URL: https://67456a2c.wasp-docs-on-main.pages.dev
Branch Preview URL: https://franjo-auth2-3-spec-provider.wasp-docs-on-main.pages.dev

View logs

@FranjoMindek
FranjoMindek force-pushed the franjo/auth2-3-spec-provider-union branch from d4fccef to 4fa8644 Compare August 14, 2026 16:31
@pkg-pr-new

pkg-pr-new Bot commented Aug 14, 2026

Copy link
Copy Markdown

Open in StackBlitz

@wasp.sh/spec

npx https://pkg.pr.new/wasp-lang/wasp/@wasp.sh/spec@4726

@wasp.sh/wasp-cli

npx https://pkg.pr.new/wasp-lang/wasp/@wasp.sh/wasp-cli@4726

@wasp.sh/wasp-cli-darwin-arm64-unknown

npx https://pkg.pr.new/wasp-lang/wasp/@wasp.sh/wasp-cli-darwin-arm64-unknown@4726

@wasp.sh/wasp-cli-darwin-x64-unknown

npx https://pkg.pr.new/wasp-lang/wasp/@wasp.sh/wasp-cli-darwin-x64-unknown@4726

@wasp.sh/wasp-cli-linux-arm64-glibc

npx https://pkg.pr.new/wasp-lang/wasp/@wasp.sh/wasp-cli-linux-arm64-glibc@4726

@wasp.sh/wasp-cli-linux-x64-glibc

npx https://pkg.pr.new/wasp-lang/wasp/@wasp.sh/wasp-cli-linux-x64-glibc@4726

@wasp.sh/wasp-cli-linux-x64-musl

npx https://pkg.pr.new/wasp-lang/wasp/@wasp.sh/wasp-cli-linux-x64-musl@4726

commit: ed34ccc

@FranjoMindek
FranjoMindek force-pushed the franjo/auth2-3-spec-provider-union branch from 4fa8644 to 36c80e7 Compare August 14, 2026 19:16
@FranjoMindek

Copy link
Copy Markdown
Contributor Author

Follow-up to the contract change in #4725: defineAuthProviderManifest (and therefore customAuthProvider and every adapter spec helper) now rejects external provider ids that do not start with external:, with a test. The manifest id docs explain the reserved unprefixed namespace.

},
onAuthFailedRedirectTo: "/login",
onAuthSucceededRedirectTo: "/",
// Wasp's own auth, selected explicitly. Everything that only makes sense

@FranjoMindek FranjoMindek Aug 15, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These comments are unnecessary.
Also remove the original ones from the first PR.
Maybe just leave a short TODO: to be replaced with better-auth adapter e.g. in correct example.

This is true for all examples.

Comment thread waspc/src/Wasp/AppSpec/App/Auth.hs Outdated
-- independently of Wasp releases, so a closed enum here would break decoding of
-- every manifest built against a newer adapter. Unknown entries are ignored.
data ExternalAuthProviderSpec = ExternalAuthProviderSpec
{ -- | Stable identifier ("clerk", "better-auth"). Identities Wasp provisions

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update to follow external convention

Comment thread waspc/src/Wasp/AppSpec/App/Auth.hs Outdated
Comment on lines +138 to +142
serverPackage :: Maybe String,
-- | User-code module implementing the provider (the hand-written adapter
-- escape hatch), reached through a virtual user module like every other
-- ext import.
serverModule :: Maybe ExtImport,

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If these are exclusive make them Either

Comment thread waspc/src/Wasp/AppSpec/App/Auth.hs Outdated
-- | Populates the user entity when Wasp provisions a local user for a
-- subject it has not seen before.
userSignupFields :: Maybe ExtImport,
-- | Setup function for the provider's underlying library (the

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove reudundant information like @prismaSetupFn@ convention.
Keep field descriptions minimal.

// pattern would rewrite it into `provider: SMTP({...})` and corrupt the spec.
const waspSMTPAppSpec = waspTsSpec.replace(
/provider:\s+[A-Za-z0-9_][A-Za-z0-9_]*/g,
/provider:\s+(SMTP|SendGrid|Mailgun|Resend|Dummy)\b/g,

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We replace SMTP with SMTP?

@FranjoMindek
FranjoMindek deployed to fly-deploy-test August 15, 2026 09:18 — with GitHub Actions Active
@FranjoMindek
FranjoMindek force-pushed the franjo/auth2-3-spec-provider-union branch from 0d133ef to ed34ccc Compare August 15, 2026 14:43
@FranjoMindek

Copy link
Copy Markdown
Contributor Author

Review fixes applied:

  • Example spec comments removed; the three to-flip apps carry a short TODO: to be replaced with the X adapter until their flip.
  • Auth.hs doc examples now follow the external: convention.
  • serverPackage/serverModule are now exclusive by construction: a single server :: ExternalProviderServer (newtype over Either String ExtImport) with a {package}|{module} JSON codec; the mapper emits the tagged shape and Valid.hs's exclusivity check is deleted as impossible-by-construction. Accessor functions keep the old names, so downstream generator code is untouched.
  • Field docs trimmed (prismaSetupFn convention reference and other redundancy removed).
  • mailcrab: SMTP dropped from its own replacement alternation — behavior identical, tautology gone.

@FranjoMindek
FranjoMindek deployed to fly-deploy-test August 15, 2026 15:32 — with GitHub Actions Active
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.

1 participant