-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy pathjwt-utils.ts
More file actions
43 lines (40 loc) · 1.22 KB
/
jwt-utils.ts
File metadata and controls
43 lines (40 loc) · 1.22 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import { decodeJwt, jwtVerify } from 'jose'
import type { JwtPayload } from './auth-schemas'
import { jwtPayloadSchema } from './auth-schemas'
/** Decode without verification. Use only for non-auth cases (e.g. reading exp for cookie maxAge). */
export function decodeJwtToken({ token }: { token: string }): JwtPayload | null {
try {
const decoded = decodeJwt(token)
const parsed = jwtPayloadSchema.safeParse(decoded)
return parsed.success ? parsed.data : null
} catch {
return null
}
}
export async function verifyJwtToken({
token,
secret,
}: {
token: string
secret: string
}): Promise<JwtPayload | null> {
try {
const { payload } = await jwtVerify(token, new TextEncoder().encode(secret))
const parsed = jwtPayloadSchema.safeParse(payload)
return parsed.success ? parsed.data : null
} catch {
return null
}
}
export function isTokenExpired({ token }: { token: string }): boolean {
try {
const parts = token.split('.')
const payloadPart = parts[1]
if (parts.length !== 3 || !payloadPart) return true
const payload = JSON.parse(atob(payloadPart)) as { exp?: number }
if (!payload?.exp) return true
return payload.exp * 1000 <= Date.now()
} catch {
return true
}
}