FIX: add authentication to swagger

This commit is contained in:
Gabriel Rosa
2023-02-08 15:23:49 -03:00
parent cdba41dffa
commit 8043635b1c
9 changed files with 621 additions and 45 deletions
+15 -7
View File
@@ -1,7 +1,8 @@
import { Request } from 'express';
import { CustomDecorator } from '@nestjs/common';
import { applyDecorators, CustomDecorator } from '@nestjs/common';
import { PermissionsObjectPermission } from './permissions.enum';
import { RequestUser } from './user.decorator';
import { ApiSecurity } from '@nestjs/swagger';
export const AUTH_FUNCTION_KEY = '__AUTH_FUNCTION__';
@@ -10,7 +11,7 @@ export type AuthenticationFunction = (req: Request, user: any) => boolean;
// implementation copied from SetMetadata, but tweaked to get existing values
// of the metadataKey and accumulate it with the new metadataValue
function SetMultipleMetadata(metadataKey, metadataValue): CustomDecorator {
const decoratorFactory = (target, key, descriptor) => {
const decoratorFactory: CustomDecorator = (target, key?, descriptor?) => {
// .start: tweak
// descriptor?.value = function decorator; target = class decorator
const accumulatedVal =
@@ -28,13 +29,20 @@ function SetMultipleMetadata(metadataKey, metadataValue): CustomDecorator {
};
decoratorFactory.KEY = metadataKey;
return decoratorFactory as any;
return decoratorFactory;
}
function createAuthenticatedDecorator(metadataValue: AuthenticationFunction) {
return applyDecorators(
ApiSecurity('access-token'),
SetMultipleMetadata(AUTH_FUNCTION_KEY, metadataValue),
);
}
export function RequireAllPermissions(
...permissions: PermissionsObjectPermission[]
) {
return SetMultipleMetadata(AUTH_FUNCTION_KEY, (req, user: RequestUser) =>
return createAuthenticatedDecorator((req, user: RequestUser) =>
permissions.every(({ seqid }) => user.permissions.includes(seqid)),
);
}
@@ -42,15 +50,15 @@ export function RequireAllPermissions(
export function RequireSomePermission(
...permissions: PermissionsObjectPermission[]
) {
return SetMultipleMetadata(AUTH_FUNCTION_KEY, (req, user: RequestUser) =>
return createAuthenticatedDecorator((req, user: RequestUser) =>
permissions.some(({ seqid }) => user.permissions.includes(seqid)),
);
}
export function AuthenticateCondition(func: AuthenticationFunction) {
return SetMultipleMetadata(AUTH_FUNCTION_KEY, func);
return createAuthenticatedDecorator(func);
}
export function Authenticated() {
return SetMultipleMetadata(AUTH_FUNCTION_KEY, () => true);
return createAuthenticatedDecorator(() => true);
}
+2 -5
View File
@@ -54,14 +54,11 @@ export class AuthenticationGuard
>(AUTH_FUNCTION_KEY, [ctx.getClass(), ctx.getHandler()]);
const mustBeAuthenticated = authFunctions.length > 0;
if (!mustBeAuthenticated) return true;
const request = ctx.switchToHttp().getRequest();
const accessToken = this.validateToken(request, mustBeAuthenticated);
if (!mustBeAuthenticated) {
// no need to be authenticated
return true;
}
if (!accessToken) {
// couldn't load valid token
throw new ErrorBuilder(ErrorCodes.AUTH.UNAUTHORIZED);