import { Router } from "express" ; import { compare , hash } from "bcrypt" ; import { createHash } from "crypto" ; import { validate , loginSchema , registerSchema } from "../validation" ; import { db , User } from "../db" ; import { auth , guest } from "../middleware" ; import { SESSION_COOKIE , BCRYPT_SALT_ROUNDS } from "../config" ; import { confirmationEmail } from "./email" ; const router = Router ( ) ; router . post ( "/login" , validate ( loginSchema ) , async ( req , res ) => { const { email , password } = req . body ; const user = db . users . find ( ( user ) => user . email === email ) ; const fakeHash = "$2b$12$tLn0rFkPBoE1WCpdM6MjR.t/h6Wzql1kAd27FecEDtjRYsTFlYlWa" ; const pwdHash = user ?. password || fakeHash ; const pwdMatches = await comparePassword ( password , pwdHash ) ; if ( ! user || ! pwdMatches ) { return res . status ( 401 ) . json ( { message : "Email or password is incorrect" , } ) ; } req . session . userId = user . id ; res . json ( { message : "OK" } ) ; } ) ; router . post ( "/logout" , auth , ( req , res ) => { req . session . destroy ( ( err ) => { if ( err ) throw err ; res . clearCookie ( SESSION_COOKIE ) ; res . json ( { message : "OK" } ) ; } ) ; } ) ; router . post ( "/register" , guest , validate ( registerSchema ) , async ( req , res ) => { const { email , password , name } = req . body ; const userExists = db . users . some ( ( user ) => user . email === email ) ; if ( userExists ) { return res . status ( 400 ) . json ( { message : "Email is already taken" , } ) ; } const user = { id : db . users . length + 1 , email , password : await hashPassword ( password ) , name , verifiedAt : null , } ; db . users . push ( user ) ; req . session . userId = user . id ; const { mailer } = req . app . locals ; await mailer . sendMail ( confirmationEmail ( email , user . id ) ) ; res . status ( 201 ) . json ( { message : "OK" } ) ; } ) ; export const comparePassword = ( plaintextPassword , hash ) => compare ( sha256 ( plaintextPassword ) , hash ) ; export const hashPassword = ( plaintextPassword ) => hash ( sha256 ( plaintextPassword ) , BCRYPT_SALT_ROUNDS ) ; const sha256 = ( plaintext ) => createHash ( "sha256" ) . update ( plaintext ) . digest ( "base64" ) ; export { router as auth } ;