feat: add admin profile editing capability

Added admin endpoint and functionality for editing user profiles from the
report management interface:

Backend Changes:
- Added PUT /api/users/:id endpoint for admin-only profile editing
- Reuses existing updateUserSettings logic with slug uniqueness validation
- Protected with adminGuard and csrfProtection
- Proper audit logging for admin profile edits

Frontend Changes:
- Added adminUpdateUser() method to UserService
- Updated editProfile() in admin-reports to load profile and allow bio editing
- Uses prompt for quick bio editing (can be expanded to full form later)
- Shows success/error toasts and refreshes report list after edit

Admins can now quickly edit reported user profiles directly from the
report management interface.
This commit is contained in:
2026-02-19 20:05:57 -08:00
committed by Naomi Carrigan
parent 6e884b9ae8
commit c154ef1897
3 changed files with 61 additions and 3 deletions
+34
View File
@@ -255,6 +255,40 @@ const usersRoutes: FastifyPluginAsync = async (app) => {
return user;
}
);
app.put<{ Params: { id: string }; Body: UpdateUserSettingsBody; Reply: User | { error: string } }>(
"/:id",
{
preValidation: [app.authenticate, adminGuard],
preHandler: [app.csrfProtection],
},
async (request, reply) => {
const { id } = request.params;
const updates = request.body;
// If slug is being updated, check if it's unique
if (updates.slug) {
const existingUser = await userService.getUserBySlug(updates.slug);
if (existingUser && existingUser.id !== id) {
return reply.code(400).send({ error: "Slug already taken" });
}
}
const updatedUser = await userService.updateUserSettings(id, updates);
if (!updatedUser) {
return reply.code(404).send({ error: "User not found" });
}
await AuditService.logFromRequest(request, {
action: AuditAction.entryUpdate,
category: AuditCategory.admin,
targetUserId: id,
details: `Admin updated profile for user: ${updatedUser.username}`,
});
return updatedUser;
}
);
};
export default usersRoutes;