Skip to content

Commit

Permalink
Add warning if target signerUrl doesn't have guard
Browse files Browse the repository at this point in the history
  • Loading branch information
vh13294 committed Sep 8, 2021
1 parent 4a7adce commit 001ffcb
Show file tree
Hide file tree
Showing 7 changed files with 49 additions and 13 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,6 @@ require('crypto').randomBytes(64, (err, buf) => {

### TODO

- [ ] Create unit test (expiration, tampered, with or without globalPrefix, request with or without query & param)
- [ ] Create unit test (expiration, tampered, with or without globalPrefix, request with or without query & param, if target for signerUrl doesn't have guard)

- [ ] Automate CI, npm run build, push, npm publish
- [ ] Add warning if target for signerUrl doesn't have guard
26 changes: 21 additions & 5 deletions lib/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { createHmac, timingSafeEqual } from 'crypto';
import { stringify as qsStringify } from 'qs';

import { PATH_METADATA } from '@nestjs/common/constants';
import { Controller } from '@nestjs/common/interfaces/controllers/controller.interface';

import { BadRequestException } from '@nestjs/common';
import { ControllerMethod, Query, Params } from './interfaces';
import { GUARDS_METADATA, PATH_METADATA } from '@nestjs/common/constants';

import { ControllerMethod, Query, Params, ControllerClass } from './interfaces';
import { SignedUrlGuard } from './signed-url-guard';

export function generateUrl(
appUrl: string,
Expand All @@ -26,14 +26,30 @@ export function stringifyQuery(query?: Query): string {
}

export function getControllerMethodRoute(
controller: Controller,
controller: ControllerClass,
controllerMethod: ControllerMethod,
): string {
const controllerRoute = Reflect.getMetadata(PATH_METADATA, controller);
const methodRoute = Reflect.getMetadata(PATH_METADATA, controllerMethod);
return joinRoutes(controllerRoute, methodRoute);
}

export function checkIfMethodHasSignedGuardDecorator(
controller: ControllerClass,
controllerMethod: ControllerMethod,
): void {
const arrOfClasses = Reflect.getMetadata(GUARDS_METADATA, controllerMethod);
const errorMessage = `Please add SignedUrlGuard to ${controller.name}.${controllerMethod.name}`;
if (!arrOfClasses) {
throw new BadRequestException(errorMessage);
}

const guardExist = arrOfClasses.includes(SignedUrlGuard);
if (!guardExist) {
throw new BadRequestException(errorMessage);
}
}

export function generateHmac(url: string, secret?: string): string {
if (!secret) {
throw new BadRequestException('Secret key is needed for signing URL');
Expand Down
10 changes: 7 additions & 3 deletions lib/interfaces.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { Request } from 'express';
import { Controller } from '@nestjs/common/interfaces/controllers/controller.interface';
import { Controller } from '@nestjs/common/interfaces';

export interface ControllerClass extends Controller {
name: string;
}

export type ControllerMethod = (...args: any[]) => Promise<any> | any;

Expand Down Expand Up @@ -28,7 +32,7 @@ export interface RequestWithSignature extends Request {
}

export interface GenerateUrlFromControllerArgs {
controller: Controller;
controller: ControllerClass;
controllerMethod: ControllerMethod;
query?: Query;
params?: Params;
Expand All @@ -41,7 +45,7 @@ export interface GenerateUrlFromPathArgs {
}

export interface SignControllerUrlArgs {
controller: Controller;
controller: ControllerClass;
controllerMethod: ControllerMethod;
expirationDate?: Date;
query?: NotReservedQuery;
Expand Down
3 changes: 3 additions & 0 deletions lib/url-generator.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
stringifyQuery,
generateUrl,
appendQuery,
checkIfMethodHasSignedGuardDecorator,
} from './helpers';

import {
Expand Down Expand Up @@ -86,6 +87,8 @@ export class UrlGeneratorService {
query,
params,
}: SignControllerUrlArgs): string {
checkIfMethodHasSignedGuardDecorator(controller, controllerMethod);

const controllerMethodFullRoute = getControllerMethodRoute(
controller,
controllerMethod,
Expand Down
4 changes: 2 additions & 2 deletions sample/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions sample/src/emailModule/auth.guard.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Observable } from 'rxjs';

@Injectable()
export class AuthGuard implements CanActivate {
canActivate(
context: ExecutionContext,
): boolean | Promise<boolean> | Observable<boolean> {
const request = context.switchToHttp().getRequest();
return true;
}
}
3 changes: 2 additions & 1 deletion sample/src/emailModule/email.controller.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Controller, Get, Param, Query, UseGuards } from '@nestjs/common';

import { SignedUrlGuard, UrlGeneratorService } from 'nestjs-url-generator';
import { AuthGuard } from './auth.guard';
import { EmailParams } from './params/email.params';
import { EmailQuery } from './query/email.query';

Expand Down Expand Up @@ -45,7 +46,7 @@ export class EmailController {
}

@Get('emailVerification/version/:version/user/:userId')
@UseGuards(SignedUrlGuard)
@UseGuards(SignedUrlGuard, AuthGuard)
async emailVerification(
@Param() emailParams: EmailParams,
@Query() emailQuery: EmailQuery,
Expand Down

0 comments on commit 001ffcb

Please sign in to comment.