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
5 changes: 5 additions & 0 deletions backend/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@ NODE_ENV=development
PORT=6003
FRONTEND_URL=http://localhost:3000

# Google OAuth
GOOGLE_CLIENT_ID=your_google_client_id
GOOGLE_CLIENT_SECRET=your_google_client_secret
GOOGLE_CALLBACK_URL=http://localhost:3000/api/auth/google/callback

DB_HOST=localhost
DB_PORT=5432
DB_USERNAME=postgres
Expand Down
89 changes: 89 additions & 0 deletions backend/package-lock.json

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

2 changes: 2 additions & 0 deletions backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
"otplib": "^13.1.1",
"papaparse": "^5.5.3",
"passport": "^0.7.0",
"passport-google-oauth20": "^2.0.0",
"passport-jwt": "^4.0.1",
"passport-local": "^1.0.0",
"pdfkit": "^0.17.2",
Expand Down Expand Up @@ -96,6 +97,7 @@
"@types/nodemailer": "^7.0.9",
"@types/otplib": "^7.0.0",
"@types/papaparse": "^5.3.16",
"@types/passport-google-oauth20": "^2.0.17",
"@types/passport-jwt": "^4.0.1",
"@types/passport-local": "^1.0.38",
"@types/pdfkit": "^0.17.3",
Expand Down
4 changes: 4 additions & 0 deletions backend/src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { ConfigModule, ConfigService } from '@nestjs/config';
import { TypeOrmModule } from '@nestjs/typeorm';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { UsersModule } from './users/users.module';
import { AuthModule } from './auth/auth.module';

@Module({
imports: [
Expand All @@ -22,6 +24,8 @@ import { AppService } from './app.service';
}),
inject: [ConfigService],
}),
UsersModule,
AuthModule,
],
controllers: [AppController],
providers: [AppService],
Expand Down
31 changes: 31 additions & 0 deletions backend/src/auth/auth.controller.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { Test, TestingModule } from '@nestjs/testing';
import { AuthController } from './auth.controller';
import { AuthService } from './auth.service';

describe('AuthController', () => {
let controller: AuthController;

const mockAuthService = {
forgotPassword: jest.fn(),
resetPassword: jest.fn(),
validateOAuthLogin: jest.fn(),
};

beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [AuthController],
providers: [
{
provide: AuthService,
useValue: mockAuthService,
},
],
}).compile();

controller = module.get<AuthController>(AuthController);
});

it('should be defined', () => {
expect(controller).toBeDefined();
});
});
44 changes: 44 additions & 0 deletions backend/src/auth/auth.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import {
Controller,
Post,
Body,
Get,
UseGuards,
Req,
HttpCode,
HttpStatus,
} from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { AuthService } from './auth.service';

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

@Post('forgot-password')
@HttpCode(HttpStatus.OK)
async forgotPassword(@Body('email') email: string) {
await this.authService.forgotPassword(email);
return { message: 'If the email exists, a reset link has been sent.' };
}

@Post('reset-password')
@HttpCode(HttpStatus.OK)
async resetPassword(@Body() body: any) {
await this.authService.resetPassword(body.token, body.newPassword);
return { message: 'Password has been reset successfully.' };
}

@Get('google')
@UseGuards(AuthGuard('google'))
async googleAuth() {
// Initiates the Google OAuth flow
}

@Get('google/callback')
@UseGuards(AuthGuard('google'))
async googleAuthRedirect(@Req() req: any) {
// user is attached to req by the strategy
return req.user;
}
}
22 changes: 22 additions & 0 deletions backend/src/auth/auth.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { PassportModule } from '@nestjs/passport';
import { AuthController } from './auth.controller';
import { AuthService } from './auth.service';
import { GoogleStrategy } from './strategies/google.strategy';
import { PasswordResetToken } from './entities/password-reset-token.entity';
import { UsersModule } from '../users/users.module';
import { MailModule } from '../mail/mail.module';

@Module({
imports: [
TypeOrmModule.forFeature([PasswordResetToken]),
PassportModule,
UsersModule,
MailModule,
],
controllers: [AuthController],
providers: [AuthService, GoogleStrategy],
exports: [AuthService],
})
export class AuthModule {}
Loading
Loading