feat(SPG-124) Authorization
parent
34ea6a501d
commit
f5c1008ece
|
@ -1,6 +1,5 @@
|
|||
import { Module, Scope } from '@nestjs/common';
|
||||
import { RefreshTokenInterceptor, SessionModule } from './core/sessions';
|
||||
import { AuthModule } from './auth/auth.module';
|
||||
import { JWTGuard } from './core/guards';
|
||||
import { APP_FILTER, APP_GUARD, APP_INTERCEPTOR } from '@nestjs/core';
|
||||
import { HttpExceptionFilter, TransformInterceptor } from './core/response';
|
||||
|
@ -9,9 +8,14 @@ import { CONNECTION_NAME } from './core/strings/constants/base.constants';
|
|||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
import { ConfigModule } from '@nestjs/config';
|
||||
import { UserPrivilegeModule } from './modules/user-related/user-privilege/user-privilege.module';
|
||||
import { UserPrivilegeModel } from './modules/user-related/user-privilege/data/model/user-privilege.model';
|
||||
import { CqrsModule } from '@nestjs/cqrs';
|
||||
import { CouchModule } from './modules/configuration/couch/couch.module';
|
||||
import { UserPrivilegeModels } from './modules/user-related/user-privilege/constants';
|
||||
import { RolesGuard } from './core/guards/domain/roles.guard';
|
||||
import { PrivilegeService } from './core/guards/domain/services/privilege.service';
|
||||
import { UserModel } from './modules/user-related/user/data/models/user.model';
|
||||
import { AuthModule } from './modules/configuration/auth/auth.module';
|
||||
import { UserModule } from './modules/user-related/user/user.module';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
|
@ -27,18 +31,20 @@ import { CouchModule } from './modules/configuration/couch/couch.module';
|
|||
username: process.env.DEFAULT_DB_USER,
|
||||
password: process.env.DEFAULT_DB_PASS,
|
||||
database: process.env.DEFAULT_DB_NAME,
|
||||
entities: [UserPrivilegeModel],
|
||||
synchronize: true,
|
||||
entities: [...UserPrivilegeModels, UserModel],
|
||||
synchronize: false,
|
||||
}),
|
||||
CqrsModule,
|
||||
SessionModule,
|
||||
AuthModule,
|
||||
CouchModule,
|
||||
|
||||
UserModule,
|
||||
UserPrivilegeModule,
|
||||
],
|
||||
controllers: [],
|
||||
providers: [
|
||||
PrivilegeService,
|
||||
/**
|
||||
* By default all request from client will protect by JWT
|
||||
* if there is some endpoint/function that does'nt require authentication
|
||||
|
@ -47,7 +53,7 @@ import { CouchModule } from './modules/configuration/couch/couch.module';
|
|||
{
|
||||
provide: APP_GUARD,
|
||||
scope: Scope.REQUEST,
|
||||
useClass: JWTGuard,
|
||||
useClass: RolesGuard,
|
||||
},
|
||||
{
|
||||
provide: APP_INTERCEPTOR,
|
||||
|
|
|
@ -1 +1,3 @@
|
|||
export const UNPROTECTED_URL = 'unprotected_url';
|
||||
export const PRIVILEGE_KEY = 'privilege_key';
|
||||
export const MAIN_MENU = 'main_menu';
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
import { SetMetadata } from '@nestjs/common';
|
||||
import { UNPROTECTED_URL } from '../../constants';
|
||||
import { MAIN_MENU, UNPROTECTED_URL } from '../../constants';
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* Use Public instead
|
||||
* This decorator will exclude the request from token check
|
||||
*
|
||||
* NOTE:
|
||||
|
@ -11,3 +13,9 @@ import { UNPROTECTED_URL } from '../../constants';
|
|||
*/
|
||||
export const Unprotected = (isUnprotected = true) =>
|
||||
SetMetadata(UNPROTECTED_URL, isUnprotected);
|
||||
|
||||
export const Public = (isUnprotected = true) =>
|
||||
SetMetadata(UNPROTECTED_URL, isUnprotected);
|
||||
|
||||
export const MainMenu = () => SetMetadata(MAIN_MENU, true);
|
||||
export const ExcludePrivilege = () => SetMetadata(MAIN_MENU, true);
|
||||
|
|
|
@ -2,22 +2,25 @@ import {
|
|||
Injectable,
|
||||
CanActivate,
|
||||
ExecutionContext,
|
||||
UnauthorizedException,
|
||||
Scope,
|
||||
Logger,
|
||||
UnauthorizedException,
|
||||
} from '@nestjs/common';
|
||||
import { Reflector } from '@nestjs/core';
|
||||
import { Observable } from 'rxjs';
|
||||
import { SessionService, UsersSession } from 'src/core/sessions';
|
||||
import { UNPROTECTED_URL } from '../constants';
|
||||
import { PrivilegeService } from './services/privilege.service';
|
||||
|
||||
@Injectable({ scope: Scope.REQUEST })
|
||||
export class JWTGuard implements CanActivate {
|
||||
constructor(
|
||||
protected readonly session: SessionService,
|
||||
protected readonly reflector: Reflector,
|
||||
protected readonly privilege: PrivilegeService,
|
||||
) {}
|
||||
|
||||
protected isPublic = false;
|
||||
protected userSession: UsersSession;
|
||||
|
||||
canActivate(
|
||||
|
@ -31,6 +34,8 @@ export class JWTGuard implements CanActivate {
|
|||
UNPROTECTED_URL,
|
||||
[context.getHandler(), context.getClass()],
|
||||
);
|
||||
this.isPublic = isUnprotected;
|
||||
this.session.setPublic(isUnprotected);
|
||||
if (isUnprotected) return true;
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,23 +1,36 @@
|
|||
import { Injectable, ExecutionContext } from '@nestjs/common';
|
||||
import { Observable } from 'rxjs';
|
||||
import {
|
||||
Injectable,
|
||||
ExecutionContext,
|
||||
ForbiddenException,
|
||||
} from '@nestjs/common';
|
||||
import { JWTGuard } from './jwt.guard';
|
||||
import { MAIN_MENU } from '../constants';
|
||||
|
||||
@Injectable()
|
||||
export class RolesGuard extends JWTGuard {
|
||||
canActivate(
|
||||
context: ExecutionContext,
|
||||
): boolean | Promise<boolean> | Observable<boolean> {
|
||||
async canActivate(context: ExecutionContext): Promise<boolean> {
|
||||
super.canActivate(context);
|
||||
|
||||
/**
|
||||
* Create function to check if `this.userSession` have access
|
||||
* to Read / Create / Update / and Other Action
|
||||
*/
|
||||
// jika endpoint tersebut bukan public, maka lakukan check lanjutan
|
||||
if (!this.isPublic) {
|
||||
// Check apakah endpoint ada decorator untuk exlude privilege (@ExcludePrivilege())
|
||||
const excludePrivilege = this.reflector.getAllAndOverride<boolean>(
|
||||
MAIN_MENU,
|
||||
[context.getHandler(), context.getClass()],
|
||||
);
|
||||
if (excludePrivilege) return true;
|
||||
|
||||
// check apakah dapat akses module
|
||||
const isNotAllow = await this.privilege.isNotAllowed();
|
||||
if (isNotAllow) {
|
||||
throw new ForbiddenException({
|
||||
statusCode: 10003,
|
||||
message: `Forbidden Access, you don't have access to this module!`,
|
||||
error: 'ACCESS_FORBIDDEN',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign rules to session, So Query can take the rules and give
|
||||
* the data base on user request
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
import { ForbiddenException, Inject, Injectable, Scope } from '@nestjs/common';
|
||||
import { REQUEST } from '@nestjs/core';
|
||||
import { Request } from 'express';
|
||||
import { InjectDataSource } from '@nestjs/typeorm';
|
||||
import { getAction } from 'src/core/helpers/path/get-action-from-path.helper';
|
||||
import { UserProvider } from 'src/core/sessions';
|
||||
import { CONNECTION_NAME } from 'src/core/strings/constants/base.constants';
|
||||
import { UserPrivilegeConfigurationModel } from 'src/modules/user-related/user-privilege/data/models/user-privilege-configuration.model';
|
||||
import { DataSource, IsNull } from 'typeorm';
|
||||
import { UserRole } from 'src/modules/user-related/user/constants';
|
||||
import { UserPrivilegeConfigurationEntity } from 'src/modules/user-related/user-privilege/domain/entities/user-privilege-configuration.entity';
|
||||
|
||||
@Injectable({ scope: Scope.REQUEST })
|
||||
export class PrivilegeService {
|
||||
constructor(
|
||||
@InjectDataSource(CONNECTION_NAME.DEFAULT)
|
||||
protected readonly dataSource: DataSource,
|
||||
|
||||
@Inject(REQUEST) private readonly request: Request,
|
||||
protected readonly session: UserProvider,
|
||||
) {}
|
||||
|
||||
get repository() {
|
||||
return this.dataSource.getRepository(UserPrivilegeConfigurationModel);
|
||||
}
|
||||
|
||||
get user() {
|
||||
return this.session.user;
|
||||
}
|
||||
|
||||
get action() {
|
||||
const headerAction = this.request.headers['ex-model-action'] as string;
|
||||
return headerAction ?? getAction(this.request.method, this.request.path);
|
||||
}
|
||||
|
||||
async isAllowed() {
|
||||
// jika rolenya adalah superadmin, abaikan dan return true
|
||||
if (this.user.role == UserRole.SUPERADMIN) return true;
|
||||
|
||||
// check privilege dan sesuaikan dengan akse
|
||||
const configurations = await this.privilegeConfiguration();
|
||||
return configurations[this.action];
|
||||
}
|
||||
|
||||
async isNotAllowed() {
|
||||
return !(await this.isAllowed());
|
||||
}
|
||||
|
||||
private moduleKey() {
|
||||
const headerKey = 'ex-model-key';
|
||||
const moduleKey = this.request.headers[headerKey] as string;
|
||||
if (!moduleKey) {
|
||||
throw new ForbiddenException({
|
||||
statusCode: 10005,
|
||||
message: `Forbidden Access, access Module is Require!`,
|
||||
error: 'MODULE_KEY_NOT_FOUND',
|
||||
});
|
||||
}
|
||||
const [module, menu, sub_menu, section] = moduleKey.split('.');
|
||||
return { module, menu, sub_menu, section };
|
||||
}
|
||||
|
||||
async privilegeConfiguration(): Promise<UserPrivilegeConfigurationEntity> {
|
||||
const { module, menu, sub_menu, section } = this.moduleKey();
|
||||
return await this.repository.findOne({
|
||||
select: ['id', 'view', 'create', 'edit', 'delete', 'cancel', 'confirm'],
|
||||
where: {
|
||||
user_privilege_id: this.user.user_privilege_id,
|
||||
module: module,
|
||||
menu: menu ?? IsNull(),
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
import { PrivilegeAction } from 'src/core/strings/constants/privilege.constants';
|
||||
|
||||
function containsUuid(str) {
|
||||
const parts = str.split('/'); // Split the string by "/"
|
||||
for (const part of parts) {
|
||||
if (
|
||||
/^[0-9a-f]{8}\b-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(
|
||||
part,
|
||||
)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export function getAction(method: string, path: string): string {
|
||||
if (method === 'GET') return PrivilegeAction.VIEW;
|
||||
else if (method === 'POST') return PrivilegeAction.CREATE;
|
||||
else if (method === 'DELETE') return PrivilegeAction.DELETE;
|
||||
else if (method === 'PATCH' || method === 'PUT') {
|
||||
if (['confirm', 'active', 'inactive'].includes(path))
|
||||
return PrivilegeAction.CONFIRM;
|
||||
else if (path.includes('cancel')) return PrivilegeAction.CANCEL;
|
||||
else return PrivilegeAction.EDIT;
|
||||
}
|
||||
return 'forbidden';
|
||||
}
|
|
@ -1,4 +1,8 @@
|
|||
import { UserRole } from 'src/modules/user-related/user/constants';
|
||||
|
||||
export interface UsersSession {
|
||||
id: number;
|
||||
name: string;
|
||||
role: UserRole;
|
||||
user_privilege_id: string;
|
||||
}
|
||||
|
|
|
@ -6,7 +6,23 @@ import { isTokenNearExpired } from '../utils/jwt.helpers';
|
|||
|
||||
@Injectable({ scope: Scope.REQUEST })
|
||||
export class SessionService {
|
||||
private public = false;
|
||||
public ignorePrivilegeCondition = false;
|
||||
|
||||
constructor(private readonly jwt: JwtService) {}
|
||||
|
||||
setPublic(value: boolean) {
|
||||
this.public = value;
|
||||
}
|
||||
|
||||
get isPublic() {
|
||||
return this.public;
|
||||
}
|
||||
|
||||
get isPrivate() {
|
||||
return !this.isPublic;
|
||||
}
|
||||
|
||||
createAccessToken(session: UsersSession): string {
|
||||
return this.jwt.sign(session);
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { Global, Module } from '@nestjs/common';
|
||||
import { JwtModule } from '@nestjs/jwt';
|
||||
import { JWT_EXPIRED, JWT_SECRET } from '../../auth/constants';
|
||||
import { UserProvider } from './domain/providers/user';
|
||||
import { SessionService } from './domain/services/session.service';
|
||||
import { JWT_EXPIRED, JWT_SECRET } from './constants';
|
||||
|
||||
@Global()
|
||||
@Module({
|
||||
|
|
|
@ -42,4 +42,6 @@ export enum OPERATION {
|
|||
export const BLANK_USER = {
|
||||
id: null,
|
||||
name: null,
|
||||
role: null,
|
||||
user_privilege_id: null,
|
||||
};
|
||||
|
|
|
@ -0,0 +1,178 @@
|
|||
export enum PrivilegeAction {
|
||||
VIEW = 'view',
|
||||
CREATE = 'create',
|
||||
EDIT = 'edit',
|
||||
DELETE = 'delete',
|
||||
CANCEL = 'cancel',
|
||||
CONFIRM = 'confirm',
|
||||
}
|
||||
|
||||
export const PrivilegeAdminConstant = [
|
||||
{
|
||||
menu: 'DASHBOARD',
|
||||
menu_label: 'Dashboard',
|
||||
actions: [PrivilegeAction.VIEW],
|
||||
index: 1,
|
||||
},
|
||||
{
|
||||
menu: 'CALENDAR',
|
||||
menu_label: 'Kalender',
|
||||
actions: [PrivilegeAction.VIEW],
|
||||
index: 2,
|
||||
},
|
||||
{
|
||||
menu: 'BOOKING',
|
||||
menu_label: 'Pemesanan',
|
||||
actions: [
|
||||
PrivilegeAction.VIEW,
|
||||
PrivilegeAction.CREATE,
|
||||
PrivilegeAction.CONFIRM,
|
||||
PrivilegeAction.DELETE,
|
||||
PrivilegeAction.CANCEL,
|
||||
PrivilegeAction.EDIT,
|
||||
],
|
||||
index: 3,
|
||||
},
|
||||
{
|
||||
menu: 'REFUND',
|
||||
menu_label: 'Pengembalian',
|
||||
actions: [
|
||||
PrivilegeAction.VIEW,
|
||||
PrivilegeAction.CREATE,
|
||||
PrivilegeAction.CONFIRM,
|
||||
PrivilegeAction.DELETE,
|
||||
PrivilegeAction.CANCEL,
|
||||
PrivilegeAction.EDIT,
|
||||
],
|
||||
index: 4,
|
||||
},
|
||||
{
|
||||
menu: 'REKONSILIASI',
|
||||
menu_label: 'Rekonsiliasi',
|
||||
actions: [
|
||||
PrivilegeAction.VIEW,
|
||||
PrivilegeAction.CREATE,
|
||||
PrivilegeAction.CONFIRM,
|
||||
PrivilegeAction.DELETE,
|
||||
PrivilegeAction.CANCEL,
|
||||
PrivilegeAction.EDIT,
|
||||
],
|
||||
index: 5,
|
||||
},
|
||||
{
|
||||
menu: 'ITEM',
|
||||
menu_label: 'Item',
|
||||
actions: [
|
||||
PrivilegeAction.VIEW,
|
||||
PrivilegeAction.CREATE,
|
||||
PrivilegeAction.EDIT,
|
||||
PrivilegeAction.DELETE,
|
||||
],
|
||||
index: 6,
|
||||
},
|
||||
{
|
||||
menu: 'RATE_TYPE',
|
||||
menu_label: 'Tipe Rate',
|
||||
actions: [
|
||||
PrivilegeAction.VIEW,
|
||||
PrivilegeAction.CREATE,
|
||||
PrivilegeAction.EDIT,
|
||||
PrivilegeAction.DELETE,
|
||||
],
|
||||
index: 7,
|
||||
},
|
||||
{
|
||||
menu: 'USER',
|
||||
menu_label: 'Pengguna',
|
||||
actions: [
|
||||
PrivilegeAction.VIEW,
|
||||
PrivilegeAction.CREATE,
|
||||
PrivilegeAction.EDIT,
|
||||
PrivilegeAction.DELETE,
|
||||
],
|
||||
index: 8,
|
||||
},
|
||||
{
|
||||
menu: 'TENANT',
|
||||
menu_label: 'Tenant',
|
||||
actions: [
|
||||
PrivilegeAction.VIEW,
|
||||
PrivilegeAction.CREATE,
|
||||
PrivilegeAction.EDIT,
|
||||
PrivilegeAction.DELETE,
|
||||
],
|
||||
index: 9,
|
||||
},
|
||||
{
|
||||
menu: 'WEB_INFORMATION',
|
||||
menu_label: 'Informasi Web',
|
||||
actions: [
|
||||
PrivilegeAction.VIEW,
|
||||
PrivilegeAction.CREATE,
|
||||
PrivilegeAction.EDIT,
|
||||
PrivilegeAction.DELETE,
|
||||
],
|
||||
index: 10,
|
||||
},
|
||||
{
|
||||
menu: 'SETTING',
|
||||
menu_label: 'Setting',
|
||||
actions: [
|
||||
PrivilegeAction.VIEW,
|
||||
PrivilegeAction.CREATE,
|
||||
PrivilegeAction.EDIT,
|
||||
PrivilegeAction.DELETE,
|
||||
],
|
||||
index: 11,
|
||||
},
|
||||
{
|
||||
menu: 'LAPORAN',
|
||||
menu_label: 'Laporan',
|
||||
actions: [PrivilegeAction.VIEW],
|
||||
index: 12,
|
||||
},
|
||||
{
|
||||
menu: 'DISKON_CODE',
|
||||
menu_label: 'Generate Diskon Kode',
|
||||
actions: [PrivilegeAction.CREATE],
|
||||
index: 13,
|
||||
},
|
||||
];
|
||||
|
||||
export const PrivilegePOSConstant = [
|
||||
{
|
||||
menu: 'SALES',
|
||||
menu_label: 'Penjualan',
|
||||
actions: [
|
||||
PrivilegeAction.VIEW,
|
||||
PrivilegeAction.CREATE,
|
||||
PrivilegeAction.DELETE,
|
||||
PrivilegeAction.EDIT,
|
||||
],
|
||||
index: 14,
|
||||
},
|
||||
{
|
||||
menu: 'QR_PRINT',
|
||||
menu_label: 'Print QR',
|
||||
actions: [PrivilegeAction.VIEW, PrivilegeAction.CREATE],
|
||||
index: 15,
|
||||
},
|
||||
{
|
||||
menu: 'BOOKING',
|
||||
menu_label: 'Pemesanan',
|
||||
actions: [PrivilegeAction.VIEW, PrivilegeAction.CREATE],
|
||||
index: 16,
|
||||
},
|
||||
{
|
||||
menu: 'WITHDRAW',
|
||||
menu_label: 'Penarikan Kas',
|
||||
actions: [PrivilegeAction.VIEW, PrivilegeAction.CREATE],
|
||||
index: 17,
|
||||
},
|
||||
{
|
||||
menu: 'POS_DISKON_CODE',
|
||||
menu_label: 'Generate Diskon Kode',
|
||||
actions: [PrivilegeAction.CREATE],
|
||||
index: 18,
|
||||
},
|
||||
];
|
|
@ -9,7 +9,7 @@ export class AuthController {
|
|||
constructor(private orchestrator: AuthOrchestrator) {}
|
||||
|
||||
@Post()
|
||||
@Public(false)
|
||||
@Public(true)
|
||||
async login(@Body() body: LoginDto) {
|
||||
return await this.orchestrator.login(body);
|
||||
}
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
import { Body, Controller, Get, Param, Put, Query } from '@nestjs/common';
|
||||
import { ApiTags } from '@nestjs/swagger';
|
||||
import { ApiBearerAuth, ApiTags } from '@nestjs/swagger';
|
||||
import { Public } from 'src/core/guards';
|
||||
import { MODULE_NAME } from 'src/core/strings/constants/module.constants';
|
||||
import { UserPrivilegeConfigurationDataOrchestrator } from '../domain/usecases/user-privilege-configuration/user-privilege-configuration-data.orchestrator';
|
||||
import { UserPrivilegeConfigurationDto } from './dto/user-privilege-configuration.dto';
|
||||
import { UserPrivilegeConfigurationEntity } from '../domain/entities/user-privilege-configuration.entity';
|
||||
import { Pagination } from 'src/core/response';
|
||||
import { FilterUserPrivilegeConfigurationDto } from './dto/filter-user-privilege-configuration.dto';
|
||||
import { PaginationResponse } from 'src/core/response/domain/ok-response.interface';
|
||||
|
||||
|
@ -14,6 +13,7 @@ import { PaginationResponse } from 'src/core/response/domain/ok-response.interfa
|
|||
)
|
||||
@Controller(MODULE_NAME.USER_PRIVILEGE_CONFIGURATION)
|
||||
@Public(false)
|
||||
@ApiBearerAuth('JWT')
|
||||
export class UserPrivilegeConfigurationController {
|
||||
constructor(
|
||||
private orchestrator: UserPrivilegeConfigurationDataOrchestrator,
|
||||
|
|
|
@ -10,7 +10,7 @@ import {
|
|||
import { UserPrivilegeDataOrchestrator } from '../domain/usecases/user-privilege/user-privilege-data.orchestrator';
|
||||
import { CreateUserPrivilegeDto } from './dto/create-user-privilege.dto';
|
||||
import { MODULE_NAME } from 'src/core/strings/constants/module.constants';
|
||||
import { ApiTags } from '@nestjs/swagger';
|
||||
import { ApiBearerAuth, ApiTags } from '@nestjs/swagger';
|
||||
import { UserPrivilegeEntity } from '../domain/entities/user-privilege.entity';
|
||||
import { BatchResult } from 'src/core/response/domain/ok-response.interface';
|
||||
import { BatchIdsDto } from 'src/core/modules/infrastructure/dto/base-batch.dto';
|
||||
|
@ -19,6 +19,7 @@ import { Public } from 'src/core/guards';
|
|||
@ApiTags(`${MODULE_NAME.USER_PRIVILEGE.split('-').join(' ')} - data`)
|
||||
@Controller(MODULE_NAME.USER_PRIVILEGE)
|
||||
@Public(false)
|
||||
@ApiBearerAuth('JWT')
|
||||
export class UserPrivilegeDataController {
|
||||
constructor(private orchestrator: UserPrivilegeDataOrchestrator) {}
|
||||
|
||||
|
|
|
@ -4,19 +4,19 @@ import { Pagination } from 'src/core/response';
|
|||
import { PaginationResponse } from 'src/core/response/domain/ok-response.interface';
|
||||
import { UserPrivilegeEntity } from '../domain/entities/user-privilege.entity';
|
||||
import { UserPrivilegeReadOrchestrator } from '../domain/usecases/user-privilege/user-privilege-read.orchestrator';
|
||||
import { ApiTags } from '@nestjs/swagger';
|
||||
import { ApiBearerAuth, ApiTags } from '@nestjs/swagger';
|
||||
import { MODULE_NAME } from 'src/core/strings/constants/module.constants';
|
||||
import { ExcludePrivilege, Public } from 'src/core/guards';
|
||||
|
||||
@ApiTags(`${MODULE_NAME.USER_PRIVILEGE.split('-').join(' ')} - read`)
|
||||
@Controller(MODULE_NAME.USER_PRIVILEGE)
|
||||
@Public(false)
|
||||
@ApiBearerAuth('JWT')
|
||||
export class UserPrivilegeReadController {
|
||||
constructor(private orchestrator: UserPrivilegeReadOrchestrator) {}
|
||||
|
||||
@Get()
|
||||
@Pagination()
|
||||
@ExcludePrivilege()
|
||||
async index(
|
||||
@Query() params: FilterUserPrivilegeDto,
|
||||
): Promise<PaginationResponse<UserPrivilegeEntity>> {
|
||||
|
|
Loading…
Reference in New Issue