authentication.guard.ts 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. import {
  2. CanActivate,
  3. ExecutionContext,
  4. Injectable,
  5. UnauthorizedException,
  6. } from '@nestjs/common';
  7. import { Reflector } from '@nestjs/core';
  8. import { AuthType } from '../../enums/auth-type.enum';
  9. import { AccessTokenGuard } from '../access-token/access-token.guard';
  10. import { AUTH_TYPE_KEY } from '../../decorators/auth-guard.decorator';
  11. @Injectable()
  12. export class AuthenticationGuard implements CanActivate {
  13. private static readonly defaultAuthType = AuthType.Bearer;
  14. private readonly authTypeGuardMap: Record<
  15. AuthType,
  16. CanActivate | CanActivate[]
  17. > = {
  18. [AuthType.Bearer]: this.accessTokenGuard,
  19. [AuthType.None]: { canActivate: () => true },
  20. };
  21. constructor(
  22. private readonly reflector: Reflector,
  23. private readonly accessTokenGuard: AccessTokenGuard,
  24. ) {}
  25. async canActivate(context: ExecutionContext): Promise<boolean> {
  26. const authTypes = this.reflector.getAllAndOverride<AuthType[]>(
  27. AUTH_TYPE_KEY,
  28. [context.getHandler(), context.getClass()],
  29. ) ?? [AuthenticationGuard.defaultAuthType];
  30. const guards = authTypes.map((type) => this.authTypeGuardMap[type]).flat();
  31. let error = new UnauthorizedException();
  32. for (const instance of guards) {
  33. const canActivate = await Promise.resolve(
  34. instance.canActivate(context),
  35. ).catch((err) => {
  36. error = err;
  37. });
  38. if (canActivate) {
  39. return true;
  40. }
  41. }
  42. throw error;
  43. }
  44. }