feat(user-settings): avatar delete + accent color
- DELETE /users/me/avatar endpoint with file cleanup - PATCH /users/me/accent-color with hex validation (#rrggbb) - auth.service.ts: include accentColor in user select - AccountSettingsForm: delete-avatar button + accent color picker/save/reset - auth-actions.ts: deleteAvatarAction + updateAccentColorAction Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -200,6 +200,7 @@ export class AuthService {
|
||||
passwordHash: true,
|
||||
ldapDn: true,
|
||||
avatarPath: true,
|
||||
accentColor: true,
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -272,6 +272,54 @@ export class UserController {
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
/**
|
||||
* DELETE /users/me/avatar
|
||||
* Remove the current user's profile picture.
|
||||
*/
|
||||
@Delete('me/avatar')
|
||||
async deleteAvatar(@CurrentUser() currentUser: any) {
|
||||
const user = await this.prisma.user.findUnique({
|
||||
where: { id: currentUser.id },
|
||||
select: { avatarPath: true },
|
||||
});
|
||||
|
||||
if (user?.avatarPath) {
|
||||
const monorepoRoot = path.resolve(__dirname, '..', '..', '..', '..');
|
||||
const absolutePath = path.join(monorepoRoot, user.avatarPath);
|
||||
if (fs.existsSync(absolutePath)) {
|
||||
fs.unlinkSync(absolutePath);
|
||||
}
|
||||
await this.prisma.user.update({
|
||||
where: { id: currentUser.id },
|
||||
data: { avatarPath: null },
|
||||
});
|
||||
}
|
||||
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
/**
|
||||
* PATCH /users/me/accent-color
|
||||
* Set or clear the current user's accent color.
|
||||
* T-acc-01: hex color validated server-side.
|
||||
*/
|
||||
@Patch('me/accent-color')
|
||||
async updateAccentColor(
|
||||
@Body() body: { color: string | null },
|
||||
@CurrentUser() currentUser: any,
|
||||
) {
|
||||
if (body.color !== null && body.color !== undefined && !/^#[0-9a-fA-F]{6}$/.test(body.color)) {
|
||||
throw new BadRequestException('Invalid color format. Use hex (#rrggbb).');
|
||||
}
|
||||
|
||||
await this.prisma.user.update({
|
||||
where: { id: currentUser.id },
|
||||
data: { accentColor: body.color ?? null },
|
||||
});
|
||||
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
/**
|
||||
* GET /users/me/avatar
|
||||
* Stream the current user's avatar image.
|
||||
|
||||
Reference in New Issue
Block a user