Skip to content

Commit 3b10b13

Browse files
feat: Blitz RPC endpoint to the app directory (#4341)
* feat: make `rpchandler` work with `Request` and return a `Response` * rename: rpcRequestHandler * feat: improvements * blitz-auth now works * return headers * working * cleanup * working sveltekit, with regressin of next.js app dir * cleanup * pnpm lock fix * Update packages/blitz-auth/src/server/auth-plugin.ts * fix build * more work * fixes * fix issues with auth * maybe required breaking change * pointless test * Update packages/blitz-auth/package.json * fixes * fix * get all tests passing * more fixes * changeset * fixes * fix * pnpm lock update * fix * update pnpm lcok * revert unnecessary changes * imporve api naming * cleanup * fix * Update integration-tests/next-13-app-dir/src/blitz-server.ts * Apply suggestions from code review * remove unrelated changes * Update packages/blitz-auth/src/server/auth-sessions.ts * fix types * fix overload * remove dependence on http module * review changes * oops * fix * fix types * Revert "fix types" This reverts commit b06a4fb. * Revert "fix" This reverts commit 47d0cdd. * Revert "oops" This reverts commit 94cb558. * Revert "review changes" This reverts commit 14d8eb2. * fix the logic * sort deps * template fixes * chore: add changeset * chore: remove outdated changeset * fix changeset formatting * Update .changeset/tidy-gorillas-confess.md * remove `blitzAuthRpcMiddleware` * remove uses of any * fix jsdoc * no var * separate the type imports * fix unsupported method of session in rsc * fix * api changes * Apply suggestions from code review Co-authored-by: Brandon Bayer <[email protected]> * Apply suggestions from code review * Update .changeset/tidy-gorillas-confess.md * fix * fic --------- Co-authored-by: Brandon Bayer <[email protected]>
1 parent 2560175 commit 3b10b13

File tree

62 files changed

+1329
-700
lines changed

Some content is hidden

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

62 files changed

+1329
-700
lines changed

.changeset/tidy-gorillas-confess.md

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
---
2+
"blitz": minor
3+
"@blitzjs/auth": minor
4+
"@blitzjs/next": minor
5+
"@blitzjs/rpc": minor
6+
"@blitzjs/generator": minor
7+
---
8+
9+
feat: add blitz auth support for the Web `Request` API standard
10+
11+
Usage using the new `withBlitzAuth` adapter in the App Router:
12+
13+
```ts
14+
import {withBlitzAuth} from "app/blitz-server"
15+
16+
export const {POST} = withBlitzAuth({
17+
POST: async (_request, _params, ctx) => {
18+
const session = ctx.session
19+
await session.$revoke()
20+
21+
return new Response(
22+
JSON.stringify({
23+
userId: session.userId,
24+
}),
25+
{status: 200},
26+
)
27+
},
28+
})
29+
```
30+
31+
feat: New Blitz RPC handler meant to with the next.js app router `route.ts` files
32+
33+
Usage using the new `rpcAppHandler` function
34+
35+
```ts
36+
// app/api/rpc/[[...blitz]]/route.ts
37+
import {rpcAppHandler} from "@blitzjs/rpc"
38+
import {withBlitzAuth} from "app/blitz-server"
39+
40+
// Usage with blitz auth
41+
export const {GET, POST, HEAD} = withBlitzAuth(rpcAppHandler())
42+
43+
// Standalone usage
44+
export const {GET, POST, HEAD} = rpcAppHandler()
45+
```
46+
47+
chore: Update the app directory starter

.github/workflows/main.yml

+4-4
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ jobs:
2323
- name: Setup node
2424
uses: actions/setup-node@v2
2525
with:
26-
node-version: 18
26+
node-version: 20
2727
cache: "pnpm"
2828
- name: Install dependencies
2929
run: pnpm install --frozen-lockfile
@@ -44,7 +44,7 @@ jobs:
4444
- name: Setup node
4545
uses: actions/setup-node@v2
4646
with:
47-
node-version: 18
47+
node-version: 20
4848
cache: "pnpm"
4949
- run: pnpm install --frozen-lockfile
5050
- name: Build
@@ -75,7 +75,7 @@ jobs:
7575
- name: Setup node@16
7676
uses: actions/setup-node@v2
7777
with:
78-
node-version: 18
78+
node-version: 20
7979
cache: "pnpm"
8080

8181
- name: Install dependencies
@@ -137,7 +137,7 @@ jobs:
137137
if: matrix.folder != 'next-13-app-dir' || matrix.os != 'windows-latest'
138138
uses: actions/setup-node@v2
139139
with:
140-
node-version: 18
140+
node-version: 20
141141
cache: "pnpm"
142142

143143
- name: Install dependencies

apps/next13/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
"@tanstack/react-query": "4.0.10",
2323
"blitz": "2.0.10",
2424
"flatted": "3.2.7",
25-
"next": "canary",
25+
"next": "14.3.0-canary.28",
2626
"prisma": "^4.5.0",
2727
"react": "18.2.0",
2828
"react-dom": "18.2.0",

apps/next13/prisma/dev.db

0 Bytes
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import {rpcAppHandler} from "@blitzjs/rpc"
2+
import {withBlitzAuth} from "src/blitz-server"
3+
4+
export const {GET, POST, HEAD} = withBlitzAuth(rpcAppHandler())

apps/next13/src/blitz-server.ts

+20-19
Original file line numberDiff line numberDiff line change
@@ -6,26 +6,27 @@ import {simpleRolesIsAuthorized} from "@blitzjs/auth"
66
import {BlitzLogger} from "blitz"
77
import {RpcServerPlugin} from "@blitzjs/rpc"
88

9-
const {api, getBlitzContext, useAuthenticatedBlitzContext, invoke} = setupBlitzServer({
10-
plugins: [
11-
AuthServerPlugin({
12-
cookiePrefix: "web-cookie-prefix",
13-
storage: PrismaStorage(db),
14-
isAuthorized: simpleRolesIsAuthorized,
15-
}),
16-
RpcServerPlugin({
17-
logging: {
18-
disablelevel: "debug",
19-
},
20-
onInvokeError(error) {
21-
console.log("onInvokeError", error)
22-
},
23-
}),
24-
],
25-
logger: BlitzLogger({}),
26-
})
9+
const {api, getBlitzContext, useAuthenticatedBlitzContext, invoke, withBlitzAuth} =
10+
setupBlitzServer({
11+
plugins: [
12+
AuthServerPlugin({
13+
cookiePrefix: "web-cookie-prefix",
14+
storage: PrismaStorage(db),
15+
isAuthorized: simpleRolesIsAuthorized,
16+
}),
17+
RpcServerPlugin({
18+
logging: {
19+
disablelevel: "debug",
20+
},
21+
onInvokeError(error) {
22+
console.log("onInvokeError", error)
23+
},
24+
}),
25+
],
26+
logger: BlitzLogger({}),
27+
})
2728

28-
export {api, getBlitzContext, useAuthenticatedBlitzContext, invoke}
29+
export {api, getBlitzContext, useAuthenticatedBlitzContext, invoke, withBlitzAuth}
2930

3031
export const cliConfig: BlitzCliConfig = {
3132
customTemplates: "src/templates",

apps/next13/src/pages/api/rpc/[[...blitz]].ts

-4
This file was deleted.

apps/next13/src/users/queries/getCurrentUser.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,5 @@ export default async function getCurrentUser(input: null, ctx: Ctx) {
1212
}
1313

1414
export const config = {
15-
httpMethod: "GET",
15+
httpMethod: "POST",
1616
}

apps/toolkit-app-passportjs/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
"@hookform/resolvers": "2.9.10",
3232
"@prisma/client": "4.6.1",
3333
"blitz": "2.0.10",
34-
"next": "canary",
34+
"next": "14.3.0-canary.28",
3535
"openid-client": "5.2.1",
3636
"prisma": "4.6.1",
3737
"react": "18.2.0",

apps/toolkit-app/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
"@hookform/resolvers": "2.9.10",
3333
"@prisma/client": "4.6.1",
3434
"blitz": "2.0.10",
35-
"next": "canary",
35+
"next": "14.3.0-canary.28",
3636
"next-auth": "4.24.7",
3737
"prisma": "4.6.1",
3838
"react": "18.2.0",

apps/toolkit-app/src/pages/auth/login.tsx apps/toolkit-app/src/pages/login.tsx

+1-5
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,11 @@ const LoginPage: BlitzPage = () => {
1111
<LoginForm
1212
onSuccess={(_user) => {
1313
const next = router.query.next ? decodeURIComponent(router.query.next as string) : "/"
14-
// return router.push(next)
14+
return router.push(next)
1515
}}
1616
/>
1717
</Layout>
1818
)
1919
}
2020

21-
LoginPage.authenticate = {
22-
redirectTo: "/",
23-
}
24-
2521
export default LoginPage

apps/web/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
"blitz": "2.0.10",
2727
"jest": "29.3.0",
2828
"jest-environment-jsdom": "29.3.0",
29-
"next": "canary",
29+
"next": "14.3.0-canary.28",
3030
"passport-mock-strategy": "2.0.0",
3131
"passport-twitter": "1.0.4",
3232
"prisma": "4.6.1",

integration-tests/auth-with-rpc/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
"@prisma/client": "4.6.1",
2727
"blitz": "2.0.10",
2828
"delay": "5.0.0",
29-
"next": "canary",
29+
"next": "14.3.0-canary.28",
3030
"prisma": "4.6.1",
3131
"react": "18.2.0",
3232
"react-dom": "18.2.0",

integration-tests/auth/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
"@prisma/client": "4.6.1",
2424
"blitz": "2.0.10",
2525
"lowdb": "3.0.0",
26-
"next": "canary",
26+
"next": "14.3.0-canary.28",
2727
"prisma": "4.6.1",
2828
"react": "18.2.0",
2929
"react-dom": "18.2.0",

integration-tests/auth/pages/api/signin.ts

+2-5
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,11 @@ export const authenticateUser = async (email: string, password: string) => {
2121
}
2222

2323
export default api(async (req, res, ctx) => {
24-
const blitzContext = ctx
25-
2624
const user = await authenticateUser(req.query.email as string, req.query.password as string)
27-
28-
await blitzContext.session.$create({
25+
await ctx.session.$create({
2926
userId: user.id,
3027
role: user.role as Role,
3128
})
3229

33-
res.status(200).json({email: req.query.email, userId: blitzContext.session.userId})
30+
res.status(200).json({email: req.query.email, userId: ctx.session.userId})
3431
})

integration-tests/get-initial-props/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
"@prisma/client": "4.6.1",
2323
"blitz": "2.0.10",
2424
"lowdb": "3.0.0",
25-
"next": "canary",
25+
"next": "14.3.0-canary.28",
2626
"prisma": "4.6.1",
2727
"react": "18.2.0",
2828
"react-dom": "18.2.0"

integration-tests/middleware/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"@blitzjs/next": "2.0.10",
1616
"@blitzjs/rpc": "2.0.10",
1717
"blitz": "2.0.10",
18-
"next": "canary",
18+
"next": "14.3.0-canary.28",
1919
"react": "18.2.0",
2020
"react-dom": "18.2.0"
2121
},
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import {withBlitzAuth} from "../../../src/blitz-server"
2+
3+
export const {POST} = withBlitzAuth({
4+
POST: async (_request, _params, ctx) => {
5+
const session = ctx.session
6+
await session.$revoke()
7+
8+
return new Response(
9+
JSON.stringify({
10+
userId: session.userId,
11+
}),
12+
{status: 200},
13+
)
14+
},
15+
})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import {H} from "@blitzjs/auth/dist/index-0ecbee46"
2+
import {withBlitzAuth} from "../../../src/blitz-server"
3+
4+
const emptyResponse = async () => {
5+
return new Response(null, {status: 200})
6+
}
7+
8+
export const {POST, HEAD} = withBlitzAuth({
9+
POST: emptyResponse,
10+
HEAD: emptyResponse,
11+
})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import {rpcAppHandler} from "@blitzjs/rpc"
2+
import {withBlitzAuth} from "../../../../src/blitz-server"
3+
4+
export const {GET, POST, HEAD} = withBlitzAuth(rpcAppHandler())
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import {withBlitzAuth} from "../../../src/blitz-server"
2+
import prisma from "../../../db/index"
3+
import {Role} from "../../../types"
4+
5+
export const authenticateUser = async (email: string, password: string) => {
6+
const user = await prisma.user.findFirst({where: {email}})
7+
8+
if (!user) throw new Error("Authentication Error")
9+
await prisma.user.update({where: {id: user.id}, data: {hashedPassword: password}})
10+
11+
const {hashedPassword, ...rest} = user
12+
return rest
13+
}
14+
15+
export const {POST} = withBlitzAuth({
16+
POST: async (request: Request, context, ctx) => {
17+
const {searchParams} = new URL(request.url)
18+
const user = await authenticateUser(
19+
searchParams.get("email") as string,
20+
searchParams.get("password") as string,
21+
)
22+
23+
await ctx.session.$create({
24+
userId: user.id,
25+
role: user.role as Role,
26+
})
27+
28+
return new Response(
29+
JSON.stringify({email: searchParams.get("email"), userId: ctx.session.userId}),
30+
{
31+
status: 200,
32+
headers: {
33+
"Content-Type": "application/json",
34+
},
35+
},
36+
)
37+
},
38+
})
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
/// <reference types="next" />
22
/// <reference types="next/image-types/global" />
3-
/// <reference types="next/navigation-types/compat/navigation" />
43

54
// NOTE: This file should not be edited
65
// see https://nextjs.org/docs/basic-features/typescript for more information.

integration-tests/next-13-app-dir/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
"@prisma/client": "4.6.1",
2525
"blitz": "2.0.10",
2626
"lowdb": "3.0.0",
27-
"next": "canary",
27+
"next": "14.3.0-canary.28",
2828
"prisma": "4.6.1",
2929
"react": "18.2.0",
3030
"react-dom": "18.2.0",
@@ -45,6 +45,6 @@
4545
"node-fetch": "3.2.3",
4646
"playwright": "1.28.0",
4747
"ts-node": "10.9.1",
48-
"typescript": "^4.8.4"
48+
"typescript": "^4.9.5"
4949
}
5050
}

integration-tests/next-13-app-dir/pages/api/logout.ts

-9
This file was deleted.

integration-tests/next-13-app-dir/pages/api/noauth.ts

-5
This file was deleted.

integration-tests/next-13-app-dir/pages/api/rpc/[[...blitz]].ts

-4
This file was deleted.

0 commit comments

Comments
 (0)