From 75cfde34f46f1aa3244a95c48f0fbff10345edc5 Mon Sep 17 00:00:00 2001 From: kamaldeen Aliyu Date: Fri, 29 May 2026 13:37:13 +0100 Subject: [PATCH] implemented helment --- package-lock.json | 13 +++++++++++++ package.json | 1 + src/config/config.module.ts | 10 +++++----- src/dtos/create-cat.dto.ts | 2 +- src/idempotency/idempotency.entity.ts | 8 +++++++- src/idempotency/idempotency.module.ts | 5 ++++- src/main.ts | 19 ++++++++++++++++--- src/wallet/wallets.types.ts | 9 ++++----- test/app.e2e-spec.ts | 5 +++-- 9 files changed, 54 insertions(+), 18 deletions(-) diff --git a/package-lock.json b/package-lock.json index dd27f6e..a294d89 100644 --- a/package-lock.json +++ b/package-lock.json @@ -35,6 +35,7 @@ "class-transformer": "^0.5.1", "class-validator": "^0.14.0", "handlebars": "^4.7.9", + "helmet": "^8.2.0", "ioredis": "^5.10.1", "jsonwebtoken": "^9.0.3", "nodemailer": "^8.0.4", @@ -8398,6 +8399,18 @@ "node": ">= 0.4" } }, + "node_modules/helmet": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/helmet/-/helmet-8.2.0.tgz", + "integrity": "sha512-DRgTIUgnWcJ62KyarxxziuqYxKGnR6Rgg19BlbucN/dpmJbl1XOit6qvoOX0ZT+HhWe5OUVhU/a1zpGyc1xA0Q==", + "license": "MIT", + "engines": { + "node": ">=18.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/EvanHahn" + } + }, "node_modules/hookified": { "version": "1.15.1", "resolved": "https://registry.npmjs.org/hookified/-/hookified-1.15.1.tgz", diff --git a/package.json b/package.json index 5c70c73..4100523 100644 --- a/package.json +++ b/package.json @@ -51,6 +51,7 @@ "class-transformer": "^0.5.1", "class-validator": "^0.14.0", "handlebars": "^4.7.9", + "helmet": "^8.2.0", "ioredis": "^5.10.1", "jsonwebtoken": "^9.0.3", "nodemailer": "^8.0.4", diff --git a/src/config/config.module.ts b/src/config/config.module.ts index 0d7f79c..522a015 100644 --- a/src/config/config.module.ts +++ b/src/config/config.module.ts @@ -1,12 +1,12 @@ -import { Module } from "@nestjs/common"; -import { ConfigModule as NestConfigModule } from "@nestjs/config"; -import { validateEnv } from "./env.validation"; -import configuration from "./configuration"; +import { Module } from '@nestjs/common'; +import { ConfigModule as NestConfigModule } from '@nestjs/config'; +import { validateEnv } from './env.validation'; +import configuration from './configuration'; /** * Global configuration module that provides validated environment variables * throughout the application. - * + * * Features: * - Strict validation at startup (fail-fast) * - Type-safe configuration access diff --git a/src/dtos/create-cat.dto.ts b/src/dtos/create-cat.dto.ts index a332fde..8847fa8 100644 --- a/src/dtos/create-cat.dto.ts +++ b/src/dtos/create-cat.dto.ts @@ -11,4 +11,4 @@ export class CreateCatDto { @IsNotEmpty() readonly age: number; -} \ No newline at end of file +} diff --git a/src/idempotency/idempotency.entity.ts b/src/idempotency/idempotency.entity.ts index de900d0..7787382 100644 --- a/src/idempotency/idempotency.entity.ts +++ b/src/idempotency/idempotency.entity.ts @@ -1,4 +1,10 @@ -import { Entity, Column, PrimaryColumn, CreateDateColumn, Index } from 'typeorm'; +import { + Entity, + Column, + PrimaryColumn, + CreateDateColumn, + Index, +} from 'typeorm'; @Entity('idempotency_keys') @Index(['createdAt']) diff --git a/src/idempotency/idempotency.module.ts b/src/idempotency/idempotency.module.ts index 3162666..ecb8d80 100644 --- a/src/idempotency/idempotency.module.ts +++ b/src/idempotency/idempotency.module.ts @@ -8,7 +8,10 @@ import { IdempotencyInterceptor } from './idempotency.interceptor'; import { IdempotencyCleanupJob } from './cleanup.job'; @Module({ - imports: [TypeOrmModule.forFeature([IdempotencyKey]), ScheduleModule.forRoot()], + imports: [ + TypeOrmModule.forFeature([IdempotencyKey]), + ScheduleModule.forRoot(), + ], providers: [ IdempotencyService, IdempotencyGuard, diff --git a/src/main.ts b/src/main.ts index ce24095..1417269 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,10 +1,24 @@ -import { NestFactory, ValidationPipe } from '@nestjs/core'; +import { NestFactory } from '@nestjs/core'; +import { ValidationPipe } from '@nestjs/common'; import { AppModule } from './app.module'; import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger'; +import helmet from 'helmet'; async function bootstrap() { const app = await NestFactory.create(AppModule); app.setGlobalPrefix('api/v1'); + app.use( + helmet({ + contentSecurityPolicy: { + directives: { + defaultSrc: ["'self'"], + styleSrc: ["'self'", "'unsafe-inline'"], + scriptSrc: ["'self'"], + imgSrc: ["'self'", 'data:', 'https:'], + }, + }, + }), + ); app.useGlobalPipes( new ValidationPipe({ whitelist: true, @@ -13,7 +27,6 @@ async function bootstrap() { }), ); - // Configure Swagger/OpenAPI const swaggerConfig = new DocumentBuilder() .setTitle('NexaFx API') .setDescription('NexaFx financial platform REST API') @@ -29,4 +42,4 @@ async function bootstrap() { await app.listen(process.env.PORT ?? 3000); } -bootstrap(); +void bootstrap(); diff --git a/src/wallet/wallets.types.ts b/src/wallet/wallets.types.ts index a7d4059..0c0e949 100644 --- a/src/wallet/wallets.types.ts +++ b/src/wallet/wallets.types.ts @@ -1,6 +1,5 @@ export interface WalletBalance { - accountId: string; - currency: string; - balance: number; - } - \ No newline at end of file + accountId: string; + currency: string; + balance: number; +} diff --git a/test/app.e2e-spec.ts b/test/app.e2e-spec.ts index 471a109..3b58e36 100644 --- a/test/app.e2e-spec.ts +++ b/test/app.e2e-spec.ts @@ -17,7 +17,8 @@ describe('AppController (e2e)', () => { process.env.JWT_SECRET = 'test-jwt-secret'; process.env.REFRESH_TOKEN_SECRET = 'test-refresh-token-secret'; process.env.OTP_SECRET = 'test-otp-secret'; - process.env.WALLET_ENCRYPTION_KEY = '0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef'; + process.env.WALLET_ENCRYPTION_KEY = + '0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef'; process.env.BLOCKCHAIN_RPC_URL = 'http://localhost:8545'; process.env.PROVIDER_API_URL = 'https://api.example.com'; process.env.PROVIDER_API_KEY = 'test-provider-key'; @@ -66,4 +67,4 @@ describe('AppController (e2e)', () => { .send({ name: 'Fluffy', breed: 'Persian', age: 3 }) .expect(201); }); -}); \ No newline at end of file +});