权限门控(P1-8 剩余): - 新增 resolveAdminPermission(sessionPermissions, code):会话接口的最新权限列表优先, 接口异常才回退登录时的本地快照;空数组也判无权限,避免"刚被收回权限仍能点"。 - 寄售仓库面板:consignment.manage 控制手动入库/编辑/作废/退单回库/匹配开关(无权限时开关禁用)。 - 寄卖提报面板:consignment.review 控制审核入库/驳回。 - 接单平台页:无 consignment.view 不渲染两个寄卖 tab,并把 URL/localStorage 的旧选择拉回工单页。 数据约束(P2-19 剩余): - 迁移 080:allocation_status 历史非法值归位「待安排」(备注留痕)后加 CHECK(待安排/已安排), 并顺手修正 077 遗留的"收集链接/玩家提交"权限描述文案。 - 编辑接口拒绝直接改 allocationStatus(400 consignment_allocation_status_update_forbidden)。 运营体验: - 两个面板补 isError 错误态与重试;审核通过/驳回加 confirmLoading 与提交中守卫(防双提交)。 - 待审徽标改用后端真实总数(原来只统计当前页);编辑弹窗押金不再兜底 ¥100(会误写押金)。 - 履约拦截弹窗冷静期文案不再硬编码"3 天",改为按商品规则设定。 - 核实并撤回"倒计时时区偏移"误报:deadlineAt 为带 Z 的 ISO,前端无偏移问题。 验证:后端 412 例(409 通过)、前端 21 例(新增 5 例权限解析)全绿, typecheck / lint / format / check:sql / build 通过;迁移 001→080 在全新空库跑通并在 dev 库应用。
69 lines
2.6 KiB
TypeScript
69 lines
2.6 KiB
TypeScript
import assert from 'node:assert/strict'
|
|
import test from 'node:test'
|
|
|
|
import { resolveAdminPermission } from '../src/utils/admin-auth.ts'
|
|
|
|
type StorageLike = {
|
|
getItem: (key: string) => string | null
|
|
setItem: (key: string, value: string) => void
|
|
removeItem: (key: string) => void
|
|
}
|
|
|
|
function installLocalStorage(entries: Record<string, string>) {
|
|
const store = new Map(Object.entries(entries))
|
|
const storage: StorageLike = {
|
|
getItem: (key) => (store.has(key) ? (store.get(key) as string) : null),
|
|
setItem: (key, value) => {
|
|
store.set(key, value)
|
|
},
|
|
removeItem: (key) => {
|
|
store.delete(key)
|
|
},
|
|
}
|
|
;(globalThis as { localStorage?: StorageLike }).localStorage = storage
|
|
return store
|
|
}
|
|
|
|
function installAdminSessionSnapshot(permissions: string[]) {
|
|
return installLocalStorage({
|
|
'order-site-admin-token': 'token',
|
|
'order-site-admin-token-expires-at': new Date(Date.now() + 60_000).toISOString(),
|
|
'order-site-admin-permissions': JSON.stringify(permissions),
|
|
})
|
|
}
|
|
|
|
test('会话接口返回的权限列表优先于本地快照(管理员刚收回权限的场景)', () => {
|
|
installAdminSessionSnapshot(['consignment.manage'])
|
|
|
|
// 本地快照里有 manage,但会话接口的最新列表没有 → 以会话为准
|
|
assert.equal(resolveAdminPermission(['consignment.view'], 'consignment.manage'), false)
|
|
assert.equal(resolveAdminPermission(['consignment.view'], 'consignment.view'), true)
|
|
})
|
|
|
|
test('会话返回空权限数组时判定为无权限,不回退本地快照', () => {
|
|
installAdminSessionSnapshot(['consignment.manage', 'consignment.review'])
|
|
|
|
assert.equal(resolveAdminPermission([], 'consignment.manage'), false)
|
|
assert.equal(resolveAdminPermission([], 'consignment.review'), false)
|
|
})
|
|
|
|
test('会话权限缺失(接口失败/未返回)时回退本地快照', () => {
|
|
installAdminSessionSnapshot(['consignment.review'])
|
|
|
|
assert.equal(resolveAdminPermission(undefined, 'consignment.review'), true)
|
|
assert.equal(resolveAdminPermission(null, 'consignment.manage'), false)
|
|
})
|
|
|
|
test('没有登录会话时即使快照里有权限也不放行', () => {
|
|
installLocalStorage({ 'order-site-admin-permissions': JSON.stringify(['consignment.manage']) })
|
|
|
|
assert.equal(resolveAdminPermission(undefined, 'consignment.manage'), false)
|
|
})
|
|
|
|
test('空权限名一律拒绝(避免调用方漏传参数时误放行)', () => {
|
|
installAdminSessionSnapshot(['consignment.manage'])
|
|
|
|
assert.equal(resolveAdminPermission(['consignment.manage'], ''), false)
|
|
assert.equal(resolveAdminPermission([''], 'consignment.manage'), false)
|
|
})
|