Skip to content

Commit

Permalink
Feat/hmac (SOS-RS#164)
Browse files Browse the repository at this point in the history
- Added hmac decorator to protect endpoints
  • Loading branch information
fagundesjg authored May 23, 2024
1 parent 6388fce commit 48d9e1b
Show file tree
Hide file tree
Showing 8 changed files with 57 additions and 0 deletions.
1 change: 1 addition & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ DB_PASSWORD=
DB_DATABASE_NAME=
DATABASE_URL="postgresql://${DB_USER}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_DATABASE_NAME}?schema=public"
SECRET_KEY=
HMAC_SECRET_KEY=

HOST=::0.0.0.0
PORT=4000
1 change: 1 addition & 0 deletions .env.local
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ DB_PASSWORD=root
DATABASE_URL="postgresql://${DB_USER}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_DATABASE_NAME}?schema=public"

SECRET_KEY=batata
HMAC_SECRET_KEY=

HOST=::0.0.0.0
PORT=4000
1 change: 1 addition & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ jobs:
echo SECRET_KEY=${{ secrets.SECRET_KEY }} >> .env
echo HOST=${{ secrets.HOST }} >> .env
echo PORT=${{ secrets.PORT }} >> .env
echo HMAC_SECRET_KEY=${{ secrets.HMAC_SECRET_KEY }} >> .env
echo SERVER_USER_PASSWORD=${{ secrets.SERVER_USER_PASSWORD }} >> .env
cat .env
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ jobs:
echo SECRET_KEY=${{ secrets.SECRET_KEY }} >> .env
echo HOST=${{ secrets.HOST }} >> .env
echo PORT=${{ secrets.PORT }} >> .env
echo HMAC_SECRET_KEY=${{ secrets.HMAC_SECRET_KEY }} >> .env
echo SERVER_USER_PASSWORD=${{ secrets.SERVER_USER_PASSWORD }} >> .env
cat .env
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/staging.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ jobs:
echo SECRET_KEY=${{ secrets.SECRET_KEY }} >> .env
echo HOST=${{ secrets.HOST }} >> .env
echo PORT=${{ secrets.PORT }} >> .env
echo HMAC_SECRET_KEY=${{ secrets.HMAC_SECRET_KEY }} >> .env
echo SERVER_USER_PASSWORD=${{ secrets.SERVER_USER_PASSWORD }} >> .env
cat .env
Expand Down
7 changes: 7 additions & 0 deletions src/decorators/Hmac/hmac.decorator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { applyDecorators, UseGuards } from '@nestjs/common';

import { HmacGuard } from '@/guards/hmac.guard';

export function Hmac() {
return applyDecorators(UseGuards(HmacGuard));
}
3 changes: 3 additions & 0 deletions src/decorators/Hmac/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { Hmac } from './hmac.decorator';

export { Hmac };
42 changes: 42 additions & 0 deletions src/guards/hmac.guard.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import {
Injectable,
CanActivate,
ExecutionContext,
UnauthorizedException,
} from '@nestjs/common';
import * as crypto from 'crypto';

@Injectable()
export class HmacGuard implements CanActivate {
constructor() {}

canActivate(context: ExecutionContext): boolean {
const request = context.switchToHttp().getRequest();
const hmacHeader = request.headers['x-hmac-signature'];
const timestamp = request.headers['x-hmac-timestamp'];

if (!hmacHeader || !timestamp) {
throw new UnauthorizedException();
}

const secretKey = process.env.HMAC_SECRET_KEY ?? '';
const currentTimestamp = Math.floor(Date.now() / 1000);

if (Math.abs(currentTimestamp - parseInt(timestamp)) > 10) {
throw new UnauthorizedException();
}

const payload = `${request.method}:${request.url}:${timestamp}:${JSON.stringify(request.body)}`;

const hmac = crypto
.createHmac('sha256', secretKey)
.update(payload)
.digest('hex');

if (hmac !== hmacHeader) {
throw new UnauthorizedException();
}

return true;
}
}

0 comments on commit 48d9e1b

Please sign in to comment.