docs(quick-260914-ebg): Kopfkommentar adminResetPassword — Schwesterwege PATCH/DELETE /users/:id geschlossen (WINDOWS #29)

- auth.service.ts: letzter Satz des Kopfkommentars ueber adminResetPassword nennt T-FH9-05 nicht mehr als offen, sondern verweist auf den seit 260914-ebg (WINDOWS #29) identischen Riegel in UserController.update()/remove()
- Falsifizierung: Rueckbau des Task-1-Commits (git apply -R) macht Test 9 und Test 13 rot (Tests  2 failed | 14 passed (16)), danach byte-identisch wiederhergestellt (git checkout --, git status --porcelain leer)
- Rule 1 Nebenfund: acht neue Tests in user.controller.spec.ts trugen sechs ueberfluessige `as any`-Umschreibungen (UpdateUserDto ist vollstaendig optional, siehe planning_measurements), die die Biome-Warnungen dieser Datei von 25 auf 31 trieben — entfernt, damit die relative Biome-Schwelle der Baseline (25) wieder eingehalten wird, ohne die Schwelle anzuheben

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018N9CD3ebPKm1b32bPpBknY
This commit is contained in:
2026-09-14 10:37:40 +02:00
parent 759ea3b2ca
commit 63f9df0afb
2 changed files with 9 additions and 8 deletions
+3 -2
View File
@@ -404,8 +404,9 @@ export class AuthService {
* `BadRequestException` nennt weder Halter noch Mandanten. Der Riegel * `BadRequestException` nennt weder Halter noch Mandanten. Der Riegel
* unten schliesst zusaetzlich die Rechteausweitung INNERHALB des * unten schliesst zusaetzlich die Rechteausweitung INNERHALB des
* Mandanten (T-FH9-04): ein Nicht-SUPER_ADMIN darf das Kennwort eines * Mandanten (T-FH9-04): ein Nicht-SUPER_ADMIN darf das Kennwort eines
* SUPER_ADMIN nicht setzen. Der Schwesterweg `PATCH /users/:id` hat * SUPER_ADMIN nicht setzen. Die Schwesterwege `PATCH /users/:id` und
* dieselbe Luecke nicht geschlossen — offener Ledger-Eintrag T-FH9-05. * `DELETE /users/:id` tragen seit 260914-ebg (WINDOWS #29) denselben
* Riegel in `UserController.update()`/`remove()`.
*/ */
async adminResetPassword( async adminResetPassword(
tenantId: string, tenantId: string,
+6 -6
View File
@@ -284,17 +284,17 @@ describe('UserController', () => {
userService.findById.mockResolvedValue({ id: 'boss', tenantId: 't1', role: Role.SUPER_ADMIN }); userService.findById.mockResolvedValue({ id: 'boss', tenantId: 't1', role: Role.SUPER_ADMIN });
await expect( await expect(
controller.update('boss', { password: 'fresh-password' } as any, admin), controller.update('boss', { password: 'fresh-password' }, admin),
).rejects.toThrow('Cannot modify a SUPER_ADMIN user'); ).rejects.toThrow('Cannot modify a SUPER_ADMIN user');
expect(userService.update).not.toHaveBeenCalled(); expect(userService.update).not.toHaveBeenCalled();
await expect( await expect(
controller.update('boss', { isActive: false } as any, admin), controller.update('boss', { isActive: false }, admin),
).rejects.toThrow('Cannot modify a SUPER_ADMIN user'); ).rejects.toThrow('Cannot modify a SUPER_ADMIN user');
expect(userService.update).not.toHaveBeenCalled(); expect(userService.update).not.toHaveBeenCalled();
await expect( await expect(
controller.update('boss', { role: Role.USER } as any, admin), controller.update('boss', { role: Role.USER }, admin),
).rejects.toThrow('Cannot modify a SUPER_ADMIN user'); ).rejects.toThrow('Cannot modify a SUPER_ADMIN user');
expect(userService.update).not.toHaveBeenCalled(); expect(userService.update).not.toHaveBeenCalled();
}); });
@@ -313,7 +313,7 @@ describe('UserController', () => {
passwordHash: 'h', passwordHash: 'h',
}); });
const result = await controller.update('boss', { password: 'fresh-password' } as any, superAdmin); const result = await controller.update('boss', { password: 'fresh-password' }, superAdmin);
expect(userService.update).toHaveBeenCalledWith( expect(userService.update).toHaveBeenCalledWith(
't1', 't1',
@@ -328,7 +328,7 @@ describe('UserController', () => {
userService.findById.mockResolvedValue({ id: 'u1', tenantId: 't1', role: Role.USER }); userService.findById.mockResolvedValue({ id: 'u1', tenantId: 't1', role: Role.USER });
userService.update.mockResolvedValue({ id: 'u1', tenantId: 't1', role: Role.USER }); userService.update.mockResolvedValue({ id: 'u1', tenantId: 't1', role: Role.USER });
await controller.update('u1', { displayName: 'Neu' } as any, admin); await controller.update('u1', { displayName: 'Neu' }, admin);
expect(userService.update).toHaveBeenCalledWith( expect(userService.update).toHaveBeenCalledWith(
't1', 't1',
@@ -342,7 +342,7 @@ describe('UserController', () => {
userService.findById.mockResolvedValue({ id: 'boss2', tenantId: 't2', role: Role.SUPER_ADMIN }); userService.findById.mockResolvedValue({ id: 'boss2', tenantId: 't2', role: Role.SUPER_ADMIN });
await expect( await expect(
controller.update('boss2', { displayName: 'Neu' } as any, admin), controller.update('boss2', { displayName: 'Neu' }, admin),
).rejects.toThrow('Cannot modify users from other tenants'); ).rejects.toThrow('Cannot modify users from other tenants');
expect(userService.update).not.toHaveBeenCalled(); expect(userService.update).not.toHaveBeenCalled();
}); });