diff --git a/README.md b/README.md new file mode 100644 index 0000000000000000000000000000000000000000..a4540c105df278023b8a7f6eb43774d5170bcac6 --- /dev/null +++ b/README.md @@ -0,0 +1,30 @@ +# Auth Service + +# Endpoints + +##Â Login + +``` +/auth/login +``` + +Request format: + +```json +{ + "email": "joebloggs@gmail.com", + "password": "password123" +} +``` + +Responses: + +## Register + +``` +/auth/register +``` + +# JWT Validation + +How to validate the JWT and extract the user informtion from it diff --git a/src/login.ts b/src/login.ts index a0885d3f7b34a9126e243777714250aee0bc7c6d..983bc9a6feed39457db34d48cf3acbbc5487c9c6 100644 --- a/src/login.ts +++ b/src/login.ts @@ -1,10 +1,8 @@ import { Request, Response } from "express"; import Joi from "joi"; -import { TokenService } from "./token_service"; +import { ITokenPayload, TokenService } from "./token_service"; + -interface ILoginResponse { - token: string; -} interface ILoginRequest { email: string; @@ -16,7 +14,7 @@ export class LoginHandler { } public async handle(req: Request, res: Response): Promise<Response> { - console.log(req.body); + const schema = Joi.object({ email: Joi.string().email().required(), password: Joi.string().min(8).required() @@ -46,8 +44,11 @@ export class LoginHandler { } } - private async login(req: ILoginRequest ): Promise<ILoginResponse | null>{ + public async login(req: ILoginRequest ): Promise<ITokenPayload | null>{ + // fetch from the database the following user object and if the user exists and the password hash matches the password hash in the database + // then return the token + // otherwise return null const user : IUser = { id: `id-${req.email}`, email: req.email, diff --git a/src/register.ts b/src/register.ts new file mode 100644 index 0000000000000000000000000000000000000000..f111d8a9b518b81fc7b46355dd8fa02e6b599c37 --- /dev/null +++ b/src/register.ts @@ -0,0 +1,63 @@ +import Joi from "joi"; +import { Request, Response } from "express"; +import { ITokenPayload, TokenService } from "./token_service"; + +interface IRegistrationRequest { + email: string; + password: string; + fullName: string; +} + +export class RegistrationHandler { + + + constructor(private tokenService: TokenService){} + + public async handle(req: Request, res: Response): Promise<Response> { + const schema = Joi.object({ + email: Joi.string().email().required(), + password: Joi.string().min(8).required(), + fullName: Joi.string().required() + }) + + try { + const {value, error } = schema.validate(req.body); + + if(error) { + console.log('validation error: ', error.message); + return res.status(400).send({message: error!.message}); + } + + const {email, password, fullName} = value; + + const responseBody = await this.register({email, password, fullName}); + + if(!responseBody) { + return res.status(403).send({message: 'There already exists a user with that email address'}); + } + + return res.status(200).send(responseBody); + } + catch (err) { + console.log('Error: ', err); + return res.status(500).send(err); + } + } + + public async register(req: IRegistrationRequest ): Promise<ITokenPayload| null>{ + + // Check that there isn't already a user in the database with the same email address + // If there is then return null + // Otherwise create a new user in the database and return the token + + const user : IUser = { + id: `id-${req.email}`, + email: req.email, + password: req.password, + fullName: req.fullName, + } + + const token = await this.tokenService.generateToken(user); + return token; + } +} \ No newline at end of file