Skip to content

Commit dd05e75

Browse files
committed
Add four auth-provider example apps in plain Wasp auth form
1 parent 2c16b09 commit dd05e75

89 files changed

Lines changed: 45712 additions & 0 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

examples/auth-providers/README.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Auth provider examples
2+
3+
Four Wasp apps that are identical except for **which auth provider verifies the request**.
4+
5+
They exist to answer one question: how much of an app's code survives swapping the auth
6+
provider? The answer, demonstrated rather than asserted, is _everything except the auth pages_.
7+
8+
| App | Provider | What it proves |
9+
| --------------- | -------------------------- | --------------------------------------------------------------------- |
10+
| `wasp-auth/` | Wasp's own auth | The interface is a faithful refactor — behaviour is unchanged |
11+
| `better-auth/` | Better Auth, in-process | A provider that owns its own tables and routes |
12+
| `clerk/` | Clerk, hosted | A provider with no server-side login at all, and no schema of its own |
13+
| `custom-clerk/` | Clerk, hand-written in-app | The `customAuthProvider()` escape hatch — no adapter package needed |
14+
15+
All four start as clones of `wasp-auth/` running Wasp's own auth. Each app diverges only
16+
when its provider arrives later in this PR stack, so every diff in these apps from here
17+
on is auth-relevant.
18+
19+
## Running them
20+
21+
Each app is a normal Wasp app:
22+
23+
```sh
24+
cd wasp-auth && wasp db migrate-dev && wasp start
25+
```
26+
27+
See each app's own README for provider-specific setup.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.wasp/
2+
node_modules/
3+
.env.server
4+
.env.client
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Helps prevent supply chain attacks
2+
min-release-age=7
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
.wasp
2+
node_modules
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Ignore editor tmp files
2+
**/*~
3+
**/#*#
4+
.DS_Store
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
File marking the root of Wasp project.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Auth providers — Better Auth
2+
3+
For now a byte-for-byte clone of `../wasp-auth` running Wasp's own auth. It switches to
4+
Better Auth via the `@wasp.sh/auth-better-auth` adapter package later in this PR stack.
5+
6+
Two things are already in place so that the switch shows up as a pure auth diff:
7+
8+
- the `better-auth` dependency is installed, and
9+
- `schema.prisma` carries Better Auth's own tables (`BetterAuth*`). They are plain
10+
Prisma models and sit unused until the provider arrives.
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import js from "@eslint/js";
2+
import eslintPrettier from "eslint-config-prettier/flat";
3+
import eslintReact from "eslint-plugin-react";
4+
import { defineConfig } from "eslint/config";
5+
import globals from "globals";
6+
import eslintTypescript from "typescript-eslint";
7+
8+
export default defineConfig([
9+
{
10+
files: ["**/*.{js,mjs,cjs,ts,mts,cts,jsx,tsx}"],
11+
plugins: { js },
12+
extends: ["js/recommended"],
13+
},
14+
{
15+
files: ["**/*.{js,mjs,cjs,ts,mts,cts,jsx,tsx}"],
16+
languageOptions: { globals: { ...globals.browser, ...globals.node } },
17+
},
18+
eslintTypescript.configs.recommended,
19+
eslintReact.configs.flat.recommended,
20+
eslintReact.configs.flat["jsx-runtime"],
21+
eslintPrettier,
22+
// Overrides:
23+
{
24+
// `@typescript-eslint/no-require-imports` is enabled by default in `typescript-eslint/recommended` config.
25+
// This allows us to use `require` syntax in CJS files.
26+
files: ["**/*.{cjs,cts}"],
27+
rules: {
28+
"@typescript-eslint/no-require-imports": ["off"],
29+
},
30+
},
31+
]);
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { action, app, page, query, route } from "@wasp.sh/spec";
2+
import { MainPage } from "./src/MainPage" with { type: "ref" };
3+
import { LoginPage } from "./src/auth/LoginPage" with { type: "ref" };
4+
import { createTask, getMyTasks } from "./src/operations" with { type: "ref" };
5+
6+
export default app({
7+
name: "authProviderBetterAuth",
8+
wasp: { version: "^0.26.0" },
9+
title: "Auth providers — Better Auth",
10+
11+
auth: {
12+
userEntity: "User",
13+
// Wasp's own auth. `provider` is left unset, which is the default and means
14+
// "use Wasp's built-in auth" -- exactly what every existing Wasp app does.
15+
methods: {
16+
usernameAndPassword: {},
17+
},
18+
onAuthFailedRedirectTo: "/login",
19+
onAuthSucceededRedirectTo: "/",
20+
},
21+
22+
spec: [
23+
route("MainRoute", "/", page(MainPage, { authRequired: true })),
24+
route("LoginRoute", "/login", page(LoginPage)),
25+
query(getMyTasks, { entities: ["Task"], auth: true }),
26+
action(createTask, { entities: ["Task"], auth: true }),
27+
],
28+
});
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
-- CreateTable
2+
CREATE TABLE "User" (
3+
"id" TEXT NOT NULL PRIMARY KEY
4+
);
5+
6+
-- CreateTable
7+
CREATE TABLE "Task" (
8+
"id" TEXT NOT NULL PRIMARY KEY,
9+
"description" TEXT NOT NULL,
10+
"isDone" BOOLEAN NOT NULL DEFAULT false,
11+
"userId" TEXT NOT NULL,
12+
CONSTRAINT "Task_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
13+
);
14+
15+
-- CreateTable
16+
CREATE TABLE "better_auth_user" (
17+
"id" TEXT NOT NULL PRIMARY KEY,
18+
"name" TEXT NOT NULL,
19+
"email" TEXT NOT NULL,
20+
"emailVerified" BOOLEAN NOT NULL DEFAULT false,
21+
"image" TEXT,
22+
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
23+
"updatedAt" DATETIME NOT NULL
24+
);
25+
26+
-- CreateTable
27+
CREATE TABLE "better_auth_session" (
28+
"id" TEXT NOT NULL PRIMARY KEY,
29+
"token" TEXT NOT NULL,
30+
"expiresAt" DATETIME NOT NULL,
31+
"ipAddress" TEXT,
32+
"userAgent" TEXT,
33+
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
34+
"updatedAt" DATETIME NOT NULL,
35+
"userId" TEXT NOT NULL,
36+
CONSTRAINT "better_auth_session_userId_fkey" FOREIGN KEY ("userId") REFERENCES "better_auth_user" ("id") ON DELETE CASCADE ON UPDATE CASCADE
37+
);
38+
39+
-- CreateTable
40+
CREATE TABLE "better_auth_account" (
41+
"id" TEXT NOT NULL PRIMARY KEY,
42+
"accountId" TEXT NOT NULL,
43+
"providerId" TEXT NOT NULL,
44+
"accessToken" TEXT,
45+
"refreshToken" TEXT,
46+
"idToken" TEXT,
47+
"accessTokenExpiresAt" DATETIME,
48+
"refreshTokenExpiresAt" DATETIME,
49+
"scope" TEXT,
50+
"password" TEXT,
51+
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
52+
"updatedAt" DATETIME NOT NULL,
53+
"userId" TEXT NOT NULL,
54+
CONSTRAINT "better_auth_account_userId_fkey" FOREIGN KEY ("userId") REFERENCES "better_auth_user" ("id") ON DELETE CASCADE ON UPDATE CASCADE
55+
);
56+
57+
-- CreateTable
58+
CREATE TABLE "better_auth_verification" (
59+
"id" TEXT NOT NULL PRIMARY KEY,
60+
"identifier" TEXT NOT NULL,
61+
"value" TEXT NOT NULL,
62+
"expiresAt" DATETIME NOT NULL,
63+
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
64+
"updatedAt" DATETIME NOT NULL
65+
);
66+
67+
-- CreateTable
68+
CREATE TABLE "Auth" (
69+
"id" TEXT NOT NULL PRIMARY KEY,
70+
"userId" TEXT,
71+
CONSTRAINT "Auth_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User" ("id") ON DELETE CASCADE ON UPDATE CASCADE
72+
);
73+
74+
-- CreateTable
75+
CREATE TABLE "AuthIdentity" (
76+
"providerName" TEXT NOT NULL,
77+
"providerUserId" TEXT NOT NULL,
78+
"providerData" TEXT NOT NULL DEFAULT '{}',
79+
"authId" TEXT NOT NULL,
80+
81+
PRIMARY KEY ("providerName", "providerUserId"),
82+
CONSTRAINT "AuthIdentity_authId_fkey" FOREIGN KEY ("authId") REFERENCES "Auth" ("id") ON DELETE CASCADE ON UPDATE CASCADE
83+
);
84+
85+
-- CreateTable
86+
CREATE TABLE "Session" (
87+
"id" TEXT NOT NULL PRIMARY KEY,
88+
"expiresAt" DATETIME NOT NULL,
89+
"userId" TEXT NOT NULL,
90+
CONSTRAINT "Session_userId_fkey" FOREIGN KEY ("userId") REFERENCES "Auth" ("id") ON DELETE CASCADE ON UPDATE CASCADE
91+
);
92+
93+
-- CreateIndex
94+
CREATE UNIQUE INDEX "better_auth_user_email_key" ON "better_auth_user"("email");
95+
96+
-- CreateIndex
97+
CREATE UNIQUE INDEX "better_auth_session_token_key" ON "better_auth_session"("token");
98+
99+
-- CreateIndex
100+
CREATE UNIQUE INDEX "Auth_userId_key" ON "Auth"("userId");
101+
102+
-- CreateIndex
103+
CREATE UNIQUE INDEX "Session_id_key" ON "Session"("id");
104+
105+
-- CreateIndex
106+
CREATE INDEX "Session_userId_idx" ON "Session"("userId");

0 commit comments

Comments
 (0)