Skip to content

Commit

Permalink
Merge pull request #170 from portableDD/feat/admin
Browse files Browse the repository at this point in the history
"feat: admin auth"
  • Loading branch information
Ibinola authored Feb 26, 2025
2 parents 5f00ab2 + 026f7ad commit d8d63d4
Show file tree
Hide file tree
Showing 18 changed files with 580 additions and 61 deletions.
7 changes: 7 additions & 0 deletions backend/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@ JWT_TOKEN_ISSUER=
JWT_ACCESS_TOKEN_TTL=
JWT_REFRESH_TOKEN_TTL=


# Admin JWT
JWT_ADMIN_SECRET=super-secret-admin-jwt-key
JWT_ADMIN_EXPIRATION=15m
JWT_ADMIN_REFRESH_SECRET=super-secret-admin-refresh-key
JWT_ADMIN_REFRESH_EXPIRATION=7d

# Application
PORT=3000
NODE_ENV=development
Expand Down
90 changes: 85 additions & 5 deletions backend/package-lock.json

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

7 changes: 6 additions & 1 deletion backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,12 @@
"jsonwebtoken": "^9.0.2",
"passport": "^0.7.0",
"passport-jwt": "^4.0.1",
"passport-local": "^1.0.0",
"pg": "^8.13.3",
"reflect-metadata": "^0.2.0",
"rxjs": "^7.8.1",
"typeorm": "^0.3.20"
"typeorm": "^0.3.20",
"uuid": "^11.1.0"
},
"devDependencies": {
"@nestjs/cli": "^10.0.0",
Expand All @@ -55,7 +57,10 @@
"@types/express": "^5.0.0",
"@types/jest": "^29.5.2",
"@types/node": "^20.3.1",
"@types/passport-jwt": "^4.0.1",
"@types/passport-local": "^1.0.38",
"@types/supertest": "^6.0.0",
"@types/uuid": "^10.0.0",
"@typescript-eslint/eslint-plugin": "^8.0.0",
"@typescript-eslint/parser": "^8.0.0",
"cross-env": "^7.0.3",
Expand Down
68 changes: 68 additions & 0 deletions backend/src/admin/admin-auth.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import {
Controller,
Post,
Body,
UseGuards,
Request,
HttpCode,
Get,
} from '@nestjs/common';
import { AdminJwtAuthGuard } from './guards/admin-jwt-auth.guard';
import { AdminLocalAuthGuard } from './guards/admin-local-auth.guard';
import { AdminAuthService } from './providers/admin-auth.services';

@Controller('admin/auth')
export class AdminAuthController {
constructor(private adminAuthService: AdminAuthService) {}

@UseGuards(AdminLocalAuthGuard)
@Post('login')
@HttpCode(200)
async login(@Request() req) {
return this.adminAuthService.login(req.user);
}

@Post('refresh-token')
@HttpCode(200)
async refreshToken(@Body('refreshToken') refreshToken: string) {
return this.adminAuthService.refreshToken(refreshToken);
}

@Post('forgot-password')
@HttpCode(200)
async forgotPassword(@Body('email') email: string) {
return this.adminAuthService.forgotPassword(email);
}

@Post('reset-password')
@HttpCode(200)
async resetPassword(
@Body('email') email: string,
@Body('token') token: string,
@Body('newPassword') newPassword: string,
) {
return this.adminAuthService.resetPassword(email, token, newPassword);
}

@Post('send-verification')
@UseGuards(AdminJwtAuthGuard)
@HttpCode(200)
async sendVerification(@Request() req) {
return this.adminAuthService.sendVerificationEmail(req.user.id);
}

@Post('verify-email')
@HttpCode(200)
async verifyEmail(
@Body('email') email: string,
@Body('token') token: string,
) {
return this.adminAuthService.verifyEmail(email, token);
}

@Get('me')
@UseGuards(AdminJwtAuthGuard)
getProfile(@Request() req) {
return req.user;
}
}
20 changes: 0 additions & 20 deletions backend/src/admin/admin.controller.spec.ts

This file was deleted.

2 changes: 1 addition & 1 deletion backend/src/admin/admin.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
Put,
UseGuards,
} from '@nestjs/common';
import { AdminService } from './admin.service';
import { AdminService } from './providers/admin.service';
import { CreateAdminDto } from './dto/create-admin.dto';
import { UpdateAdminDto } from './dto/update-admin.dto';
import { RolesGuard } from 'security/roles.guard';
Expand Down
42 changes: 37 additions & 5 deletions backend/src/admin/admin.module.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,45 @@
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { AdminService } from './admin.service';
import { JwtModule } from '@nestjs/jwt';
import { PassportModule } from '@nestjs/passport';
import { ConfigModule, ConfigService } from '@nestjs/config';

import { AdminService } from './providers/admin.service';
import { AdminController } from './admin.controller';
import { AdminAuthController } from './admin-auth.controller';
import { AdminJwtStrategy } from './strategies/admin-jwt.strategy';
import { AdminLocalStrategy } from './strategies/admin-local.strategy';
import { Admin } from './entities/admin.entity';
import { AdminAuthService } from './providers/admin-auth.services';
import { BcryptProvider } from './providers/bcrpt-provider';
import { HashingProvider } from './providers/hashing-services';

@Module({
imports: [TypeOrmModule.forFeature([Admin])],
controllers: [AdminController],
providers: [AdminService],
exports: [AdminService],
imports: [
TypeOrmModule.forFeature([Admin]),
PassportModule,
JwtModule.registerAsync({
imports: [ConfigModule],
useFactory: async (configService: ConfigService) => ({
secret: configService.get<string>('JWT_ADMIN_SECRET'),
signOptions: {
expiresIn: configService.get<string>('JWT_ADMIN_EXPIRATION', '15m'),
},
}),
inject: [ConfigService],
}),
],
controllers: [AdminController, AdminAuthController],
providers: [
AdminService,
AdminAuthService,
AdminJwtStrategy,
AdminLocalStrategy,
{
provide: HashingProvider,
useClass: BcryptProvider,
},
],
exports: [AdminService, AdminAuthService],
})
export class AdminModule {}
18 changes: 0 additions & 18 deletions backend/src/admin/admin.service.spec.ts

This file was deleted.

32 changes: 31 additions & 1 deletion backend/src/admin/entities/admin.entity.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';
import {
Entity,
PrimaryGeneratedColumn,
Column,
CreateDateColumn,
UpdateDateColumn,
} from 'typeorm';

@Entity('admin')
export class Admin {
Expand All @@ -16,4 +22,28 @@ export class Admin {

@Column({ default: 'admin' })
role: string;

@Column({ default: false })
emailVerified: boolean;

@Column({ nullable: true })
refreshToken: string;

@Column({ nullable: true })
resetToken: string;

@Column({ type: 'timestamp', nullable: true })
resetTokenExpiry: Date;

@Column({ nullable: true })
verificationToken: string;

@Column({ type: 'timestamp', nullable: true })
verificationTokenExpiry: Date;

@CreateDateColumn()
createdAt: Date;

@UpdateDateColumn()
updatedAt: Date;
}
Loading

0 comments on commit d8d63d4

Please sign in to comment.