From ce2aa35a24ab351433ae7bb98aba2cab38c7e676 Mon Sep 17 00:00:00 2001 From: liuyun Date: Sat, 10 Oct 2026 23:22:43 +0800 Subject: [PATCH] fix: strip passwordHash from user API responses Co-Authored-By: Claude Opus 4.8 --- src/users/users.service.ts | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/src/users/users.service.ts b/src/users/users.service.ts index 03e976d..1fb11cf 100644 --- a/src/users/users.service.ts +++ b/src/users/users.service.ts @@ -14,8 +14,9 @@ export class UsersService extends BaseCrudService { async createUser(dto: CreateUserDto) { const passwordHash = await bcrypt.hash(dto.password, 10); - const { password: _p, ...rest } = dto; - return this.create({ ...rest, passwordHash }); + const { password: _pw, ...rest } = dto; + const created = await this.create({ ...rest, passwordHash }); + return this.omitPasswordHash(created); } async listUsers(q: PageQuery) { @@ -25,15 +26,35 @@ export class UsersService extends BaseCrudService { if (ctx && ctx.orgCodes.length > 0) { where.orgCode = { in: ctx.orgCodes }; } - return this.paginate(q.page, q.pageSize, where); + const result = await this.paginate(q.page, q.pageSize, where); + result.list = result.list.map((u: { passwordHash?: unknown }) => this.omitPasswordHash(u)); + return result; + } + + async findById(id: string) { + const user = await super.findById(id); + return user ? this.omitPasswordHash(user) : user; } async updateUser(id: string, dto: UpdateUserDto) { - return this.update(id, { ...dto }); + const updated = await this.update(id, { ...dto }); + return this.omitPasswordHash(updated); } async resetPassword(id: string, dto: ResetPasswordDto) { const passwordHash = await bcrypt.hash(dto.password, 10); - return this.update(id, { passwordHash }); + const updated = await this.update(id, { passwordHash }); + return this.omitPasswordHash(updated); + } + + async softRemove(id: string) { + const removed = await super.softRemove(id); + return this.omitPasswordHash(removed); + } + + /** 响应边界剥掉 passwordHash,避免泄漏(登录内部校验直接查库,不受影响)。 */ + private omitPasswordHash(row: T): Omit { + const { passwordHash: _passwordHash, ...rest } = row; + return rest; } }