feat: Implement admin user management features

- Added adminCreateUser endpoint and corresponding DTO for creating users.
- Implemented deleteUser and resetPassword functionalities for admin users.
- Introduced updateEmail functionality for admin users.
- Updated UsersService to handle user creation, deletion, password reset, and email updates.
- Modified UsersController to include new admin routes with appropriate role checks.
- Refactored frontend navigation to link to user management under profile.
- Created new profile tabs for user management and database management.
- Developed AnvandareClient component for user management, including user creation, deletion, role changes, and password resets.
- Added DatabsTab for managing product listings and merging duplicates.
- Enhanced MinProfilTab for user profile management with form handling.
This commit is contained in:
Nils-Johan Gynther
2026-04-18 14:49:02 +02:00
parent 00dc0d6c69
commit 537a4f8ab6
16 changed files with 1141 additions and 66 deletions
+34 -1
View File
@@ -1,5 +1,7 @@
import { Injectable } from '@nestjs/common';
import { Injectable, ConflictException } from '@nestjs/common';
import { PrismaService } from '../prisma/prisma.service';
import * as bcrypt from 'bcryptjs';
import * as crypto from 'crypto';
@Injectable()
export class UsersService {
@@ -31,4 +33,35 @@ export class UsersService {
setRole(id: number, role: string) {
return this.prisma.user.update({ where: { id }, data: { role } });
}
async adminCreate(data: { username: string; email: string; password: string; role?: string }) {
const existing = await this.prisma.user.findFirst({
where: { OR: [{ username: data.username }, { email: data.email }] },
});
if (existing) {
throw new ConflictException(
existing.username === data.username ? 'Användarnamnet är redan taget' : 'E-postadressen används redan',
);
}
const passwordHash = await bcrypt.hash(data.password, 12);
return this.prisma.user.create({
data: { username: data.username, email: data.email, passwordHash, role: data.role ?? 'user' },
});
}
deleteUser(id: number) {
return this.prisma.user.delete({ where: { id } });
}
async resetPassword(id: number): Promise<{ temporaryPassword: string }> {
// Generera läsbart 12-teckens lösenord (4 ord från slumpmässiga bytes)
const temporaryPassword = crypto.randomBytes(9).toString('base64url').slice(0, 12);
const passwordHash = await bcrypt.hash(temporaryPassword, 12);
await this.prisma.user.update({ where: { id }, data: { passwordHash } });
return { temporaryPassword };
}
updateEmail(id: number, email: string) {
return this.prisma.user.update({ where: { id }, data: { email } });
}
}