I know my token is valid and contains the permissions alongside the email and role, since when I use jwt.io on what is received in the back I get something like this:
{
"https://xxx/roles": ["admin"],
"https://xxx/email": "test.test@gmail.com",
"iss": "https://yyy/",
"sub": "auth0|62fe8aa3e6af28270479a495",
"aud": [
"https://xxx",
"https://yyy"
],
"iat": 1692728774,
"exp": 1692815174,
"azp": "EOHLdEZS8KaK5CfpscR9ebZzd9ibyy4C",
"scope": "openid read:current_user update:current_user_metadata",
"permissions": [
"create:ingredients",
(...)
"update:users"
]
}
I can't find a single way to get my user email or permission (in token['https://xxx/email']) or simply the permissions in the guard and/or controller. I know they are supposed to be in "context.getArgs()[0].user.permissions" & "context.getArgs()[0].user['https://xxx/email']" but it's always undefined
I created the following decorators:
export const Permissions = (...permissions: string[]) => {
//setting permissions
return SetMetadata('permissions', permissions);
};
export const AuthUser = createParamDecorator(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(data: unknown, ctx: any): IUserToken => {
const request = ctx.switchToHttp().getRequest();
return request.user;
}
);
And the following guard:
@Injectable()
export class PermissionsGuard implements CanActivate {
constructor(private readonly reflector: Reflector) {}
canActivate(
context: ExecutionContext
): boolean | Promise<boolean> | Observable<boolean> {
const routePermissions = this.reflector.get<string[]>(
'permissions',
context.getHandler()
);
if (!routePermissions) {
return true;
}
const userPermissions = context.getArgs()[0].user.permissions;
console.log(userPermissions); // Always undefined
const hasPermission = () => {
return routePermissions.every((routePermission) =>
userPermissions.includes(routePermission)
);
};
return hasPermission();
}
}
I then added the decorators to my endpoint:
@UseGuards(AuthGuard('jwt'), PermissionsGuard)
@Get()
@Permissions('read:users')
async find(
@AuthUser() user: IUserToken,
@Res() response: Response
): Promise<Response> {
console.log(user); // Always undefined