Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,20 @@ on:
push:
branches: [main]
pull_request:
branches: [main]

jobs:
build:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'

jobs:
build-and-test:
Expand Down Expand Up @@ -64,6 +78,30 @@ jobs:
- name: Install dependencies
run: npm ci

- name: Lint
run: npm run lint

- name: Build
run: npm run build

- name: Test
run: npm test -- --passWithNoTests
env:
NODE_ENV: test
DB_HOST: localhost
DB_PORT: '5432'
DB_USER: postgres
DB_PASSWORD: postgres
DB_NAME: nexafx_test
JWT_SECRET: test-jwt-secret-at-least-32-characters-long
REFRESH_TOKEN_SECRET: test-refresh-secret-at-least-32-chars
OTP_SECRET: test-otp-secret-at-least-32-characters-long
MAIL_HOST: localhost
MAIL_PORT: '587'
MAIL_USER: test@example.com
MAIL_PASSWORD: testpassword
MAIL_FROM: noreply@example.com
DISABLE_BULL: 'true'
- name: Build
run: npm run build

Expand Down
113 changes: 113 additions & 0 deletions package-lock.json

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

8 changes: 8 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
"@nestjs/event-emitter": "^3.0.1",
"@nestjs/jwt": "^11.0.2",
"@nestjs/mapped-types": "*",
"@nestjs/passport": "^11.0.5",
"@nestjs/platform-express": "^11.0.1",
"@nestjs/platform-socket.io": "^11.1.17",
"@nestjs/schedule": "^6.1.3",
Expand All @@ -45,6 +46,8 @@
"@nestjs/websockets": "^11.1.17",
"@types/nodemailer": "^7.0.11",
"@types/socket.io-client": "^1.4.36",
"axios": "^1.6.0",
"bcryptjs": "^2.4.3",
"axios": "^1.16.1",
"bull": "^4.12.0",
"cache-manager": "^7.2.8",
Expand All @@ -56,6 +59,8 @@
"ioredis": "^5.10.1",
"jsonwebtoken": "^9.0.3",
"nodemailer": "^8.0.4",
"passport": "^0.7.0",
"passport-jwt": "^4.0.1",
"pdf-lib": "^1.17.1",
"pg": "^8.11.3",
"reflect-metadata": "^0.2.2",
Expand All @@ -73,10 +78,13 @@
"@nestjs/testing": "^11.0.1",
"@swc/cli": "^0.6.0",
"@swc/core": "^1.10.7",
"@types/bcryptjs": "^2.4.6",
"@types/express": "^5.0.0",
"@types/jest": "^29.5.14",
"@types/jsonwebtoken": "^9.0.10",
"@types/node": "^22.10.7",
"@types/passport": "^1.0.17",
"@types/passport-jwt": "^4.0.1",
"@types/supertest": "^6.0.2",
"better-sqlite3": "^12.6.2",
"eslint": "^9.18.0",
Expand Down
2 changes: 2 additions & 0 deletions src/app.controller.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { SkipThrottle } from '@nestjs/throttler';
import { Controller, Get, Post, Body } from '@nestjs/common';
import { AppService } from './app.service';
import { Public } from './auth/decorators/public.decorator';
import { CreateCatDto } from './dtos/create-cat.dto';

@SkipThrottle()
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}

@Public()
@Get()
getHello(): string {
return this.appService.getHello();
Expand Down
11 changes: 11 additions & 0 deletions src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ import { AuthModule } from './auth/auth.module';
import { DocumentsModule } from './documents/documents.module';
import { MailModule, MailQueueModule } from './mail/mail.module';
import { IdempotencyModule } from './idempotency/idempotency.module';
import { AuthModule } from './auth/auth.module';
import { JwtAuthGuard } from './auth/guards/jwt-auth.guard';
import { RolesGuard } from './auth/guards/roles.guard';
import { NotificationQueueModule } from './notification/notification.module';
import { TransactionQueueModule } from './transaction/transaction.module';
import { AccountClosureModule } from './users/account-closure.module';
Expand Down Expand Up @@ -148,6 +151,14 @@ const enableBull =
]
: []),
IdempotencyModule,
AuthModule,
],
controllers: [AppController],
providers: [
AppService,
{ provide: APP_GUARD, useClass: JwtAuthGuard },
{ provide: APP_GUARD, useClass: RolesGuard },
],
AccountClosureModule,
AuthModule,
EventEmitterModule.forRoot({ global: true }),
Expand Down
42 changes: 42 additions & 0 deletions src/auth/auth.controller.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,45 @@
import { Body, Controller, HttpCode, HttpStatus, Post, Request } from '@nestjs/common';
import { ApiTags, ApiBearerAuth } from '@nestjs/swagger';
import { AuthService } from './auth.service';
import { Public } from './decorators/public.decorator';

@ApiTags('auth')
@Controller('auth')
export class AuthController {
constructor(private readonly authService: AuthService) {}

@Public()
@Post('register')
register(@Body() body: { email: string; password: string }) {
return this.authService.register(body.email, body.password);
}

@Public()
@HttpCode(HttpStatus.OK)
@Post('login')
login(@Body() body: { email: string; password: string }) {
return this.authService.login(body.email, body.password);
}

@ApiBearerAuth()
@HttpCode(HttpStatus.OK)
@Post('logout')
logout(@Request() req: { user: { id: string } }) {
return this.authService.logout(req.user.id);
}

@Public()
@HttpCode(HttpStatus.OK)
@Post('verify-email')
verifyEmail(@Body() body: { email: string; otp: string }) {
return this.authService.verifyEmail(body.email, body.otp);
}

@Public()
@HttpCode(HttpStatus.OK)
@Post('resend-verification')
resendVerification(@Body() body: { email: string }) {
return this.authService.resendVerification(body.email);
import { Body, Controller, Headers, Ip, Post } from '@nestjs/common';
import { AuthService, CredentialsDto, RegisterDto } from './auth.service';

Expand Down
20 changes: 20 additions & 0 deletions src/auth/auth.module.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,23 @@
import { Module } from '@nestjs/common';
import { JwtModule } from '@nestjs/jwt';
import { PassportModule } from '@nestjs/passport';
import { TypeOrmModule } from '@nestjs/typeorm';
import { AuthController } from './auth.controller';
import { AuthService } from './auth.service';
import { JwtStrategy } from './strategies/jwt.strategy';
import { User } from '../users/user.entity';
import { MailModule } from '../mail/mail.module';

@Module({
imports: [
PassportModule,
JwtModule.register({}),
TypeOrmModule.forFeature([User]),
MailModule,
],
controllers: [AuthController],
providers: [AuthService, JwtStrategy],
exports: [AuthService],
import { Module, forwardRef } from '@nestjs/common';
import { JwtModule } from '@nestjs/jwt';
import { ConfigService } from '@nestjs/config';
Expand Down
Loading