Files
botfights/server/src/middleware/jwt.test.ts
T

83 lines
2.4 KiB
TypeScript
Raw Normal View History

import { describe, it, expect, vi, afterEach } from 'vitest'
import { createJwt, verifyJwt, blacklistJwt } from './jwt.js'
describe('JWT', () => {
afterEach(() => {
vi.useRealTimers()
})
it('creates a valid JWT that can be verified', () => {
const token = createJwt('abc123pubkey', 'bot-1')
const payload = verifyJwt(token)
expect(payload).not.toBeNull()
expect(payload!.sub).toBe('abc123pubkey')
expect(payload!.botId).toBe('bot-1')
expect(payload!.iat).toBeDefined()
expect(payload!.exp).toBeGreaterThan(payload!.iat)
})
it('creates JWT without botId', () => {
const token = createJwt('pubkey-only')
const payload = verifyJwt(token)
expect(payload).not.toBeNull()
expect(payload!.sub).toBe('pubkey-only')
expect(payload!.botId).toBeUndefined()
})
it('rejects expired JWT', () => {
vi.useFakeTimers()
const token = createJwt('pubkey-expire')
// Advance time past 24h expiry
vi.advanceTimersByTime(25 * 60 * 60 * 1000)
const payload = verifyJwt(token)
expect(payload).toBeNull()
})
it('rejects tampered payload', () => {
const token = createJwt('original-pubkey')
const parts = token.split('.')
// Tamper with payload — change the pubkey
const tampered = Buffer.from(JSON.stringify({
sub: 'hacker-pubkey',
iat: Math.floor(Date.now() / 1000),
exp: Math.floor(Date.now() / 1000) + 86400,
})).toString('base64url')
const tamperedToken = `${parts[0]}.${tampered}.${parts[2]}`
const payload = verifyJwt(tamperedToken)
expect(payload).toBeNull()
})
it('rejects tampered signature', () => {
const token = createJwt('pubkey-sig-test')
const parts = token.split('.')
const badSig = parts[2].split('').reverse().join('')
const tamperedToken = `${parts[0]}.${parts[1]}.${badSig}`
const payload = verifyJwt(tamperedToken)
expect(payload).toBeNull()
})
it('rejects malformed tokens', () => {
expect(verifyJwt('')).toBeNull()
expect(verifyJwt('not-a-jwt')).toBeNull()
expect(verifyJwt('a.b')).toBeNull()
expect(verifyJwt('a.b.c.d')).toBeNull()
})
it('rejects blacklisted JWT (logout)', () => {
const token = createJwt('pubkey-logout', 'bot-logout')
// Token works before blacklisting
expect(verifyJwt(token)).not.toBeNull()
// Blacklist the token
blacklistJwt(token)
// Token is now rejected
expect(verifyJwt(token)).toBeNull()
})
})