Skip to content

Commit b532f31

Browse files
refactor(cloudflare-access): decode token types (#1717)
1 parent f64569e commit b532f31

File tree

9 files changed

+175
-101
lines changed

9 files changed

+175
-101
lines changed

packages/auth-js/eslint-suppressions.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717
"@typescript-eslint/await-thenable": {
1818
"count": 1
1919
},
20+
"@typescript-eslint/no-unnecessary-type-conversion": {
21+
"count": 1
22+
},
2023
"@typescript-eslint/no-unsafe-assignment": {
2124
"count": 6
2225
}
Lines changed: 1 addition & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1 @@
1-
{
2-
"src/index.test.ts": {
3-
"@typescript-eslint/no-base-to-string": {
4-
"count": 1
5-
},
6-
"@typescript-eslint/no-unsafe-assignment": {
7-
"count": 2
8-
},
9-
"@typescript-eslint/require-await": {
10-
"count": 3
11-
}
12-
},
13-
"src/index.ts": {
14-
"@typescript-eslint/no-unsafe-argument": {
15-
"count": 1
16-
},
17-
"@typescript-eslint/no-unsafe-assignment": {
18-
"count": 4
19-
},
20-
"@typescript-eslint/no-unsafe-member-access": {
21-
"count": 3
22-
}
23-
}
24-
}
1+
{}

packages/cloudflare-access/src/index.test.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ function base64URLEncode(str: string): string {
8080

8181
function generateJWT(
8282
privateKey: string,
83-
payload: Record<string, any>,
83+
payload: Record<string, unknown>,
8484
expiresIn: number = 3600
8585
): string {
8686
// Create header
@@ -120,7 +120,7 @@ describe('Cloudflare Access middleware', async () => {
120120

121121
beforeEach(() => {
122122
vi.clearAllMocks()
123-
vi.stubGlobal('fetch', async () => {
123+
vi.stubGlobal('fetch', () => {
124124
return Response.json({
125125
keys: [publicKeyToJWK(keyPair1.publicKey), publicKeyToJWK(keyPair2.publicKey)],
126126
})
@@ -277,13 +277,13 @@ describe('Cloudflare Access middleware', async () => {
277277
expect(await res.json()).toEqual({
278278
sub: '1234567890',
279279
iss: 'https://my-cool-team-name.cloudflareaccess.com',
280-
iat: expect.any(Number),
281-
exp: expect.any(Number),
280+
iat: expect.any(Number) as number,
281+
exp: expect.any(Number) as number,
282282
})
283283
})
284284

285285
it('Should throw an error, if the access organization does not exist', async () => {
286-
vi.stubGlobal('fetch', async () => {
286+
vi.stubGlobal('fetch', () => {
287287
return Response.json({ success: false }, { status: 404 })
288288
})
289289

@@ -300,7 +300,7 @@ describe('Cloudflare Access middleware', async () => {
300300
})
301301

302302
it('Should throw an error, if the access certs url is unavailable', async () => {
303-
vi.stubGlobal('fetch', async () => {
303+
vi.stubGlobal('fetch', () => {
304304
return Response.json({ success: false }, { status: 500 })
305305
})
306306

packages/cloudflare-access/src/index.ts

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ export const cloudflareAccess = (accessTeamName: string): MiddlewareHandler => {
5555
let token
5656
try {
5757
token = decodeJwt(encodedToken)
58-
} catch (err) {
58+
} catch {
5959
return c.text('Authentication error: Unable to decode Bearer token', 401)
6060
}
6161

@@ -108,7 +108,7 @@ async function getPublicKeys(accessTeamName: string) {
108108
})
109109
}
110110

111-
const data: any = await result.json()
111+
const data = await result.json<{ keys: JsonWebKeyWithKid[] }>()
112112

113113
// Because we keep CryptoKey's in memory between requests, we need to make sure they are refreshed once in a while
114114
const cacheExpiration = Math.floor(Date.now() / 1000) + 3600 // 1h
@@ -142,20 +142,16 @@ function getJwt(c: Context) {
142142
}
143143

144144
function decodeJwt(token: string): DecodedToken {
145-
const parts = token.split('.')
146-
if (parts.length !== 3) {
145+
const [header, payload, signature] = token.split('.')
146+
if (!header || !payload || !signature) {
147147
throw new Error('Invalid token')
148148
}
149149

150-
const header = JSON.parse(atob(parts[0] as string))
151-
const payload = JSON.parse(atob(parts[1] as string))
152-
const signature = atob((parts[2] as string).replace(/_/g, '/').replace(/-/g, '+'))
153-
154150
return {
155-
header: header,
156-
payload: payload,
157-
signature: signature,
158-
raw: { header: parts[0], payload: parts[1], signature: parts[2] },
151+
header: JSON.parse(atob(header)) as object,
152+
payload: JSON.parse(atob(payload)) as CloudflareAccessPayload,
153+
signature: atob(signature.replace(/_/g, '/').replace(/-/g, '+')),
154+
raw: { header, payload, signature },
159155
}
160156
}
161157

@@ -178,8 +174,8 @@ async function isValidJwtSignature(token: DecodedToken, keys: Record<string, Cry
178174

179175
async function validateSingleKey(
180176
key: CryptoKey,
181-
signature: Uint8Array,
182-
data: Uint8Array
177+
signature: BufferSource,
178+
data: BufferSource
183179
): Promise<boolean> {
184180
return crypto.subtle.verify('RSASSA-PKCS1-v1_5', key, signature, data)
185181
}

packages/eslint-config/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,6 @@
2929
"eslint-import-resolver-typescript": "^4.2.2",
3030
"eslint-plugin-import-x": "^4.1.1",
3131
"eslint-plugin-n": "^17.10.2",
32-
"typescript-eslint": "^8.27.0"
32+
"typescript-eslint": "^8.53.1"
3333
}
3434
}

packages/mcp/eslint-suppressions.json

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,6 @@
7676
}
7777
},
7878
"src/auth/middleware/client-auth.ts": {
79-
"@typescript-eslint/no-base-to-string": {
80-
"count": 1
81-
},
8279
"@typescript-eslint/no-unsafe-assignment": {
8380
"count": 1
8481
}

packages/swagger-ui/eslint-suppressions.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
{
22
"src/index.test.ts": {
3+
"@typescript-eslint/no-unnecessary-type-conversion": {
4+
"count": 4
5+
},
36
"@typescript-eslint/restrict-template-expressions": {
47
"count": 2
58
}

packages/ua-blocker/eslint-suppressions.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@
44
"count": 1
55
}
66
},
7+
"src/ai-bots.test.ts": {
8+
"@typescript-eslint/await-thenable": {
9+
"count": 1
10+
}
11+
},
712
"src/ai-bots.ts": {
813
"@typescript-eslint/require-await": {
914
"count": 1

0 commit comments

Comments
 (0)