(token: string, secret: string)
| 56 | } |
| 57 | |
| 58 | export function verifyUserToken(token: string, secret: string): Omit<UserTokenPayload, "exp"> | null { |
| 59 | const idx = token.lastIndexOf("."); |
| 60 | if (idx <= 0) return null; |
| 61 | const body = token.slice(0, idx); |
| 62 | const sig = token.slice(idx + 1); |
| 63 | const expected = sign(body, secret); |
| 64 | |
| 65 | try { |
| 66 | if (!timingSafeEqual(Buffer.from(sig), Buffer.from(expected))) return null; |
| 67 | const parsed = JSON.parse(unbase64url(body).toString("utf8")) as UserTokenPayload; |
| 68 | if (parsed.exp < Date.now()) return null; |
| 69 | return { |
| 70 | userId: parsed.userId, |
| 71 | username: parsed.username, |
| 72 | role: parsed.role, |
| 73 | status: parsed.status, |
| 74 | }; |
| 75 | } catch { |
| 76 | return null; |
| 77 | } |
| 78 | } |
no test coverage detected