61 lines
2.1 KiB
TypeScript
61 lines
2.1 KiB
TypeScript
|
|
import { describe, expect, it, beforeAll } from 'vitest'
|
||
|
|
import {
|
||
|
|
signMentorUploadToken, verifyMentorUploadToken,
|
||
|
|
type MentorUploadPayload,
|
||
|
|
} from '../../src/lib/mentor-upload-token'
|
||
|
|
|
||
|
|
const samplePayload: MentorUploadPayload = {
|
||
|
|
mentorAssignmentId: 'ma-123',
|
||
|
|
uploaderUserId: 'user-456',
|
||
|
|
fileName: 'doc.pdf',
|
||
|
|
mimeType: 'application/pdf',
|
||
|
|
size: 12345,
|
||
|
|
bucket: 'mopc-files',
|
||
|
|
objectKey: 'Project/mentorship/123-doc.pdf',
|
||
|
|
exp: Math.floor(Date.now() / 1000) + 3600,
|
||
|
|
}
|
||
|
|
|
||
|
|
beforeAll(() => {
|
||
|
|
process.env.NEXTAUTH_SECRET = process.env.NEXTAUTH_SECRET || 'test-secret-123'
|
||
|
|
})
|
||
|
|
|
||
|
|
describe('mentor upload token', () => {
|
||
|
|
it('round-trips a payload', () => {
|
||
|
|
const token = signMentorUploadToken(samplePayload)
|
||
|
|
expect(typeof token).toBe('string')
|
||
|
|
expect(token.split('.').length).toBe(2) // payload.signature
|
||
|
|
|
||
|
|
const verified = verifyMentorUploadToken(token)
|
||
|
|
expect(verified.mentorAssignmentId).toBe('ma-123')
|
||
|
|
expect(verified.objectKey).toBe('Project/mentorship/123-doc.pdf')
|
||
|
|
})
|
||
|
|
|
||
|
|
it('rejects a tampered payload', () => {
|
||
|
|
const token = signMentorUploadToken(samplePayload)
|
||
|
|
const [, sig] = token.split('.')
|
||
|
|
const tamperedPayload = Buffer.from(JSON.stringify({ ...samplePayload, size: 999999 })).toString('base64url')
|
||
|
|
const tampered = `${tamperedPayload}.${sig}`
|
||
|
|
expect(() => verifyMentorUploadToken(tampered)).toThrow(/signature/i)
|
||
|
|
})
|
||
|
|
|
||
|
|
it('rejects a token with a different signature', () => {
|
||
|
|
const token = signMentorUploadToken(samplePayload)
|
||
|
|
const [payload] = token.split('.')
|
||
|
|
const bad = `${payload}.0000000000000000000000000000000000000000000000000000000000000000`
|
||
|
|
expect(() => verifyMentorUploadToken(bad)).toThrow(/signature/i)
|
||
|
|
})
|
||
|
|
|
||
|
|
it('rejects an expired token', () => {
|
||
|
|
const expired = signMentorUploadToken({
|
||
|
|
...samplePayload,
|
||
|
|
exp: Math.floor(Date.now() / 1000) - 60,
|
||
|
|
})
|
||
|
|
expect(() => verifyMentorUploadToken(expired)).toThrow(/expired/i)
|
||
|
|
})
|
||
|
|
|
||
|
|
it('rejects a malformed token', () => {
|
||
|
|
expect(() => verifyMentorUploadToken('not-a-token')).toThrow()
|
||
|
|
expect(() => verifyMentorUploadToken('one-segment')).toThrow()
|
||
|
|
})
|
||
|
|
})
|