Product UI no longer switches sessions locally; API clients attach Bearer tokens only and LocalAuthClient stays test-only outside the prod bundle.
115 lines
3.7 KiB
TypeScript
115 lines
3.7 KiB
TypeScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import { createInMemoryAuthClient } from './auth.local';
|
|
|
|
test('AuthClient: 基础登录与 .env 超级管理员鉴权', async () => {
|
|
const client = createInMemoryAuthClient({
|
|
adminUsername: 'admin',
|
|
adminPassword: 'admin-password-123',
|
|
env: 'dev',
|
|
});
|
|
|
|
// 1. 错误密码登录失败
|
|
await assert.rejects(
|
|
async () => {
|
|
await client.login({ username: 'admin', password: 'wrong-password' });
|
|
},
|
|
/用户名或密码错误/
|
|
);
|
|
|
|
// 2. 正确管理员登录
|
|
const session = await client.login({ username: 'admin', password: 'admin-password-123' });
|
|
assert.equal(session.user.username, 'admin');
|
|
assert.equal(session.user.roleId, 'role-admin');
|
|
assert.equal(session.env, 'dev');
|
|
assert.ok(session.token.length > 0);
|
|
});
|
|
|
|
test('AuthClient: 自主注册受控流程(仅填用户名密码姓名,职位强制绑定访客待指派)', async () => {
|
|
const client = createInMemoryAuthClient({
|
|
allowRegistration: true,
|
|
requireApproval: false,
|
|
});
|
|
|
|
// 1. 缺少必填项报错
|
|
await assert.rejects(
|
|
async () => {
|
|
await client.register({ username: 'doc_li', password: '', name: '李医生' });
|
|
},
|
|
/必填/
|
|
);
|
|
|
|
// 2. 正常注册
|
|
const regResult = await client.register({
|
|
username: 'doc_li',
|
|
password: 'Password123',
|
|
name: '李医生',
|
|
department: '临床医学部',
|
|
});
|
|
assert.equal(regResult.status, 'active');
|
|
|
|
// 3. 登录验证职位与角色为 role-guest / 访客/待指派
|
|
const session = await client.login({ username: 'doc_li', password: 'Password123' });
|
|
assert.equal(session.user.name, '李医生');
|
|
assert.equal(session.user.roleId, 'role-guest');
|
|
assert.equal(session.user.position, '访客/待指派');
|
|
assert.equal(session.mustChangePassword, false);
|
|
});
|
|
|
|
test('AuthClient: 开启注册需审批时,注册账号处于待审状态并禁止登录', async () => {
|
|
const client = createInMemoryAuthClient({
|
|
allowRegistration: true,
|
|
requireApproval: true,
|
|
});
|
|
|
|
const regResult = await client.register({
|
|
username: 'intern_wang',
|
|
password: 'Pass456789',
|
|
name: '王实习',
|
|
});
|
|
assert.equal(regResult.status, 'pending_approval');
|
|
assert.match(regResult.message, /审核/);
|
|
|
|
// 登录拦截
|
|
await assert.rejects(
|
|
async () => {
|
|
await client.login({ username: 'intern_wang', password: 'Pass456789' });
|
|
},
|
|
/审核/
|
|
);
|
|
|
|
// 管理员通过审核并指派为助理工程师
|
|
await client.updateUserStatus(regResult.userId!, 'active', 'role-engineer', '助理工程师');
|
|
|
|
// 再次登录成功
|
|
const session = await client.login({ username: 'intern_wang', password: 'Pass456789' });
|
|
assert.equal(session.user.status, 'active');
|
|
assert.equal(session.user.roleId, 'role-engineer');
|
|
assert.equal(session.user.position, '助理工程师');
|
|
});
|
|
|
|
test('AuthClient: 管理员创建账号必须在首次登录修改密码', async () => {
|
|
const client = createInMemoryAuthClient();
|
|
|
|
// 1. 管理员开通账号
|
|
const created = await client.createAdminUser({
|
|
username: 'lead_zhao',
|
|
name: '赵主管',
|
|
initialPassword: 'TempInitPass123',
|
|
roleId: 'role-tech-lead',
|
|
position: '技术主管',
|
|
});
|
|
assert.equal(created.mustChangePassword, true);
|
|
|
|
// 2. 首次登录
|
|
const session = await client.login({ username: 'lead_zhao', password: 'TempInitPass123' });
|
|
assert.equal(session.mustChangePassword, true);
|
|
|
|
// 3. 修改密码
|
|
await client.changePassword(session.user.id, 'TempInitPass123', 'NewPermanentPassword888');
|
|
|
|
// 4. 用新密码登录,mustChangePassword 变为 false
|
|
const updatedSession = await client.login({ username: 'lead_zhao', password: 'NewPermanentPassword888' });
|
|
assert.equal(updatedSession.mustChangePassword, false);
|
|
});
|