-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Add project frontend API with tests and fix backend project API #25
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,4 +4,4 @@ Still on progress | |
|
||
CodeFox | ||
LOGO | ||
![](./assets/WechatIMG1000.svg) | ||
![](./assets/WechatIMG1000.svg) |
Original file line number | Diff line number | Diff line change | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,12 @@ | ||||||||||||||
import { Injectable } from '@nestjs/common'; | ||||||||||||||
import { Query, Resolver } from '@nestjs/graphql'; | ||||||||||||||
import { RequireRoles } from './decorator/auth.decorator'; | ||||||||||||||
|
||||||||||||||
Comment on lines
+1
to
+4
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove unused The Apply this diff to remove the unused import: -import { Injectable } from '@nestjs/common';
import { Query, Resolver } from '@nestjs/graphql';
import { RequireRoles } from './decorator/auth.decorator'; 📝 Committable suggestion
Suggested change
🧰 Tools🪛 GitHub Check: autofix
|
||||||||||||||
@Resolver() | ||||||||||||||
export class AppResolver { | ||||||||||||||
@Query(() => String) | ||||||||||||||
@RequireRoles('Admin') | ||||||||||||||
getHello(): string { | ||||||||||||||
return 'Hello World!'; | ||||||||||||||
} | ||||||||||||||
} | ||||||||||||||
Comment on lines
+5
to
+12
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Consider using role enum instead of hard-coded string. Using string literals for role names can lead to maintenance issues. Consider using an enum for role definitions to ensure type safety and maintainability. Create a roles enum and use it in the decorator: // src/common/enums/roles.enum.ts
export enum Roles {
ADMIN = 'Admin',
// Add other roles as needed
}
// In this file:
@RequireRoles(Roles.ADMIN) |
This file was deleted.
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -2,6 +2,7 @@ | |||||||||||||||||||||||||||||||||||||
ConflictException, | ||||||||||||||||||||||||||||||||||||||
Injectable, | ||||||||||||||||||||||||||||||||||||||
Logger, | ||||||||||||||||||||||||||||||||||||||
NotFoundException, | ||||||||||||||||||||||||||||||||||||||
UnauthorizedException, | ||||||||||||||||||||||||||||||||||||||
} from '@nestjs/common'; | ||||||||||||||||||||||||||||||||||||||
import { ConfigService } from '@nestjs/config'; | ||||||||||||||||||||||||||||||||||||||
|
@@ -11,9 +12,11 @@ | |||||||||||||||||||||||||||||||||||||
import { LoginUserInput } from 'src/user/dto/login-user.input'; | ||||||||||||||||||||||||||||||||||||||
import { RegisterUserInput } from 'src/user/dto/register-user.input'; | ||||||||||||||||||||||||||||||||||||||
import { User } from 'src/user/user.model'; | ||||||||||||||||||||||||||||||||||||||
import { Repository } from 'typeorm'; | ||||||||||||||||||||||||||||||||||||||
import { In, Repository } from 'typeorm'; | ||||||||||||||||||||||||||||||||||||||
import { CheckTokenInput } from './dto/check-token.input'; | ||||||||||||||||||||||||||||||||||||||
import { JwtCacheService } from 'src/auth/jwt-cache.service'; | ||||||||||||||||||||||||||||||||||||||
import { Menu } from './menu/menu.model'; | ||||||||||||||||||||||||||||||||||||||
import { Role } from './role/role.model'; | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
@Injectable() | ||||||||||||||||||||||||||||||||||||||
export class AuthService { | ||||||||||||||||||||||||||||||||||||||
|
@@ -23,6 +26,10 @@ | |||||||||||||||||||||||||||||||||||||
private jwtService: JwtService, | ||||||||||||||||||||||||||||||||||||||
private jwtCacheService: JwtCacheService, | ||||||||||||||||||||||||||||||||||||||
private configService: ConfigService, | ||||||||||||||||||||||||||||||||||||||
@InjectRepository(Menu) | ||||||||||||||||||||||||||||||||||||||
private menuRepository: Repository<Menu>, | ||||||||||||||||||||||||||||||||||||||
@InjectRepository(Role) | ||||||||||||||||||||||||||||||||||||||
private roleRepository: Repository<Role>, | ||||||||||||||||||||||||||||||||||||||
) {} | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
async register(registerUserInput: RegisterUserInput): Promise<User> { | ||||||||||||||||||||||||||||||||||||||
|
@@ -77,7 +84,7 @@ | |||||||||||||||||||||||||||||||||||||
await this.jwtService.verifyAsync(params.token); | ||||||||||||||||||||||||||||||||||||||
return this.jwtCacheService.isTokenStored(params.token); | ||||||||||||||||||||||||||||||||||||||
} catch (error) { | ||||||||||||||||||||||||||||||||||||||
console.log(error); | ||||||||||||||||||||||||||||||||||||||
return false; | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
|
@@ -85,7 +92,7 @@ | |||||||||||||||||||||||||||||||||||||
Logger.log('logout token', token); | ||||||||||||||||||||||||||||||||||||||
try { | ||||||||||||||||||||||||||||||||||||||
await this.jwtService.verifyAsync(token); | ||||||||||||||||||||||||||||||||||||||
} catch (error) { | ||||||||||||||||||||||||||||||||||||||
return false; | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
|
@@ -95,4 +102,242 @@ | |||||||||||||||||||||||||||||||||||||
this.jwtCacheService.removeToken(token); | ||||||||||||||||||||||||||||||||||||||
return true; | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
async assignMenusToRole(roleId: string, menuIds: string[]): Promise<Role> { | ||||||||||||||||||||||||||||||||||||||
// Find the role with existing menus | ||||||||||||||||||||||||||||||||||||||
const role = await this.roleRepository.findOne({ | ||||||||||||||||||||||||||||||||||||||
where: { id: roleId }, | ||||||||||||||||||||||||||||||||||||||
relations: ['menus'], | ||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
if (!role) { | ||||||||||||||||||||||||||||||||||||||
throw new NotFoundException(`Role with ID "${roleId}" not found`); | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
// Find all menus | ||||||||||||||||||||||||||||||||||||||
const menus = await this.menuRepository.findByIds(menuIds); | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
if (menus.length !== menuIds.length) { | ||||||||||||||||||||||||||||||||||||||
throw new NotFoundException('Some menus were not found'); | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
Comment on lines
+118
to
+122
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Use consistent repository methods for querying entities In Apply this diff to update the code: - const menus = await this.menuRepository.findByIds(menuIds);
+ const menus = await this.menuRepository.findBy({ id: In(menuIds) });
|
||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
if (!role.menus) { | ||||||||||||||||||||||||||||||||||||||
role.menus = []; | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
const newMenus = menus.filter( | ||||||||||||||||||||||||||||||||||||||
(menu) => !role.menus.some((existingMenu) => existingMenu.id === menu.id), | ||||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
if (newMenus.length === 0) { | ||||||||||||||||||||||||||||||||||||||
throw new ConflictException( | ||||||||||||||||||||||||||||||||||||||
'All specified menus are already assigned to this role', | ||||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
role.menus.push(...newMenus); | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
try { | ||||||||||||||||||||||||||||||||||||||
await this.roleRepository.save(role); | ||||||||||||||||||||||||||||||||||||||
Logger.log( | ||||||||||||||||||||||||||||||||||||||
`${newMenus.length} menus assigned to role ${role.name} successfully`, | ||||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
return await this.roleRepository.findOne({ | ||||||||||||||||||||||||||||||||||||||
where: { id: roleId }, | ||||||||||||||||||||||||||||||||||||||
relations: ['menus'], | ||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||
} catch (error) { | ||||||||||||||||||||||||||||||||||||||
Logger.error(`Failed to assign menus to role: ${error.message}`); | ||||||||||||||||||||||||||||||||||||||
throw error; | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
async removeMenuFromRole(roleId: string, menuId: string): Promise<Role> { | ||||||||||||||||||||||||||||||||||||||
const role = await this.roleRepository.findOne({ | ||||||||||||||||||||||||||||||||||||||
where: { id: roleId }, | ||||||||||||||||||||||||||||||||||||||
relations: ['menus'], | ||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
if (!role) { | ||||||||||||||||||||||||||||||||||||||
throw new NotFoundException(`Role with ID "${roleId}" not found`); | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
const menuIndex = role.menus?.findIndex((menu) => menu.id === menuId); | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
if (menuIndex === -1) { | ||||||||||||||||||||||||||||||||||||||
throw new NotFoundException( | ||||||||||||||||||||||||||||||||||||||
`Menu with ID "${menuId}" not found in role "${role.name}"`, | ||||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
Comment on lines
+166
to
+172
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Handle potential undefined In the Apply this diff to address the issue: + if (!role.menus || role.menus.length === 0) {
+ throw new NotFoundException(`No menus assigned to role "${role.name}"`);
+ }
const menuIndex = role.menus.findIndex((menu) => menu.id === menuId);
if (menuIndex === -1) {
throw new NotFoundException(
`Menu with ID "${menuId}" not found in role "${role.name}"`,
);
} 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
role.menus.splice(menuIndex, 1); | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
try { | ||||||||||||||||||||||||||||||||||||||
await this.roleRepository.save(role); | ||||||||||||||||||||||||||||||||||||||
Logger.log(`Menu removed from role ${role.name} successfully`); | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
return await this.roleRepository.findOne({ | ||||||||||||||||||||||||||||||||||||||
where: { id: roleId }, | ||||||||||||||||||||||||||||||||||||||
relations: ['menus'], | ||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||
} catch (error) { | ||||||||||||||||||||||||||||||||||||||
Logger.error(`Failed to remove menu from role: ${error.message}`); | ||||||||||||||||||||||||||||||||||||||
throw error; | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
async assignRoles(userId: string, roleIds: string[]): Promise<User> { | ||||||||||||||||||||||||||||||||||||||
const user = await this.userRepository.findOne({ | ||||||||||||||||||||||||||||||||||||||
where: { id: userId }, | ||||||||||||||||||||||||||||||||||||||
relations: ['roles'], | ||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
if (!user) { | ||||||||||||||||||||||||||||||||||||||
throw new NotFoundException(`User with ID "${userId}" not found`); | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
const roles = await this.roleRepository.findBy({ id: In(roleIds) }); | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
if (roles.length !== roleIds.length) { | ||||||||||||||||||||||||||||||||||||||
throw new NotFoundException('Some roles were not found'); | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
if (!user.roles) { | ||||||||||||||||||||||||||||||||||||||
user.roles = []; | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
const newRoles = roles.filter( | ||||||||||||||||||||||||||||||||||||||
(role) => !user.roles.some((existingRole) => existingRole.id === role.id), | ||||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
if (newRoles.length === 0) { | ||||||||||||||||||||||||||||||||||||||
throw new ConflictException( | ||||||||||||||||||||||||||||||||||||||
'All specified roles are already assigned to this user', | ||||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
user.roles.push(...newRoles); | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
try { | ||||||||||||||||||||||||||||||||||||||
await this.userRepository.save(user); | ||||||||||||||||||||||||||||||||||||||
Logger.log( | ||||||||||||||||||||||||||||||||||||||
`${newRoles.length} roles assigned to user ${user.username} successfully`, | ||||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
return await this.userRepository.findOne({ | ||||||||||||||||||||||||||||||||||||||
where: { id: userId }, | ||||||||||||||||||||||||||||||||||||||
relations: ['roles'], | ||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||
} catch (error) { | ||||||||||||||||||||||||||||||||||||||
Logger.error(`Failed to assign roles to user: ${error.message}`); | ||||||||||||||||||||||||||||||||||||||
throw error; | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
async removeRoleFromUser(userId: string, roleId: string): Promise<User> { | ||||||||||||||||||||||||||||||||||||||
const user = await this.userRepository.findOne({ | ||||||||||||||||||||||||||||||||||||||
where: { id: userId }, | ||||||||||||||||||||||||||||||||||||||
relations: ['roles'], | ||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
if (!user) { | ||||||||||||||||||||||||||||||||||||||
throw new NotFoundException(`User with ID "${userId}" not found`); | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
const roleIndex = user.roles?.findIndex((role) => role.id === roleId); | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
if (roleIndex === -1) { | ||||||||||||||||||||||||||||||||||||||
throw new NotFoundException( | ||||||||||||||||||||||||||||||||||||||
`Role with ID "${roleId}" not found in user's roles`, | ||||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
Comment on lines
+248
to
+254
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Handle potential undefined In the Apply this diff to address the issue: + if (!user.roles || user.roles.length === 0) {
+ throw new NotFoundException(`No roles assigned to user "${user.username}"`);
+ }
const roleIndex = user.roles.findIndex((role) => role.id === roleId);
if (roleIndex === -1) {
throw new NotFoundException(
`Role with ID "${roleId}" not found in user's roles`,
);
} 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
user.roles.splice(roleIndex, 1); | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
try { | ||||||||||||||||||||||||||||||||||||||
await this.userRepository.save(user); | ||||||||||||||||||||||||||||||||||||||
Logger.log(`Role removed from user ${user.username} successfully`); | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
return await this.userRepository.findOne({ | ||||||||||||||||||||||||||||||||||||||
where: { id: userId }, | ||||||||||||||||||||||||||||||||||||||
relations: ['roles'], | ||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||
} catch (error) { | ||||||||||||||||||||||||||||||||||||||
Logger.error(`Failed to remove role from user: ${error.message}`); | ||||||||||||||||||||||||||||||||||||||
throw error; | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
async getUserRolesAndMenus(userId: string): Promise<{ | ||||||||||||||||||||||||||||||||||||||
roles: Role[]; | ||||||||||||||||||||||||||||||||||||||
menus: Menu[]; | ||||||||||||||||||||||||||||||||||||||
}> { | ||||||||||||||||||||||||||||||||||||||
const user = await this.userRepository.findOne({ | ||||||||||||||||||||||||||||||||||||||
where: { id: userId }, | ||||||||||||||||||||||||||||||||||||||
relations: ['roles', 'roles.menus'], | ||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
if (!user) { | ||||||||||||||||||||||||||||||||||||||
throw new NotFoundException(`User with ID "${userId}" not found`); | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
const userRoles = user.roles || []; | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
// Get unique menus across all roles | ||||||||||||||||||||||||||||||||||||||
const userMenus = Array.from( | ||||||||||||||||||||||||||||||||||||||
new Map( | ||||||||||||||||||||||||||||||||||||||
userRoles | ||||||||||||||||||||||||||||||||||||||
.flatMap((role) => role.menus || []) | ||||||||||||||||||||||||||||||||||||||
.map((menu) => [menu.id, menu]), | ||||||||||||||||||||||||||||||||||||||
).values(), | ||||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||||
Comment on lines
+288
to
+294
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Simplify the aggregation of unique menus In Refactor the code to simplify the aggregation: // Get unique menus across all roles
- const userMenus = Array.from(
- new Map(
- userRoles
- .flatMap((role) => role.menus || [])
- .map((menu) => [menu.id, menu]),
- ).values(),
- );
+ const userMenus = Array.from(
+ new Set(
+ userRoles.flatMap((role) => role.menus || [])
+ )
+ ); Also applies to: 331-337 |
||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
return { | ||||||||||||||||||||||||||||||||||||||
roles: userRoles, | ||||||||||||||||||||||||||||||||||||||
menus: userMenus, | ||||||||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
async getUserRoles(userId: string): Promise<{ | ||||||||||||||||||||||||||||||||||||||
roles: Role[]; | ||||||||||||||||||||||||||||||||||||||
}> { | ||||||||||||||||||||||||||||||||||||||
const user = await this.userRepository.findOne({ | ||||||||||||||||||||||||||||||||||||||
where: { id: userId }, | ||||||||||||||||||||||||||||||||||||||
relations: ['roles'], | ||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
if (!user) { | ||||||||||||||||||||||||||||||||||||||
throw new NotFoundException(`User with ID "${userId}" not found`); | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
return { | ||||||||||||||||||||||||||||||||||||||
roles: user.roles || [], | ||||||||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
async getUserMenus(userId: string): Promise<{ | ||||||||||||||||||||||||||||||||||||||
menus: Menu[]; | ||||||||||||||||||||||||||||||||||||||
}> { | ||||||||||||||||||||||||||||||||||||||
const user = await this.userRepository.findOne({ | ||||||||||||||||||||||||||||||||||||||
where: { id: userId }, | ||||||||||||||||||||||||||||||||||||||
relations: ['roles', 'roles.menus'], | ||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
if (!user) { | ||||||||||||||||||||||||||||||||||||||
throw new NotFoundException(`User with ID "${userId}" not found`); | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
const userMenus = Array.from( | ||||||||||||||||||||||||||||||||||||||
new Map( | ||||||||||||||||||||||||||||||||||||||
(user.roles || []) | ||||||||||||||||||||||||||||||||||||||
.flatMap((role) => role.menus || []) | ||||||||||||||||||||||||||||||||||||||
.map((menu) => [menu.id, menu]), | ||||||||||||||||||||||||||||||||||||||
).values(), | ||||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
return { | ||||||||||||||||||||||||||||||||||||||
menus: userMenus, | ||||||||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove unused imports or implement guards.
The
RolesGuard
andMenuGuard
are imported but never used in this module. If these guards are intended for route protection, they need to be properly implemented usingAPP_GUARD
provider.Apply this diff to implement the guards globally:
Alternatively, if these guards are not needed, remove the unused imports.
🧰 Tools
🪛 GitHub Check: autofix