import test from 'node:test'; import assert from 'node:assert/strict'; import { createInMemoryAuthClient } from '../api/auth.local'; import { DEFAULT_ROLES, hasPermission } from './rbac'; import { UserProfile } from '../types/docgov'; test('全链路场景 1: 用户自主受控注册(仅填用户名/密码/姓名,职位严格绑定访客待指派)', async () => { const client = createInMemoryAuthClient({ allowRegistration: true, requireApproval: false, env: 'dev', }); // 1. 自主注册新员工 const regRes = await client.register({ username: 'new_intern', password: 'InternPass123', name: '陈实习', department: '微创器械研发部', employeeId: 'INT-001', }); assert.equal(regRes.status, 'active'); assert.match(regRes.message, /成功/); // 2. 登录并校验角色为 role-guest,职位为 访客/待指派 const session = await client.login({ username: 'new_intern', password: 'InternPass123', }); assert.equal(session.user.name, '陈实习'); assert.equal(session.user.roleId, 'role-guest'); assert.equal(session.user.position, '访客/待指派'); // 3. 校验访客默认无项目立项与权限管理能力 const profile: UserProfile = session.user; const guestCaps = DEFAULT_ROLES.find((r) => r.id === 'role-guest')?.permissions ?? []; assert.equal(hasPermission(profile, DEFAULT_ROLES, 'project:create', guestCaps), false); assert.equal(hasPermission(profile, DEFAULT_ROLES, 'perm:manage', guestCaps), false); }); test('全链路场景 2: 系统准入策略(关闭自主注册与开启强制审批流转)', async () => { const client = createInMemoryAuthClient({ allowRegistration: false, requireApproval: true, env: 'test', }); // 1. 关闭自主注册时拦截 await assert.rejects( async () => { await client.register({ username: 'outsider', password: 'Pass123456', name: '外协人员', }); }, /暂停自主注册/ ); // 2. 管理员开启注册但要求审批 await client.updateSystemAuthConfig({ allowRegistration: true, requireApproval: true, }); const regRes = await client.register({ username: 'outsider', password: 'Pass123456', name: '外协人员', }); assert.equal(regRes.status, 'pending_approval'); // 3. 待审状态禁止登录 await assert.rejects( async () => { await client.login({ username: 'outsider', password: 'Pass123456' }); }, /审核/ ); // 4. 管理员审核通过并授予工程师职位 await client.updateUserStatus(regRes.userId!, 'active', 'role-engineer', '方案工程师'); // 5. 再次登录成功激活 const session = await client.login({ username: 'outsider', password: 'Pass123456' }); assert.equal(session.user.status, 'active'); assert.equal(session.user.roleId, 'role-engineer'); assert.equal(session.user.position, '方案工程师'); }); test('全链路场景 3: 管理员开通账号首次强制改密闭环', async () => { const client = createInMemoryAuthClient({ adminUsername: 'admin', adminPassword: 'admin-password-123', }); // 1. 管理员开通新员工账号 const created = await client.createAdminUser({ username: 'sun_engineer', name: '孙工', initialPassword: 'InitPassword123', roleId: 'role-engineer', position: '方案工程师', department: '骨科器械组', }); assert.equal(created.mustChangePassword, true); // 2. 孙工首次登录,返回 mustChangePassword = true const session = await client.login({ username: 'sun_engineer', password: 'InitPassword123', }); assert.equal(session.mustChangePassword, true); // 3. 执行首次强制改密 await client.changePassword(session.user.id, 'InitPassword123', 'SunNewSecret999'); // 4. 再次登录,验证 mustChangePassword 复位为 false const freshSession = await client.login({ username: 'sun_engineer', password: 'SunNewSecret999', }); assert.equal(freshSession.mustChangePassword, false); }); test('全链路场景 4: 环境标识随登录会话返回(dev/test/main)', async () => { const devClient = createInMemoryAuthClient({ env: 'dev' }); const devSession = await devClient.login({ username: 'admin', password: 'admin-secret-password-123' }); assert.equal(devSession.env, 'dev'); const testClient = createInMemoryAuthClient({ env: 'test' }); const testSession = await testClient.login({ username: 'admin', password: 'admin-secret-password-123' }); assert.equal(testSession.env, 'test'); const prodClient = createInMemoryAuthClient({ env: 'main' }); const prodSession = await prodClient.login({ username: 'admin', password: 'admin-secret-password-123' }); assert.equal(prodSession.env, 'main'); });