diff --git a/apps/api/src/admin/admin.service.spec.ts b/apps/api/src/admin/admin.service.spec.ts index 2a9c6fd..647b5c9 100644 --- a/apps/api/src/admin/admin.service.spec.ts +++ b/apps/api/src/admin/admin.service.spec.ts @@ -24,7 +24,15 @@ describe("AdminService", () => { workspaceMember: { create: vi.fn(), }, - $transaction: vi.fn(), + session: { + deleteMany: vi.fn(), + }, + $transaction: vi.fn(async (ops) => { + if (typeof ops === "function") { + return ops(mockPrismaService); + } + return Promise.all(ops); + }), }; const mockAdminId = "550e8400-e29b-41d4-a716-446655440001"; @@ -82,10 +90,6 @@ describe("AdminService", () => { service = module.get(AdminService); vi.clearAllMocks(); - - mockPrismaService.$transaction.mockImplementation(async (fn: (tx: unknown) => unknown) => { - return fn(mockPrismaService); - }); }); it("should be defined", () => { @@ -325,12 +329,13 @@ describe("AdminService", () => { }); describe("deactivateUser", () => { - it("should set deactivatedAt on the user", async () => { + it("should set deactivatedAt and invalidate sessions", async () => { mockPrismaService.user.findUnique.mockResolvedValue(mockUser); mockPrismaService.user.update.mockResolvedValue({ ...mockUser, deactivatedAt: new Date(), }); + mockPrismaService.session.deleteMany.mockResolvedValue({ count: 3 }); const result = await service.deactivateUser(mockUserId); @@ -341,6 +346,7 @@ describe("AdminService", () => { data: { deactivatedAt: expect.any(Date) }, }) ); + expect(mockPrismaService.session.deleteMany).toHaveBeenCalledWith({ where: { userId: mockUserId } }); }); it("should throw NotFoundException if user does not exist", async () => { diff --git a/apps/api/src/admin/admin.service.ts b/apps/api/src/admin/admin.service.ts index e228ad6..b4add35 100644 --- a/apps/api/src/admin/admin.service.ts +++ b/apps/api/src/admin/admin.service.ts @@ -192,19 +192,22 @@ export class AdminService { throw new BadRequestException(`User ${id} is already deactivated`); } - const user = await this.prisma.user.update({ - where: { id }, - data: { deactivatedAt: new Date() }, - include: { - workspaceMemberships: { - include: { - workspace: { select: { id: true, name: true } }, + const [user] = await this.prisma.$transaction([ + this.prisma.user.update({ + where: { id }, + data: { deactivatedAt: new Date() }, + include: { + workspaceMemberships: { + include: { + workspace: { select: { id: true, name: true } }, + }, }, }, - }, - }); + }), + this.prisma.session.deleteMany({ where: { userId: id } }), + ]); - this.logger.log(`User deactivated: ${id}`); + this.logger.log(`User deactivated and sessions invalidated: ${id}`); return { id: user.id,