Skip to content

Commit

Permalink
Add extensibility parameter to avoid code validation
Browse files Browse the repository at this point in the history
  • Loading branch information
oegea committed Oct 23, 2024
1 parent f255e0c commit 1ea113c
Show file tree
Hide file tree
Showing 11 changed files with 42 additions and 28 deletions.
5 changes: 2 additions & 3 deletions authentication-service/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,10 @@ app.use(expressEnableCorsMiddleware)
app.use(express.json())

export const startAuthenticationService = async (): Promise<express.Application> => {

app.get('/login/:email', (req, res) => {
startLoginController(req, res).execute()
})

app.get('/login/:email/validate/:code', (req, res) => {
validateLoginController(req, res).execute()
})
Expand All @@ -37,4 +36,4 @@ export const getExpressApp = (): express.Application => {
return app
}

export {express, loadConfig, startLoginController, validateLoginController}
export { express, loadConfig, startLoginController, validateLoginController }
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,26 @@ import { ValidateLoginRequestValueObject } from '../../domain/valueObjects/Valid
import { ValidateLoginService } from '../../domain/services/ValidateLoginService'

class ValidateLoginUseCase {
private readonly validateLoginRequestValueObject: ({ email, code, sessionDetails }: {email: string, code: number, sessionDetails?: any}) => Promise<ValidateLoginRequestValueObject>
private readonly validateLoginRequestValueObject: (
{ email, code, sessionDetails, skipCodeValidation }: {email: string, code: number, sessionDetails?: any, skipCodeValidation?: boolean}
) => Promise<ValidateLoginRequestValueObject>

private readonly validateLoginService: ValidateLoginService

constructor ({
validateLoginRequestValueObject,
validateLoginService
}: {
validateLoginRequestValueObject: ({ email, code, sessionDetails }: {email: string, code: number, sessionDetails?: any}) => Promise<ValidateLoginRequestValueObject>
validateLoginRequestValueObject: ({ email, code, sessionDetails, skipCodeValidation }: {email: string, code: number, sessionDetails?: any, skipCodeValidation?: boolean}) => Promise<ValidateLoginRequestValueObject>
validateLoginService: ValidateLoginService
}) {
this.validateLoginRequestValueObject = validateLoginRequestValueObject
this.validateLoginService = validateLoginService
}

public async execute ({ email, code, sessionDetails }: {email: string, code: number, sessionDetails?: any}): Promise<string> {
public async execute ({ email, code, sessionDetails, skipCodeValidation }: {email: string, code: number, sessionDetails?: any, skipCodeValidation?: boolean}): Promise<string> {
try {
const validateLoginRequestValueObject = await this.validateLoginRequestValueObject({ email, code, sessionDetails })
const validateLoginRequestValueObject = await this.validateLoginRequestValueObject({ email, code, sessionDetails, skipCodeValidation })
return await this.validateLoginService.execute({ validateLoginRequestValueObject })
} catch (e) {
throw e.message
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
interface ClientIPAddressRepository {
get: () => Promise<string>
get: () => Promise<string>
}
export { ClientIPAddressRepository }

Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ class StartLoginService {
}: {
startLoginRequestValueObject: StartLoginRequestValueObject
}): Promise<void> {

// For security purposes, we'll wait sometime before returning the token
await new Promise((resolve) => setTimeout(resolve, WAIT_TIME))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,15 @@ class ValidateLoginService {
// For security purposes, we'll wait sometime before returning the token
await new Promise((resolve) => setTimeout(resolve, WAIT_TIME))

// Should not continue if provided code and email is not valid
const codeIsValid = await this.loginRepository.verifyCode(validateLoginRequestValueObject)
if (!validateLoginRequestValueObject.shouldSkipCodeValidation()) {
// Should not continue if provided code and email is not valid
const codeIsValid = await this.loginRepository.verifyCode(validateLoginRequestValueObject)

// Remove the code from the database even if it is not valid
await this.loginRepository.removeCode(validateLoginRequestValueObject)
// Remove the code from the database even if it is not valid
await this.loginRepository.removeCode(validateLoginRequestValueObject)

if (!codeIsValid) { throw new Error('ValidateLoginService: received code is not valid') }
if (!codeIsValid) { throw new Error('ValidateLoginService: received code is not valid') }
}

const token = this.tokenGeneratorRepository.generateToken(validateLoginRequestValueObject)
return await token
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class StartLoginRequestValueObject {
emailValueObject,
ipAddress
}: {
emailValueObject: EmailValueObject,
emailValueObject: EmailValueObject
ipAddress: string
}) {
this.emailValueObject = emailValueObject
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,23 @@ class ValidateLoginRequestValueObject {
private readonly code: number
private readonly emailValueObject: EmailValueObject
private readonly sessionDetails: any
private readonly skipCodeValidation: boolean

constructor ({
code,
emailValueObject,
sessionDetails
sessionDetails,
skipCodeValidation = false
}: {
code: number
emailValueObject: EmailValueObject,
emailValueObject: EmailValueObject
sessionDetails?: any
skipCodeValidation?: boolean
}) {
this.code = code
this.emailValueObject = emailValueObject
this.sessionDetails = sessionDetails
this.skipCodeValidation = skipCodeValidation
}

async validate (): Promise<void> {
Expand All @@ -31,6 +35,10 @@ class ValidateLoginRequestValueObject {
return this.emailValueObject.getEmail()
}

shouldSkipCodeValidation (): boolean {
return this.skipCodeValidation
}

getSessionDetails (): any {
return this.sessionDetails
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const startLoginRequestValueObject = async ({
email,
ipAddress
}: {
email: string,
email: string
ipAddress: string
}): Promise<StartLoginRequestValueObject> => {
const emailValueObjectInstance = await emailValueObject({ email })
Expand All @@ -40,17 +40,20 @@ const startLoginRequestValueObject = async ({
const validateLoginRequestValueObject = async ({
email,
code,
sessionDetails
sessionDetails,
skipCodeValidation
}: {
email: string
code: number,
code: number
sessionDetails?: any
skipCodeValidation?: boolean
}): Promise<ValidateLoginRequestValueObject> => {
const emailValueObjectInstance = await emailValueObject({ email })
const validateLoginRequestValueObject = new ValidateLoginRequestValueObject({
code,
emailValueObject: emailValueObjectInstance,
sessionDetails
sessionDetails,
skipCodeValidation
})

await validateLoginRequestValueObject.validate()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ class ValidateLoginController extends SharedController {

const number = parseInt(code)

const skipCodeValidation = this.req.skipCodeValidation === 'true'

const useCase = validateLoginUseCase()
const token = await useCase.execute({ email, code: number, sessionDetails })
const token = await useCase.execute({ email, code: number, sessionDetails, skipCodeValidation })
this.success(token)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import { EmailValidatorRepository } from '../../domain/repositories/EmailValidat
class LocalEmailValidatorRepository implements EmailValidatorRepository {
async hasValidFormat (email: string): Promise<boolean> {
try {
const regexEmail = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return regexEmail.test(email);
const regexEmail = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
return regexEmail.test(email)
} catch (e) {
console.error(e)
return false
}
}
}

export { LocalEmailValidatorRepository }
export { LocalEmailValidatorRepository }
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ class MongoDBLoginRepository implements LoginRepository {
async save (startLoginRequestValueObject: StartLoginRequestValueObject): Promise<boolean> {
const collection = this.getMongoDbAuthCollection()
try {

const attempsByIp = Number(process.env.AUTH_LIMIT_ATTEMPTS_PER_IP)
if (attempsByIp !== undefined && Number(attempsByIp) > 0) {
const ipLimitCollection = this.getMongoDbIpLimitCollection()
Expand Down Expand Up @@ -56,7 +55,7 @@ class MongoDBLoginRepository implements LoginRepository {
expirationTime: Date.now() + Number(process.env.AUTH_LIMIT_ATTEMPTS_PER_IP_WAIT_TIME)
})
}

await collection.deleteMany({
email: startLoginRequestValueObject.getEmail()
})
Expand Down

0 comments on commit 1ea113c

Please sign in to comment.