import jwt from "jsonwebtoken"; import {db} from "../../../../database/dbclient.js"; import {users} from "../../../../database/schema/users.js"; import {eq, sql} from "drizzle-orm"; import {checkPassword} from "../utils/checkPassword.js"; import {roleCheck} from "./userRoles/getUserAccess.js"; import {createLog} from "../../logger/logger.js"; import {differenceInDays} from "date-fns"; /** * Authenticate a user and return a JWT. */ const {sign} = jwt; export async function login( username: string, password: string ): Promise<{token: string; user: {user_id: string; username: string}}> { const user = await db.select().from(users).where(eq(users.username, username)); //console.log(user); if (user.length === 0) { throw new Error("Invalid or Missing user"); } // check the password const checkedPass = await checkPassword(password, user[0]?.password); //console.log(checkedPass); if (!checkedPass) { throw new Error("Invalid Password"); } // Create a JWT const secret: string = process.env.JWT_SECRET!; const expiresIn = Number(process.env.JWT_EXPIRES!) || 60; // get the user roles const roles = await roleCheck(user[0].user_id); const userData = { user_id: user[0].user_id, username: user[0].username, email: user[0].email, //roles: roles || null, role: user[0].role || null, // this should be removed onces full migration to v2 is completed prod: btoa(`${username.toLowerCase()}:${password}`), }; // update the user last login try { const lastLog = await db .update(users) .set({lastLogin: sql`NOW()`}) .where(eq(users.user_id, user[0].user_id)) .returning({lastLogin: users.lastLogin}); createLog( "info", "lst", "auth", `Its been ${differenceInDays(lastLog[0]?.lastLogin ?? "", new Date(Date.now()))} days since ${ user[0].username } has logged in` ); //]); } catch (error) { createLog("error", "lst", "auth", "There was an error updating the user last login"); } const token = sign({user: userData}, secret, {expiresIn: expiresIn * 60}); return {token, user: userData}; }