feat: harden sessions and track downstream acknowledgements
This commit is contained in:
@@ -128,6 +128,8 @@ export class UsersService {
|
||||
async update(id: string, data: UpdateUserDto, scopeTenantId?: string) {
|
||||
const current = await this.getExisting(id, scopeTenantId);
|
||||
const roleCode = data.roleCode ?? current.roles[0]?.role.code as UserRoleCode | undefined;
|
||||
const roleChanged = data.roleCode !== undefined && data.roleCode !== current.roles[0]?.role.code;
|
||||
const tenantChanged = data.tenantId !== undefined && data.tenantId !== current.tenantId;
|
||||
this.assertUserInput({
|
||||
tenantId: data.tenantId ?? current.tenantId ?? undefined,
|
||||
username: data.username ?? current.username,
|
||||
@@ -153,7 +155,7 @@ export class UsersService {
|
||||
phone: data.phone === undefined ? undefined : normalizeOptional(data.phone),
|
||||
displayName: data.displayName ?? current.displayName,
|
||||
status: data.status ?? current.status,
|
||||
...(data.status === 'disabled' && current.status !== 'disabled' ? { sessionVersion: { increment: 1 } } : {}),
|
||||
...((data.status === 'disabled' && current.status !== 'disabled') || roleChanged || tenantChanged ? { sessionVersion: { increment: 1 } } : {}),
|
||||
},
|
||||
include: { tenant: true, roles: { include: { role: true } } },
|
||||
});
|
||||
@@ -235,6 +237,17 @@ export class UsersService {
|
||||
return updated;
|
||||
}
|
||||
|
||||
async verifyCurrentPassword(id: string, password: string) {
|
||||
if (!password) {
|
||||
throw new BadRequestException('请输入当前密码');
|
||||
}
|
||||
const current = await this.getExisting(id);
|
||||
if (current.passwordHash !== hashPassword(password)) {
|
||||
throw new BadRequestException('当前密码不正确');
|
||||
}
|
||||
return current;
|
||||
}
|
||||
|
||||
listRoles() {
|
||||
return this.prisma.role.findMany({
|
||||
include: { permissions: { include: { permission: true } } },
|
||||
@@ -262,18 +275,26 @@ export class UsersService {
|
||||
}
|
||||
|
||||
assignRole(data: AssignRoleDto) {
|
||||
return this.prisma.userRole.upsert({
|
||||
where: { userId_roleId: { userId: data.userId, roleId: data.roleId } },
|
||||
update: {},
|
||||
create: data,
|
||||
return this.prisma.$transaction(async (tx) => {
|
||||
const assignment = await tx.userRole.upsert({
|
||||
where: { userId_roleId: { userId: data.userId, roleId: data.roleId } },
|
||||
update: {},
|
||||
create: data,
|
||||
});
|
||||
await tx.user.update({ where: { id: data.userId }, data: { sessionVersion: { increment: 1 } } });
|
||||
return assignment;
|
||||
});
|
||||
}
|
||||
|
||||
assignPermission(data: AssignPermissionDto) {
|
||||
return this.prisma.rolePermission.upsert({
|
||||
where: { roleId_permissionId: { roleId: data.roleId, permissionId: data.permissionId } },
|
||||
update: {},
|
||||
create: data,
|
||||
return this.prisma.$transaction(async (tx) => {
|
||||
const assignment = await tx.rolePermission.upsert({
|
||||
where: { roleId_permissionId: { roleId: data.roleId, permissionId: data.permissionId } },
|
||||
update: {},
|
||||
create: data,
|
||||
});
|
||||
await tx.user.updateMany({ where: { roles: { some: { roleId: data.roleId } } }, data: { sessionVersion: { increment: 1 } } });
|
||||
return assignment;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user