95 lines
2.6 KiB
TypeScript

import assert from 'node:assert/strict'
import test from 'node:test'
import { unsafeOriginGuard } from '../originGuard'
const originalEnv = {
nodeEnv: process.env.NODE_ENV,
publicBaseUrl: process.env.APP_PUBLIC_BASE_URL,
centerUrl: process.env.YYD_NOTIFICATION_CENTER_URL,
corsOrigins: process.env.CORS_ALLOWED_ORIGINS
}
test.before(() => {
process.env.NODE_ENV = 'production'
process.env.APP_PUBLIC_BASE_URL = 'https://asset.example.com'
process.env.YYD_NOTIFICATION_CENTER_URL = 'https://sc.example.com/notification-center'
process.env.CORS_ALLOWED_ORIGINS = ''
})
test.after(() => {
for (const [key, value] of Object.entries({
NODE_ENV: originalEnv.nodeEnv,
APP_PUBLIC_BASE_URL: originalEnv.publicBaseUrl,
YYD_NOTIFICATION_CENTER_URL: originalEnv.centerUrl,
CORS_ALLOWED_ORIGINS: originalEnv.corsOrigins
})) {
if (value === undefined) delete process.env[key]
else process.env[key] = value
}
})
const runGuard = (input: { method: string; origin?: string; path: string }) => {
const state = { status: 200, body: null as any, nextCalls: 0 }
const req = {
method: input.method,
protocol: 'https',
path: input.path,
get(name: string) {
if (name === 'host') return 'asset.example.com'
if (name === 'origin') return input.origin
return undefined
}
}
const res = {
status(code: number) {
state.status = code
return this
},
json(body: any) {
state.body = body
return this
}
}
unsafeOriginGuard(req as any, res as any, () => {
state.nextCalls += 1
})
return state
}
test('恶意同站来源的资产写操作在进入业务路由前返回403', () => {
const result = runGuard({
method: 'POST',
origin: 'https://sc.example.com',
path: '/api/equipment'
})
assert.equal(result.status, 403)
assert.equal(result.nextCalls, 0)
assert.deepEqual(result.body, { code: 403, message: '请求来源不允许', data: null })
})
test('通知中心来源只可进入一次性票据回调', () => {
assert.equal(runGuard({
method: 'POST',
origin: 'https://sc.example.com',
path: '/api/dingtalk/broker-login'
}).nextCalls, 1)
assert.equal(runGuard({
method: 'DELETE',
origin: 'https://sc.example.com',
path: '/api/equipment/1'
}).status, 403)
})
test('钉钉 WebView 的 null Origin 只可进入一次性票据回调', () => {
assert.equal(runGuard({
method: 'POST',
origin: 'null',
path: '/api/dingtalk/broker-login'
}).nextCalls, 1)
assert.equal(runGuard({
method: 'POST',
origin: 'null',
path: '/api/equipment'
}).status, 403)
})