Files
user-system/frontend/admin/src/lib/device-fingerprint.test.ts
long-agent 0795e126cc fix: resolve P0 security issues per governance baseline
P0-01: LIKE injection fix in device.go (2 locations)
- Added escapeLikePattern() to prevent LIKE pattern manipulation

P0-03: Token refresh blacklist fail-closed
- RefreshToken() now returns error if cache.Set fails
- Prevents token double-spend on cache failures

P0-05: CORS dangerous default configuration
- Default changed to empty origins, credentials off
- init() panics if default config is dangerous

P0-06: UpdateUser IDOR vulnerability fix
- Added authorization check (self-or-admin)
- Prevents unauthorized user profile modification

Also: Fixed frontend lint errors in device-fingerprint.test.ts and http/index.test.ts

All 518 frontend tests pass, all backend tests pass.
2026-04-18 09:32:54 +08:00

138 lines
4.2 KiB
TypeScript

import { describe, expect, it, vi, beforeEach, afterEach } from 'vitest'
import {
getDeviceFingerprint,
clearDeviceFingerprint,
} from './device-fingerprint'
describe('device-fingerprint', () => {
// 保存原始 navigator
const originalNavigator = global.navigator
beforeEach(() => {
// 清除缓存
clearDeviceFingerprint()
vi.clearAllMocks()
})
afterEach(() => {
clearDeviceFingerprint()
global.navigator = originalNavigator
})
describe('getDeviceFingerprint', () => {
it('should return a device fingerprint object', () => {
const fingerprint = getDeviceFingerprint()
expect(fingerprint).toBeDefined()
expect(fingerprint).toHaveProperty('device_id')
expect(fingerprint).toHaveProperty('device_name')
expect(fingerprint).toHaveProperty('device_browser')
expect(fingerprint).toHaveProperty('device_os')
})
it('should return the same fingerprint on multiple calls (singleton)', () => {
const fingerprint1 = getDeviceFingerprint()
const fingerprint2 = getDeviceFingerprint()
expect(fingerprint1).toBe(fingerprint2)
expect(fingerprint1.device_id).toBe(fingerprint2.device_id)
})
it('should return valid device_id', () => {
const fingerprint = getDeviceFingerprint()
expect(fingerprint.device_id).toBeTruthy()
expect(typeof fingerprint.device_id).toBe('string')
expect(fingerprint.device_id.length).toBeGreaterThan(0)
})
it('should return valid device_name format', () => {
const fingerprint = getDeviceFingerprint()
expect(fingerprint.device_name).toBeTruthy()
expect(typeof fingerprint.device_name).toBe('string')
// device_name 格式: "Browser on OS"
expect(fingerprint.device_name).toMatch(/.+\s+on\s+.+/)
})
it('should return valid device_browser', () => {
const fingerprint = getDeviceFingerprint()
expect(fingerprint.device_browser).toBeTruthy()
expect(typeof fingerprint.device_browser).toBe('string')
})
it('should return valid device_os', () => {
const fingerprint = getDeviceFingerprint()
expect(fingerprint.device_os).toBeTruthy()
expect(typeof fingerprint.device_os).toBe('string')
})
})
describe('clearDeviceFingerprint', () => {
it('should clear cached fingerprint', () => {
// 先获取一次生成缓存
const fingerprint1 = getDeviceFingerprint()
// 清除缓存
clearDeviceFingerprint()
// 再次获取应该是新的指纹
const fingerprint2 = getDeviceFingerprint()
// 两个指纹不应该相同
expect(fingerprint1.device_id).not.toBe(fingerprint2.device_id)
})
it('should allow multiple clears without error', () => {
clearDeviceFingerprint()
clearDeviceFingerprint()
clearDeviceFingerprint()
// 不应该抛出错误
expect(true).toBe(true)
})
})
describe('browser detection', () => {
it('should detect browser from user agent', () => {
// 注意:实际测试中 navigator.userAgent 是只读的
// 这里主要验证函数能正常工作
const fingerprint = getDeviceFingerprint()
expect(fingerprint.device_browser).toBeTruthy()
})
})
describe('OS detection', () => {
it('should detect OS from user agent', () => {
// 类似浏览器检测,验证函数能正常工作
const fingerprint = getDeviceFingerprint()
expect(fingerprint.device_os).toBeTruthy()
})
})
describe('security considerations', () => {
it('should not store fingerprint in localStorage', () => {
getDeviceFingerprint()
// 设备指纹不应该存储在 localStorage
const deviceId = localStorage.getItem('device_id')
const fingerprint = localStorage.getItem('device_fingerprint')
expect(deviceId).toBeFalsy() // null or undefined
expect(fingerprint).toBeFalsy()
})
it('should not store fingerprint in sessionStorage', () => {
getDeviceFingerprint()
// 设备指纹不应该存储在 sessionStorage
const deviceId = sessionStorage.getItem('device_id')
const fingerprint = sessionStorage.getItem('device_fingerprint')
expect(deviceId).toBeFalsy()
expect(fingerprint).toBeFalsy()
})
})
})