import { lucia } from "./auth.js"; import { generateId, Lucia } from "lucia"; import { loginSchema, signUpSchema } from "./schemas.js"; import bcrypt from "bcrypt"; import { Database } from "better-sqlite3"; import { Socket } from "socket.io"; import { getDB } from "./db.js"; var db: Database; db = getDB(); // middleware export const authCookieMiddleware = (async (req: any, res: any, next: any) => { const sessionId = lucia.readSessionCookie(req.headers.cookie ?? ""); if (!sessionId) { res.locals.user = null; res.locals.session = null; return next(); } const { session, user } = await lucia.validateSession(sessionId); if (session && session.fresh) { res.appendHeader("Set-Cookie", lucia.createSessionCookie(session.id).serialize()); } if (!session) { res.appendHeader("Set-Cookie", lucia.createBlankSessionCookie().serialize()); } res.locals.session = session; res.locals.user = user; // console.log(res.locals.session); // console.log(res.locals.user); return next(); }) export const isAuthAPIMiddleware = async (req: any, res: any, next: any) => { const sessionId = lucia.readSessionCookie(req.headers.cookie ?? ""); // console.log(sessionId); if (!sessionId) { return res.status(403).send({ error: "unauthorized" }); } const { session, user } = await lucia.validateSession(sessionId); if (!session) { return res.status(403).send({ error: "unauthorized" }); } return next(); }; export const isAuthSocketMiddleware = async (socket: Socket, next: any) => { const sessionId = lucia.readSessionCookie(socket.handshake.headers.cookie ?? ""); console.log(sessionId); if (!sessionId) return next(new Error("error")); const { session, user } = await lucia.validateSession(sessionId); if (!session) { // return res.end(); return next(new Error("error")); } // add user and session to the socket.data object socket.data.user = user; socket.data.session = session; return next(); }; export const signup_handler = async (req: any, res: any) => { // console.log(req.params); // console.log(req.body); const parsedData = signUpSchema.safeParse(req.body); if (!parsedData.success) { return res.status(403).json({ field_error: parsedData.error.flatten().fieldErrors }); // 403 is for validation error } var data = parsedData.data; // check if password and confirm_password matchs if (data.password != data.confirm_password) { return res.status(403).json({ field_error: { confirm_password: [ "password doesn't match" ] } }); } // check if username is already used var row = db.prepare("select * from users where id=?").get(data.username); if (row) { return res.status(403).json({ field_error: { username: [ "username already used." ] } }) } // save to data se const hashedPassword = await bcrypt.hash(data.password, 10); await db.prepare("insert into users(id,name,password) values(?,?,?)").run( data.username, data.name, hashedPassword ); const session = await lucia.createSession(data.username, {}); const sessionCookie = lucia.createSessionCookie(session.id); res.cookie(sessionCookie.name, sessionCookie.value, sessionCookie.attributes); res.json({ "status": "success", "msg": "user created successfully", }); }; export const login_handler = (async (req: any, res: any) => { // console.log(req.body); const parsedData = loginSchema.safeParse(req.body); if (!parsedData.success) { return res.status(403).json({ "field_error": parsedData.error.flatten().fieldErrors }) } // check if user exists const row: any = db.prepare("select * from users where id=?").get(parsedData.data.username); // console.log(row); if (!row) { return res.status(403).json({ "error": "Incorrect username or password" }) } // check password if (!await bcrypt.compare(parsedData.data.password, row.password)) { return res.status(403).json({ "error": "Incorrect username or password" }) } // save session const session = await lucia.createSession(row.id, {}); const sessionCookie = lucia.createSessionCookie(session.id); // console.log(sessionCookie.attributes); res.cookie(sessionCookie.name, sessionCookie.value, sessionCookie.attributes); res.json({ "status": "success", "msg": "logged in successfully", }); })