81 lines
2.5 KiB
TypeScript
81 lines
2.5 KiB
TypeScript
/** @jest-environment node */
|
|
|
|
import { createHash } from 'crypto'
|
|
import {
|
|
consumeDingtalkSessionTicket,
|
|
createDingtalkSessionTicket,
|
|
} from '@/lib/dingtalk-session-ticket'
|
|
|
|
describe('DingTalk one-time session ticket', () => {
|
|
const originalUseRedis = process.env.USE_REDIS
|
|
const originalRedisUrl = process.env.REDIS_URL
|
|
|
|
beforeEach(() => {
|
|
process.env.USE_REDIS = 'false'
|
|
delete process.env.REDIS_URL
|
|
})
|
|
|
|
afterAll(() => {
|
|
if (originalUseRedis === undefined) delete process.env.USE_REDIS
|
|
else process.env.USE_REDIS = originalUseRedis
|
|
|
|
if (originalRedisUrl === undefined) delete process.env.REDIS_URL
|
|
else process.env.REDIS_URL = originalRedisUrl
|
|
})
|
|
|
|
test('必须匹配原内网地址和浏览器绑定值,且只能消费一次', async () => {
|
|
const binding = 'binding-for-original-browser'
|
|
const ticketId = await createDingtalkSessionTicket({
|
|
userId: 'user-1',
|
|
redirectPath: '/admin?tab=users',
|
|
targetOrigin: 'http://192.168.58.20:4320',
|
|
handoffId: 'handoff-1',
|
|
handoffBindingHash: createHash('sha256').update(binding).digest('hex'),
|
|
})
|
|
|
|
await expect(
|
|
consumeDingtalkSessionTicket(ticketId, {
|
|
expectedTargetOrigin: 'http://192.168.58.20:4320',
|
|
expectedHandoffBinding: 'other-browser-binding',
|
|
}),
|
|
).resolves.toBeNull()
|
|
|
|
await expect(
|
|
consumeDingtalkSessionTicket(ticketId, {
|
|
expectedTargetOrigin: 'http://192.168.58.20:4321',
|
|
expectedHandoffBinding: binding,
|
|
}),
|
|
).resolves.toBeNull()
|
|
|
|
await expect(
|
|
consumeDingtalkSessionTicket(ticketId, {
|
|
expectedTargetOrigin: 'http://192.168.58.20:4320',
|
|
expectedHandoffBinding: binding,
|
|
}),
|
|
).resolves.toMatchObject({
|
|
userId: 'user-1',
|
|
redirectPath: '/admin?tab=users',
|
|
targetOrigin: 'http://192.168.58.20:4320',
|
|
})
|
|
|
|
await expect(
|
|
consumeDingtalkSessionTicket(ticketId, {
|
|
expectedTargetOrigin: 'http://192.168.58.20:4320',
|
|
expectedHandoffBinding: binding,
|
|
}),
|
|
).resolves.toBeNull()
|
|
})
|
|
|
|
test('现有仅写 Cookie 的会话票据仍能正常消费', async () => {
|
|
const ticketId = await createDingtalkSessionTicket({
|
|
redirectPath: '/performance-survey',
|
|
cookies: ['next-auth.session-token=test-token; Path=/; HttpOnly'],
|
|
})
|
|
|
|
await expect(consumeDingtalkSessionTicket(ticketId)).resolves.toMatchObject({
|
|
redirectPath: '/performance-survey',
|
|
cookies: ['next-auth.session-token=test-token; Path=/; HttpOnly'],
|
|
})
|
|
})
|
|
})
|