Skip to content

Commit faea361

Browse files
authored
Merge pull request #52 from cipherstash/generic-next-middleware
feat: add generic next middleware
2 parents 2ece15f + 7d0fac0 commit faea361

4 files changed

Lines changed: 95 additions & 53 deletions

File tree

.changeset/brave-steaks-fly.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@cipherstash/nextjs": minor
3+
---
4+
5+
Implemented a generic Next.js jseql middleware.

packages/nextjs/src/clerk/index.ts

Lines changed: 4 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import type { ClerkMiddlewareAuth } from '@clerk/nextjs/server'
22
import type { NextRequest } from 'next/server'
33
import { NextResponse } from 'next/server'
4-
import { CS_COOKIE_NAME, type CtsToken } from '../index'
4+
import { CS_COOKIE_NAME, resetCtsToken } from '../index'
5+
import { setCtsToken } from '../cts'
56
import { logger } from '../../../utils/logger'
67

78
export const jseqlClerkMiddleware = async (
@@ -22,65 +23,15 @@ export const jseqlClerkMiddleware = async (
2223
return NextResponse.next()
2324
}
2425

25-
const workspaceId = process.env.CS_WORKSPACE_ID
26-
27-
if (!workspaceId) {
28-
logger.error(
29-
'The "CS_WORKSPACE_ID" environment variable is not set, and is required by jseqlClerkMiddleware. No CipherStash session will be set.',
30-
)
31-
32-
return NextResponse.next()
33-
}
34-
35-
const ctsEndoint =
36-
process.env.CS_CTS_ENDPOINT ||
37-
'https://ap-southeast-2.aws.auth.viturhosted.net'
38-
39-
const ctsResponse = await fetch(`${ctsEndoint}/api/authorize`, {
40-
method: 'POST',
41-
headers: {
42-
'Content-Type': 'application/json',
43-
},
44-
body: JSON.stringify({
45-
workspaceId,
46-
oidcToken,
47-
}),
48-
})
49-
50-
if (!ctsResponse.ok) {
51-
logger.debug(`Failed to fetch CTS token: ${ctsResponse.statusText}`)
52-
53-
logger.error(
54-
'There was an issue communicating with the CipherStash CTS API, the CipherStash session was not set. If the issue persists, please contact support.',
55-
)
56-
57-
return NextResponse.next()
58-
}
59-
60-
const cts_token = (await ctsResponse.json()) as CtsToken
61-
62-
// Setting cookies on the request and response using the `ResponseCookies` API
63-
const response = NextResponse.next()
64-
response.cookies.set({
65-
name: CS_COOKIE_NAME,
66-
value: JSON.stringify(cts_token),
67-
expires: new Date(cts_token.expiry * 1000),
68-
sameSite: 'lax',
69-
path: '/',
70-
})
71-
72-
response.cookies.get(CS_COOKIE_NAME)
73-
return response
26+
return await setCtsToken(oidcToken)
7427
}
7528

7629
if (!userId && ctsSession) {
7730
logger.debug(
7831
'No Clerk token found in the request, so the CipherStash session was reset.',
7932
)
8033

81-
const response = NextResponse.next()
82-
response.cookies.delete(CS_COOKIE_NAME)
83-
return response
34+
return resetCtsToken()
8435
}
8536

8637
logger.debug(

packages/nextjs/src/cts/index.ts

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import { NextResponse } from 'next/server'
2+
import { logger } from '../../../utils/logger'
3+
import { CS_COOKIE_NAME, type CtsToken } from '../index'
4+
5+
export const setCtsToken = async (oidcToken: string) => {
6+
const workspaceId = process.env.CS_WORKSPACE_ID
7+
8+
if (!workspaceId) {
9+
logger.error(
10+
'The "CS_WORKSPACE_ID" environment variable is not set, and is required by jseqlClerkMiddleware. No CipherStash session will be set.',
11+
)
12+
13+
return NextResponse.next()
14+
}
15+
16+
const ctsEndoint =
17+
process.env.CS_CTS_ENDPOINT ||
18+
'https://ap-southeast-2.aws.auth.viturhosted.net'
19+
20+
const ctsResponse = await fetch(`${ctsEndoint}/api/authorize`, {
21+
method: 'POST',
22+
headers: {
23+
'Content-Type': 'application/json',
24+
},
25+
body: JSON.stringify({
26+
workspaceId,
27+
oidcToken,
28+
}),
29+
})
30+
31+
if (!ctsResponse.ok) {
32+
logger.debug(`Failed to fetch CTS token: ${ctsResponse.statusText}`)
33+
34+
logger.error(
35+
'There was an issue communicating with the CipherStash CTS API, the CipherStash session was not set. If the issue persists, please contact support.',
36+
)
37+
38+
return NextResponse.next()
39+
}
40+
41+
const cts_token = (await ctsResponse.json()) as CtsToken
42+
43+
// Setting cookies on the request and response using the `ResponseCookies` API
44+
const response = NextResponse.next()
45+
response.cookies.set({
46+
name: CS_COOKIE_NAME,
47+
value: JSON.stringify(cts_token),
48+
expires: new Date(cts_token.expiry * 1000),
49+
sameSite: 'lax',
50+
path: '/',
51+
})
52+
53+
response.cookies.get(CS_COOKIE_NAME)
54+
return response
55+
}

packages/nextjs/src/index.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1+
import type { NextRequest } from 'next/server'
2+
import { NextResponse } from 'next/server'
13
import { cookies } from 'next/headers'
4+
import { setCtsToken } from './cts'
25
import { logger } from '../../utils/logger'
36

47
export const CS_COOKIE_NAME = '__cipherstash_cts_session'
@@ -20,3 +23,31 @@ export const getCtsToken = async () => {
2023
const cts_token = JSON.parse(cookieData) as CtsToken
2124
return cts_token
2225
}
26+
27+
export const resetCtsToken = () => {
28+
const response = NextResponse.next()
29+
response.cookies.delete(CS_COOKIE_NAME)
30+
return response
31+
}
32+
33+
export const jseqlMiddleware = async (oidcToken: string, req: NextRequest) => {
34+
const ctsSession = req.cookies.has(CS_COOKIE_NAME)
35+
36+
if (oidcToken && !ctsSession) {
37+
return await setCtsToken(oidcToken)
38+
}
39+
40+
if (!oidcToken && ctsSession) {
41+
logger.debug(
42+
'The JWT token was undefined, so the CipherStash session was reset.',
43+
)
44+
45+
return resetCtsToken()
46+
}
47+
48+
logger.debug(
49+
'The JWT token was undefined, so the CipherStash session was not set.',
50+
)
51+
52+
return NextResponse.next()
53+
}

0 commit comments

Comments
 (0)