feat: add token create/validate utilities
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
import { createToken, validateToken } from '../token'
|
||||
import { prisma } from '../prisma'
|
||||
|
||||
jest.mock('../prisma', () => ({
|
||||
prisma: {
|
||||
downloadToken: {
|
||||
create: jest.fn(),
|
||||
findUnique: jest.fn(),
|
||||
},
|
||||
},
|
||||
}))
|
||||
|
||||
const mockCreate = (prisma.downloadToken.create as jest.Mock)
|
||||
const mockFindUnique = (prisma.downloadToken.findUnique as jest.Mock)
|
||||
|
||||
describe('createToken', () => {
|
||||
it('inserts a DownloadToken and returns the token string', async () => {
|
||||
mockCreate.mockResolvedValue({ token: 'generated-token' })
|
||||
|
||||
const result = await createToken('dl-id-1')
|
||||
|
||||
expect(mockCreate).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
data: expect.objectContaining({ downloadId: 'dl-id-1' }),
|
||||
})
|
||||
)
|
||||
expect(result).toBe('generated-token')
|
||||
})
|
||||
})
|
||||
|
||||
describe('validateToken', () => {
|
||||
it('returns null when token not found', async () => {
|
||||
mockFindUnique.mockResolvedValue(null)
|
||||
expect(await validateToken('bad')).toBeNull()
|
||||
})
|
||||
|
||||
it('returns null when token is expired', async () => {
|
||||
mockFindUnique.mockResolvedValue({
|
||||
expiresAt: new Date(Date.now() - 1000),
|
||||
download: { id: 'dl-1', filePath: '/storage/abc.mp4' },
|
||||
})
|
||||
expect(await validateToken('expired-tok')).toBeNull()
|
||||
})
|
||||
|
||||
it('returns null when filePath is null', async () => {
|
||||
mockFindUnique.mockResolvedValue({
|
||||
expiresAt: new Date(Date.now() + 3_600_000),
|
||||
download: { id: 'dl-1', filePath: null },
|
||||
})
|
||||
expect(await validateToken('tok')).toBeNull()
|
||||
})
|
||||
|
||||
it('returns downloadId and filePath for a valid token', async () => {
|
||||
mockFindUnique.mockResolvedValue({
|
||||
expiresAt: new Date(Date.now() + 3_600_000),
|
||||
download: { id: 'dl-1', filePath: '/storage/abc.mp4' },
|
||||
})
|
||||
expect(await validateToken('tok')).toEqual({
|
||||
downloadId: 'dl-1',
|
||||
filePath: '/storage/abc.mp4',
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,25 @@
|
||||
import { prisma } from './prisma'
|
||||
import { config } from '../../config/app.config'
|
||||
|
||||
export async function createToken(downloadId: string): Promise<string> {
|
||||
const expiresAt = new Date(
|
||||
Date.now() + config.DOWNLOAD_LINK_TTL_HOURS * 60 * 60 * 1000
|
||||
)
|
||||
const record = await prisma.downloadToken.create({
|
||||
data: { downloadId, expiresAt },
|
||||
})
|
||||
return record.token
|
||||
}
|
||||
|
||||
export async function validateToken(
|
||||
token: string
|
||||
): Promise<{ downloadId: string; filePath: string } | null> {
|
||||
const record = await prisma.downloadToken.findUnique({
|
||||
where: { token },
|
||||
include: { download: { select: { id: true, filePath: true } } },
|
||||
})
|
||||
if (!record) return null
|
||||
if (record.expiresAt < new Date()) return null
|
||||
if (!record.download.filePath) return null
|
||||
return { downloadId: record.download.id, filePath: record.download.filePath }
|
||||
}
|
||||
Reference in New Issue
Block a user