import useDatabase from '~/composables/useDatabase'; import { schema } from '~/schemas/login'; import { User, UserExtendedData, UserRawData, UserSession, UserSessionRequired } from '~/types/auth'; import type { Database } from "bun:sqlite"; import { ZodError } from 'zod'; import { checkSession, logSession } from '~/server/utils/user'; interface SuccessHandler { success: true; session: UserSession; } interface ErrorHandler { success: false; error: Error | ZodError<{ usernameOrEmail: string; password: string; }>; } type Return = SuccessHandler | ErrorHandler; export default defineEventHandler(async (e): Promise => { try { const session = await getUserSession(e); const db = useDatabase(); const checkedSession = await checkSession(e, session); if(checkedSession !== undefined) return checkedSession; const body = await readValidatedBody(e, schema.safeParse); if (!body.success) { await clearUserSession(e); setResponseStatus(e, 406); return { success: false, error: body.error }; } const hash = await Bun.password.hash(body.data.password); const checkID = db.query(`SELECT id, hash FROM users WHERE (username = ?1 or email = ?1)`); const id = checkID.get(body.data.usernameOrEmail) as { id: number, hash: string }; if(!id || !id.id || !id.hash) { await clearUserSession(e); setResponseStatus(e, 401); return { success: false, error: new ZodError([{ code: 'custom', path: ['username'], message: 'Identifiant inconnu' }]) }; } const valid = await Bun.password.verify(body.data.password, id.hash); if(!valid) { await clearUserSession(e); setResponseStatus(e, 401); return { success: false, error: new ZodError([{ code: 'custom', path: ['password'], message: 'Mot de passe incorrect' }]) }; } const data = await logSession(e, await setUserSession(e, { user: getData(db, id.id) }) as UserSessionRequired); setResponseStatus(e, 201); return { success: true, session: data }; } catch(err: any) { await clearUserSession(e); console.error(err); return { success: false, error: err as Error }; } }); function getData(db: Database, id: number): User { const userQuery = db.query(`SELECT id, username, email, state FROM users WHERE id = ?1`); const user = userQuery.get(id) as UserRawData; const userDataQuery = db.query(`SELECT * FROM users_data WHERE user_id = ?1`); const userData = userDataQuery.get(id) as UserExtendedData; return { ...user, ...userData }; }