test(auth): work on auth login and signup

This commit is contained in:
2025-12-31 15:11:33 -06:00
parent cc3e823a7d
commit b4dbdd6932
4 changed files with 98 additions and 13 deletions

View File

@@ -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,
});
}
});

View File

@@ -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: {

View File

@@ -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(

View File

@@ -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));
// },
},
});