diff --git a/backend/src/auth/login.route.ts b/backend/src/auth/login.route.ts index 6c6a5cb..5edfb32 100644 --- a/backend/src/auth/login.route.ts +++ b/backend/src/auth/login.route.ts @@ -8,6 +8,32 @@ import { user } from "../db/schema/auth.schema.js"; import { auth } from "../utils/auth.utils.js"; import { apiReturn } from "../utils/returnHelper.utils.js"; +// interface EmailLoginRequest { +// email: string; +// password: string; +// } + +// interface LoginResponse { +// redirect: boolean; +// token: string; +// user: { +// name: string; +// email: string; +// emailVerified: boolean; +// image: string | null; +// createdAt: string; +// updatedAt: string; +// role: string; +// banned: boolean; +// banReason: string | null; +// banExpires: string | null; +// username: string; +// displayUsername: string; +// lastLogin: string; +// id: string; +// }; +// } + const base = { password: z.string().min(8, "Password must be at least 8 characters"), }; @@ -28,7 +54,7 @@ const signin = z.union([ const r = Router(); r.post("/", async (req, res) => { - let login: unknown = []; + let login: unknown; try { const validated = signin.parse(req.body); if ("email" in validated) { @@ -69,6 +95,19 @@ r.post("/", async (req, res) => { }); } + // make sure we update the lastLogin + // if (login?.user?.id) { + // const updated = await db + // .update(user) + // .set({ lastLogin: sql`NOW()` }) + // .where(eq(user.id, login.user.id)) + // .returning({ lastLogin: user.lastLogin }); + + // const lastLoginTimestamp = updated[0]?.lastLogin; + // console.log("Updated lastLogin:", lastLoginTimestamp); + // } else + // console.warn("User ID unavailable — skipping lastLogin update"); + return apiReturn(res, { success: true, level: "info", //connect.success ? "info" : "error", @@ -108,6 +147,16 @@ r.post("/", async (req, res) => { status: 400, //connect.success ? 200 : 400, }); } + + return apiReturn(res, { + success: false, + level: "error", + module: "routes", + subModule: "auth", + message: "System Error", + data: [err], + status: 400, + }); } }); diff --git a/backend/src/configs/scaler.config.ts b/backend/src/configs/scaler.config.ts index 1e57849..bd0614c 100644 --- a/backend/src/configs/scaler.config.ts +++ b/backend/src/configs/scaler.config.ts @@ -38,6 +38,17 @@ export const openApiBase: OpenAPIV3_1.Document = { scheme: "bearer", bearerFormat: "JWT", }, + ApiKeyAuth: { + type: "apiKey", + description: "API key required for authentication", + name: "api_key", + in: "header", + }, + basicAuth: { + type: "http", + scheme: "basic", + description: "Basic authentication using username and password", + }, }, // schemas: { // Error: { @@ -47,12 +58,24 @@ export const openApiBase: OpenAPIV3_1.Document = { // message: { type: "string" }, // }, // }, - // }, + // },. }, + tags: [ - // { name: "Health", description: "Health check endpoints" }, - // { name: "Printing", description: "Label printing operations" }, - // { name: "Silo", description: "Silo management" }, + { + name: "Auth", + description: + "Authentication section where you get and create users and api keys", + }, + { + name: "System", + description: "All system endpoints that will be available to run", + }, + { + name: "Datamart", + description: + "All Special queries to run based on there names.\n Refer to the docs to see all possible queries that can be ran here, you can also run the getQueries to see available.", + }, // { name: "TMS", description: "TMS integration" }, ], paths: {}, // Will be populated @@ -96,6 +119,7 @@ export const setupApiDocsRoutes = (baseUrl: string, app: Express) => { targetKey: "node", clientKey: "axios", }, + documentDownloadType: "json", hideClientButton: true, hiddenClients: { diff --git a/backend/src/db/schema/auth.schema.ts b/backend/src/db/schema/auth.schema.ts index 4c67171..9210462 100644 --- a/backend/src/db/schema/auth.schema.ts +++ b/backend/src/db/schema/auth.schema.ts @@ -25,7 +25,6 @@ export const user = pgTable("user", { banExpires: timestamp("ban_expires"), username: text("username").unique(), displayUsername: text("display_username"), - lastLogin: timestamp("last_login").defaultNow(), }); export const session = pgTable( diff --git a/backend/src/utils/auth.utils.ts b/backend/src/utils/auth.utils.ts index c445ce2..3606af6 100644 --- a/backend/src/utils/auth.utils.ts +++ b/backend/src/utils/auth.utils.ts @@ -3,8 +3,10 @@ import { drizzleAdapter } from "better-auth/adapters/drizzle"; import { admin, apiKey, + createAuthMiddleware, customSession, jwt, + lastLoginMethod, username, } from "better-auth/plugins"; import { eq } from "drizzle-orm"; @@ -38,7 +40,7 @@ export const auth = betterAuth({ }, lastLogin: { type: "date", - required: false, + required: true, input: false, }, }, @@ -47,6 +49,7 @@ export const auth = betterAuth({ jwt({ jwt: { expirationTime: "1h" } }), apiKey(), admin(), + lastLoginMethod(), username({ minUsernameLength: 5, usernameValidator: (username) => { @@ -119,12 +122,22 @@ export const auth = betterAuth({ secure: false, httpOnly: true, }, + hooks: { + after: createAuthMiddleware(async (ctx) => { + if (ctx.path.startsWith("/login")) { + const newSession = ctx.context.newSession; + if (newSession) { + // something here later + } + } + }), + }, events: { - async onSignInSuccess({ user }: { user: User }) { - await db - .update(rawSchema.user) - .set({ lastLogin: new Date() }) - .where(eq(schema.user.id, user.id)); - }, + // async onSignInSuccess({ user }: { user: User }) { + // await db + // .update(rawSchema.user) + // .set({ lastLogin: new Date() }) + // .where(eq(schema.user.id, user.id)); + // }, }, });