Skip to content
This repository was archived by the owner on Jan 28, 2026. It is now read-only.

Commit 296dcdd

Browse files
committed
feat: Implement role-based access control for admin users in AuthService and update user role handling across services
1 parent 736d9d8 commit 296dcdd

6 files changed

Lines changed: 21 additions & 7 deletions

File tree

src/auth/auth.service.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { JwtService } from '@nestjs/jwt';
33
import { ConfigService } from '@nestjs/config';
44
import * as bcrypt from 'bcrypt';
55
import { UserService } from '../user/user.service';
6+
import { UserRepository } from '../user/user.repository';
67
import { RegisterDto } from './dto/register.dto';
78
import { LoginDto } from './dto/login.dto';
89
import { RefreshTokenDto } from './dto/refresh-token.dto';
@@ -13,6 +14,7 @@ export class AuthService {
1314

1415
constructor(
1516
private userService: UserService,
17+
private userRepository: UserRepository,
1618
private jwtService: JwtService,
1719
private configService: ConfigService,
1820
) {}
@@ -44,6 +46,11 @@ export class AuthService {
4446
throw new UnauthorizedException('Неверный email или пароль');
4547
}
4648

49+
// Проверяем, что пользователь имеет роль ADMIN
50+
if (user.role !== 'ADMIN') {
51+
throw new UnauthorizedException('Доступ разрешен только администраторам');
52+
}
53+
4754
const payload = { email: user.email, sub: user.id };
4855
const accessTokenExpiresIn = this.configService.get<string>('JWT_EXPIRES_IN') || '24h';
4956
const refreshTokenExpiresIn = this.configService.get<string>('JWT_REFRESH_EXPIRES_IN') || '7d';
@@ -72,12 +79,19 @@ export class AuthService {
7279
try {
7380
const refreshTokenSecret = this.configService.get<string>('JWT_REFRESH_SECRET') || this.configService.get<string>('JWT_SECRET') || 'your-secret-key';
7481
const payload = this.jwtService.verify(refreshTokenDto.refresh_token, { secret: refreshTokenSecret });
75-
const user = await this.userService.findOne(payload.sub);
82+
83+
// Используем репозиторий для получения оригинальной роли (без форматирования)
84+
const user = await this.userRepository.findById(payload.sub);
7685

7786
if (!user) {
7887
throw new UnauthorizedException('Пользователь не найден');
7988
}
8089

90+
// Проверяем, что пользователь имеет роль ADMIN
91+
if (user.role !== 'ADMIN') {
92+
throw new UnauthorizedException('Доступ разрешен только администраторам');
93+
}
94+
8195
const newPayload = { email: user.email, sub: user.id };
8296
const accessTokenExpiresIn = this.configService.get<string>('JWT_EXPIRES_IN') || '24h';
8397
const refreshTokenExpiresIn = this.configService.get<string>('JWT_REFRESH_EXPIRES_IN') || '7d';

src/user/dto/create-user.dto.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ export const createUserSchema = z.object({
99
email: z.string().email('Некорректный формат email').min(1, 'Email обязателен'),
1010
password: z.string().min(1, 'Пароль обязателен'),
1111
role: z.nativeEnum(UserRole, {
12-
message: 'Роль должна быть одним из: USER, MODERATOR',
12+
message: 'Роль должна быть одним из: USER, ADMIN',
1313
}).optional(),
1414
organisationId: z.number().int().positive('ID организации должен быть положительным числом').nullable().optional(),
1515
});

src/user/dto/update-user-v2.dto.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ export const updateUserV2Schema = z.object({
99
email: z.string().email('Некорректный формат email').optional(),
1010
avatarUrl: z.string().url('Некорректный формат URL').optional(),
1111
role: z.nativeEnum(UserRole, {
12-
message: 'Роль должна быть одним из: USER, MODERATOR',
12+
message: 'Роль должна быть одним из: USER, ADMIN',
1313
}).optional(),
1414
organisationId: z.number().int().positive('ID организации должен быть положительным числом').nullable().optional(),
1515
});

src/user/dto/update-user.dto.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ export const updateUserSchema = z.object({
99
email: z.string().email('Некорректный формат email').optional(),
1010
avatarUrls: z.record(z.number(), z.string()).optional(),
1111
role: z.nativeEnum(UserRole, {
12-
message: 'Роль должна быть одним из: USER, MODERATOR',
12+
message: 'Роль должна быть одним из: USER, ADMIN',
1313
}).optional(),
1414
organisationId: z.number().int().positive('ID организации должен быть положительным числом').nullable().optional(),
1515
});

src/user/user.service.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ export class UserService {
2121
if (role === 'USER') {
2222
return 'пользователь';
2323
}
24-
if (role === 'MODERATOR') {
25-
return 'модератор';
24+
if (role === 'ADMIN') {
25+
return 'администратор';
2626
}
2727
return role;
2828
}

src/user/user.types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
export enum UserRole {
22
USER = 'USER',
3-
MODERATOR = 'MODERATOR',
3+
ADMIN = 'ADMIN',
44
}
55

0 commit comments

Comments
 (0)