So, I'm in a project where I want to add a data with admin and another with a normal user, but it says that "roles" is undefined, How do I solve this? and tell me if I need to add roles to my entity file.
my data role:
export enum Role {
Normal = 'normal',
Admin = 'admin',
}
my decorator role.ts:
/* eslint-disable prettier/prettier */
import { SetMetadata } from '@nestjs/common';
import { Role } from './data.roles';
export const ROLES_KEY = 'roles';
export const Roles = (...roles: Role[]) => SetMetadata(ROLES_KEY, roles);
my roles guard.ts:
/* eslint-disable prettier/prettier */
import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { Observable } from 'rxjs';
import { Role } from '../../P.Roles/data.roles';
import { ROLES_KEY } from '../../P.Roles/roles.decorator';
@Injectable()
export class RolesGuardGuard implements CanActivate {
constructor(private reflector: Reflector){}
canActivate(
contexto: ExecutionContext,
): boolean | Promise<boolean> | Observable<boolean> {
const requiredRoles = this.reflector.getAllAndOverride<Role[]>(ROLES_KEY, [
contexto.getHandler(),
contexto.getClass()
])
if(!requiredRoles){
return true
}
const {dadosCorretora} = contexto.switchToHttp().getRequest()
return requiredRoles.some((role) => dadosCorretora.roles?.includes(role))
}
}
my dados-corretora entity file:
/* eslint-disable prettier/prettier */
import {
Column,
CreateDateColumn,
DeleteDateColumn,
Entity,
ManyToOne,
PrimaryGeneratedColumn,
UpdateDateColumn,
} from 'typeorm';
import { CorretoraEntity } from '../corretora/corretora.entity';
import { Exclude } from 'class-transformer';
import { Role } from '../P.Roles/data.roles';
@Entity({ name: 'dadosCorretora' })
export class DadosCorretoraEntity {
@PrimaryGeneratedColumn('uuid')
id: string;
@Column({ name: 'ceo', nullable: false })
ceo: string;
@Exclude()
@Column({ name: 'senha', nullable: false })
senha: string;
@Column({ name: 'email', nullable: false })
email: string;
@Column({type: 'enum', enum: Role, default: Role.Normal})
roles: string[];
the part where i use guards with roleGuard:
@Post('/:id')
@Roles(Role.Admin)
@UseGuards(RolesGuardGuard)
// eslint-disable-next-line @typescript-eslint/no-unused-vars
async create(@Param('id') id: string, @Body() {senha, ...dados}: criarDadosDTO, @Body('senha', HashearSenha) senhaHash: string) {
const dados2 = await this.dadosCorretoraService.criarDadosC(id, {
senha: senhaHash,
...dados
})
return {
Messagem: `Dados criados para a corretora ${id}`,
Dados: dados2
}
}
I need that when he is admin, he can post, but if he is a normal user with less privileges , he cant post and give a default forbiden status, but he says that roles is undefined, idk how solve this.
Obs: the roles that is undefined is in the roles guard: dadosCorretora.roles?, not from the entity.
this is the error in terminal:
ERROR [ExceptionsHandler] Cannot read properties of undefined (reading 'roles')
Request:
{
"ceo": "Polsen",
"senha": "polsen2244GIGANTIC",
"email": "[email protected]",
"roles": "admin"
}
In "DadosCorretoraEntity" class change
@Column({type: 'enum', enum: Role, default: Role.Normal}
roles: Role; // Change from string[] to Role
You defined it as an array of strings, but it should be defined as a single string representing the role of the user.