From 4892dff38e29158c691398de560b8e8e9a0b0670 Mon Sep 17 00:00:00 2001 From: Michael Freno Date: Sun, 28 Dec 2025 21:27:28 -0500 Subject: [PATCH] style changes, and password login fix --- src/routes/login/index.tsx | 6 +-- src/server/api/routers/auth.ts | 54 +++++++++++-------- src/server/init-audit-table.ts | 95 ++++++++++++++++++++++++++++++++++ 3 files changed, 130 insertions(+), 25 deletions(-) create mode 100644 src/server/init-audit-table.ts diff --git a/src/routes/login/index.tsx b/src/routes/login/index.tsx index aacf987..2e08e96 100644 --- a/src/routes/login/index.tsx +++ b/src/routes/login/index.tsx @@ -331,12 +331,12 @@ export default function LoginPage() {
-
+
Passwords did not match!
-
+
Email Already Exists!
@@ -347,7 +347,7 @@ export default function LoginPage() { error() !== "duplicate" } > -
{error()}
+
{error()}
diff --git a/src/server/api/routers/auth.ts b/src/server/api/routers/auth.ts index 4844e77..e8bd701 100644 --- a/src/server/api/routers/auth.ts +++ b/src/server/api/routers/auth.ts @@ -851,19 +851,25 @@ export const authRouter = createTRPCRouter({ // Check all conditions after password verification if (!user || !passwordHash || !passwordMatch) { - // Log failed login attempt - const { ipAddress, userAgent } = getAuditContext(ctx.event.nativeEvent); - await logAuditEvent({ - eventType: "auth.login.failed", - eventData: { - email, - method: "password", - reason: "invalid_credentials" - }, - ipAddress, - userAgent, - success: false - }); + // Log failed login attempt (wrap in try-catch to ensure it never blocks auth flow) + try { + const { ipAddress, userAgent } = getAuditContext( + ctx.event.nativeEvent + ); + await logAuditEvent({ + eventType: "auth.login.failed", + eventData: { + email, + method: "password", + reason: "invalid_credentials" + }, + ipAddress, + userAgent, + success: false + }); + } catch (auditError) { + console.error("Audit logging failed:", auditError); + } throw new TRPCError({ code: "UNAUTHORIZED", @@ -911,15 +917,19 @@ export const authRouter = createTRPCRouter({ // Set CSRF token for authenticated session setCSRFToken(ctx.event.nativeEvent); - // Log successful login - await logAuditEvent({ - userId: user.id, - eventType: "auth.login.success", - eventData: { method: "password", rememberMe: rememberMe || false }, - ipAddress: clientIP, - userAgent, - success: true - }); + // Log successful login (wrap in try-catch to ensure it never blocks auth flow) + try { + await logAuditEvent({ + userId: user.id, + eventType: "auth.login.success", + eventData: { method: "password", rememberMe: rememberMe || false }, + ipAddress: clientIP, + userAgent, + success: true + }); + } catch (auditError) { + console.error("Audit logging failed:", auditError); + } return { success: true, message: "success" }; }), diff --git a/src/server/init-audit-table.ts b/src/server/init-audit-table.ts new file mode 100644 index 0000000..9684a64 --- /dev/null +++ b/src/server/init-audit-table.ts @@ -0,0 +1,95 @@ +/** + * Database Initialization for Audit Logging + * Run this script to create the AuditLog table in your database + * + * Usage: bun run src/server/init-audit-table.ts + */ + +import { ConnectionFactory } from "./database"; + +async function initAuditTable() { + console.log("šŸ”§ Initializing AuditLog table..."); + + try { + const conn = ConnectionFactory(); + + // Create AuditLog table + await conn.execute({ + sql: `CREATE TABLE IF NOT EXISTS AuditLog ( + id TEXT PRIMARY KEY, + user_id TEXT, + event_type TEXT NOT NULL, + event_data TEXT, + ip_address TEXT, + user_agent TEXT, + success INTEGER NOT NULL, + created_at TEXT NOT NULL DEFAULT (datetime('now')), + FOREIGN KEY (user_id) REFERENCES User(id) ON DELETE SET NULL + )` + }); + + console.log("āœ… AuditLog table created (or already exists)"); + + // Create indexes for performance + console.log("šŸ”§ Creating indexes..."); + + await conn.execute({ + sql: `CREATE INDEX IF NOT EXISTS idx_audit_user_id ON AuditLog(user_id)` + }); + + await conn.execute({ + sql: `CREATE INDEX IF NOT EXISTS idx_audit_event_type ON AuditLog(event_type)` + }); + + await conn.execute({ + sql: `CREATE INDEX IF NOT EXISTS idx_audit_created_at ON AuditLog(created_at)` + }); + + await conn.execute({ + sql: `CREATE INDEX IF NOT EXISTS idx_audit_ip_address ON AuditLog(ip_address)` + }); + + console.log("āœ… Indexes created"); + + // Verify table exists + const result = await conn.execute({ + sql: `SELECT name FROM sqlite_master WHERE type='table' AND name='AuditLog'` + }); + + if (result.rows.length > 0) { + console.log("āœ… AuditLog table verified - ready for use!"); + + // Check row count + const countResult = await conn.execute({ + sql: `SELECT COUNT(*) as count FROM AuditLog` + }); + + console.log( + `šŸ“Š Current audit log entries: ${countResult.rows[0]?.count || 0}` + ); + } else { + console.error("āŒ AuditLog table was not created properly"); + process.exit(1); + } + + console.log("\nāœ… Audit logging system is ready!"); + console.log("šŸ’” You can now use the audit logging features"); + console.log("šŸ“– See docs/AUDIT_LOGGING.md for usage examples\n"); + } catch (error) { + console.error("āŒ Failed to initialize AuditLog table:"); + console.error(error); + process.exit(1); + } +} + +// Run if executed directly +if (import.meta.main) { + initAuditTable() + .then(() => process.exit(0)) + .catch((error) => { + console.error(error); + process.exit(1); + }); +} + +export { initAuditTable };