Files
Agent-System/web/src/engine/authIntegration.test.ts
T
weichenandCursor a56d033d3c feat(web): fail-closed capabilities and admin roles from server API
Stop persisting roles to localStorage as authority; AdminSettingsModal reads
and writes role matrices via /api/v1/admin/roles; hasPermission denies when
capabilities are not loaded from /auth/me.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:22 +00:00

139 lines
4.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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');
});