-
-
Notifications
You must be signed in to change notification settings - Fork 115
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
33 changed files
with
972 additions
and
105 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
# Changelog | ||
|
||
All notable changes to this project will be documented in this file. | ||
|
||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) | ||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). | ||
|
||
## Unreleased | ||
|
||
- Initial release |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,22 +1,21 @@ | ||
import { Test, TestingModule } from '@nestjs/testing'; | ||
|
||
import { AppController } from './app.controller'; | ||
import { AppService } from './app.service'; | ||
|
||
describe('AppController', () => { | ||
let app: TestingModule; | ||
|
||
beforeAll(async () => { | ||
app = await Test.createTestingModule({ | ||
controllers: [AppController], | ||
providers: [AppService], | ||
providers: [], | ||
}).compile(); | ||
}); | ||
|
||
describe('getData', () => { | ||
describe('healthCheck', () => { | ||
it('should return "Hello API"', () => { | ||
const appController = app.get<AppController>(AppController); | ||
expect(appController.getData()).toEqual({ message: 'Hello API' }); | ||
expect(appController.health()).toEqual('UP'); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,11 @@ | ||
import { Controller, Get } from '@nestjs/common'; | ||
import { AppService } from './app.service'; | ||
import { SupabaseService } from '../supabase/supabase.service'; | ||
|
||
@Controller() | ||
export class AppController { | ||
constructor( | ||
private readonly appService: AppService, | ||
private readonly supabaseService: SupabaseService, | ||
) {} | ||
constructor() {} | ||
|
||
@Get() | ||
getHello(): string { | ||
return this.appService.getData().message; | ||
@Get('health') | ||
health(): string { | ||
return 'UP'; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import { Controller, Param, Post, Query } from '@nestjs/common'; | ||
import { AuthService } from './auth.service'; | ||
import { UserAuthenticatedResponse } from './auth.types'; | ||
|
||
@Controller('auth') | ||
export class AuthController { | ||
constructor( | ||
private authService: AuthService | ||
) {} | ||
|
||
@Post('send-otp/:email') | ||
async sendOtp(@Param('email') email: string): Promise<void> { | ||
await this.authService.sendOtp(email); | ||
} | ||
|
||
@Post('validate-otp') | ||
async validateOtp( | ||
@Query('email') email: string, | ||
@Query('otp') otp: string) | ||
: Promise<UserAuthenticatedResponse> { | ||
return await this.authService.validateOtp(email, otp); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import { Module } from '@nestjs/common'; | ||
import { AuthService } from './auth.service'; | ||
import { AuthController } from './auth.controller'; | ||
import { JwtModule } from '@nestjs/jwt'; | ||
|
||
@Module({ | ||
imports: [ | ||
JwtModule.register({ | ||
global: true, | ||
secret: process.env.JWT_SECRET, | ||
signOptions: { | ||
expiresIn: '1d' , | ||
issuer: 'keyshade.xyz', | ||
algorithm: 'HS256', | ||
} | ||
}) | ||
], | ||
providers: [AuthService], | ||
controllers: [AuthController] | ||
}) | ||
export class AuthModule {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import { Test, TestingModule } from '@nestjs/testing'; | ||
import { AuthService } from './auth.service'; | ||
import { PrimsaRepository } from '../prisma/prisma.repository'; | ||
import { TestResend } from '../resend/services/test.resend'; | ||
import { RESEND_SERVICE } from '../resend/services/resend.service.interface'; | ||
import { JwtService } from '@nestjs/jwt'; | ||
import { PrismaService } from '../prisma/prisma.service'; | ||
|
||
describe('AuthService', () => { | ||
let service: AuthService; | ||
|
||
beforeEach(async () => { | ||
const module: TestingModule = await Test.createTestingModule({ | ||
providers: [ | ||
AuthService, | ||
PrimsaRepository, | ||
{ provide: RESEND_SERVICE, useClass: TestResend }, | ||
JwtService, | ||
PrismaService | ||
], | ||
}).compile(); | ||
|
||
service = module.get<AuthService>(AuthService); | ||
}); | ||
|
||
it('should be defined', () => { | ||
expect(service).toBeDefined(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import { HttpException, HttpStatus, Inject, Injectable } from '@nestjs/common'; | ||
import { PrimsaRepository } from '../prisma/prisma.repository'; | ||
import { randomUUID } from 'crypto'; | ||
import { JwtService } from '@nestjs/jwt'; | ||
import { UserAuthenticatedResponse } from './auth.types'; | ||
import { IResendService, RESEND_SERVICE } from '../resend/services/resend.service.interface'; | ||
|
||
@Injectable() | ||
export class AuthService { | ||
private readonly OTP_EXPIRY = 5 * 60 * 1000; // 5 minutes | ||
constructor( | ||
private repository: PrimsaRepository, | ||
@Inject(RESEND_SERVICE) private resend: IResendService, | ||
private jwt: JwtService | ||
) {} | ||
|
||
async sendOtp(email: string): Promise<void> { | ||
if (!email || !email.includes('@')) { | ||
console.error(`Invalid email address: ${email}`); | ||
throw new HttpException('Please enter a valid email address', HttpStatus.BAD_REQUEST); | ||
} | ||
|
||
// We need to create the user if it doesn't exist yet | ||
if (!await this.repository.findUserByEmail(email)) { | ||
await this.repository.createUser(email); | ||
} | ||
|
||
const otp = await this.repository.createOtp( | ||
email, | ||
randomUUID().slice(0, 6).toUpperCase(), | ||
this.OTP_EXPIRY); | ||
|
||
await this.resend.sendOtp(email, otp.code); | ||
console.info(`Login code sent to ${email}: ${otp.code}`); | ||
} | ||
|
||
async validateOtp(email: string, otp: string): Promise<UserAuthenticatedResponse> { | ||
const user = await this.repository.findUserByEmail(email); | ||
if (!user) { | ||
console.error(`User not found: ${email}`); | ||
throw new HttpException('User not found', HttpStatus.NOT_FOUND); | ||
} | ||
|
||
if (!await this.repository.isOtpValid(email, otp)) { | ||
console.error(`Invalid login code for ${email}: ${otp}`); | ||
throw new HttpException('Invalid login code', HttpStatus.UNAUTHORIZED); | ||
} | ||
|
||
await this.repository.deleteOtp(email, otp); | ||
|
||
return { | ||
...user, | ||
token: await this.jwt.signAsync({ id: user.id, email: user.email }) | ||
}; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import { User } from "@prisma/client"; | ||
|
||
export type UserAuthenticatedResponse = User & { | ||
token: string; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import { Global, Module } from '@nestjs/common'; | ||
|
||
@Global() | ||
@Module({ | ||
providers: [], | ||
exports: [] | ||
}) | ||
export class CommonModule {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.