feat: admin set password for users + fix dashboard cache error

Admin Set Password:
- New setPassword adminProcedure in user router (Argon2 hashing)
- Audit log: "Password reset by admin" (no password value logged)
- UI: per-user "Password" button with key icon in User Management
- Modal: new password + confirm, min 8 chars, mismatch validation
- Success toast + auto-close on completion

Dashboard fix:
- Corrupted .next cache causing "Cannot find module worker.js"
- Fixed by clearing .next cache and restarting dev server

Co-Authored-By: claude-flow <ruv@ruv.net>
This commit is contained in:
2026-03-23 09:32:38 +01:00
parent 208f866d68
commit bc6afefeae
3 changed files with 226 additions and 150 deletions
+35
View File
@@ -126,6 +126,41 @@ export const userRouter = createTRPCRouter({
return user;
}),
setPassword: adminProcedure
.input(
z.object({
userId: z.string(),
password: z.string().min(8, "Password must be at least 8 characters"),
}),
)
.mutation(async ({ ctx, input }) => {
const user = await ctx.db.user.findUniqueOrThrow({
where: { id: input.userId },
select: { id: true, name: true, email: true },
});
const { hash } = await import("@node-rs/argon2");
const passwordHash = await hash(input.password);
await ctx.db.user.update({
where: { id: input.userId },
data: { passwordHash },
});
void createAuditEntry({
db: ctx.db,
entityType: "User",
entityId: user.id,
entityName: `${user.name} (${user.email})`,
action: "UPDATE",
...(ctx.dbUser?.id ? { userId: ctx.dbUser.id } : {}),
source: "ui",
summary: "Password reset by admin",
});
return { success: true };
}),
updateRole: adminProcedure
.input(
z.object({