feat: add authentication, user management, and admin features
Added comprehensive authentication and authorization system:
Authentication System:
- Better Auth integration with session management
- Login/logout pages and API routes
- Middleware for route protection
- Auth utilities and client libraries
User Management:
- User list, detail, and invite pages
- User API endpoints (CRUD operations)
- Session management for users
- Profile settings page
Role-Based Access Control:
- Role management pages (list, create, edit)
- Permission system with granular controls
- Role assignment to users
- Role API endpoints
Admin Features:
- Audit log page for tracking system events
- Admin settings page
- Audit service for logging user actions
Additional Features:
- Quotes management pages and components
- SalesBldr API integration
- Email service for notifications
Configuration & Documentation:
- Updated docker-compose.yml
- MCP server configuration (mcp.json)
- CVE-2025-55182 security review documentation
- Standards guide and PRD documents
- Re-enabling authentication documentation
Database Migrations:
- 012: Auth tables (users, sessions, accounts, verifications)
- 013: Role tables (roles, permissions, role_permissions, user_roles)
- 014: Admin settings table
UI Updates:
- Updated dashboard layout
- Enhanced app layout with auth integration
2026-01-31 12:43:14 -05:00
|
|
|
import { Pool } from "pg";
|
|
|
|
|
|
|
|
|
|
const pool = new Pool({
|
|
|
|
|
connectionString: process.env.DATABASE_URL,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Check if any users exist in the database
|
|
|
|
|
*/
|
|
|
|
|
export async function hasUsers(): Promise<boolean> {
|
|
|
|
|
try {
|
|
|
|
|
const result = await pool.query('SELECT COUNT(*) as count FROM "user"');
|
|
|
|
|
return parseInt(result.rows[0].count) > 0;
|
|
|
|
|
} catch (error) {
|
|
|
|
|
// Table might not exist yet
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Create the default super-admin user from environment variables
|
|
|
|
|
*/
|
|
|
|
|
export async function createDefaultAdmin(): Promise<boolean> {
|
|
|
|
|
const email = process.env.DEFAULT_ADMIN_EMAIL;
|
|
|
|
|
const name = process.env.DEFAULT_ADMIN_NAME || "System Administrator";
|
|
|
|
|
|
|
|
|
|
if (!email) {
|
|
|
|
|
console.warn("DEFAULT_ADMIN_EMAIL not set, skipping admin creation");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
// Check if user already exists
|
|
|
|
|
const existing = await pool.query(
|
|
|
|
|
'SELECT id FROM "user" WHERE email = $1',
|
|
|
|
|
[email]
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (existing.rows.length > 0) {
|
|
|
|
|
console.log("Default admin already exists");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Create the admin user
|
|
|
|
|
const id = crypto.randomUUID();
|
|
|
|
|
await pool.query(
|
|
|
|
|
`INSERT INTO "user" (id, name, email, role, email_verified, requires_setup, created_at, updated_at)
|
|
|
|
|
VALUES ($1, $2, $3, 'super-admin', false, true, NOW(), NOW())`,
|
|
|
|
|
[id, name, email]
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
console.log(`Created default admin: ${email}`);
|
|
|
|
|
return true;
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error("Failed to create default admin:", error);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Run bootstrap checks and setup
|
|
|
|
|
*/
|
|
|
|
|
export async function bootstrap(): Promise<void> {
|
|
|
|
|
try {
|
|
|
|
|
const usersExist = await hasUsers();
|
|
|
|
|
|
|
|
|
|
if (!usersExist) {
|
|
|
|
|
console.log("No users found, running initial setup...");
|
|
|
|
|
await createDefaultAdmin();
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error("Bootstrap failed:", error);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Check if a user requires setup (has requires_setup flag)
|
|
|
|
|
*/
|
|
|
|
|
export async function userRequiresSetup(userId: string): Promise<boolean> {
|
|
|
|
|
try {
|
|
|
|
|
const result = await pool.query(
|
|
|
|
|
'SELECT requires_setup FROM "user" WHERE id = $1',
|
|
|
|
|
[userId]
|
|
|
|
|
);
|
|
|
|
|
return result.rows[0]?.requires_setup === true;
|
|
|
|
|
} catch (error) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Clear the requires_setup flag for a user
|
|
|
|
|
*/
|
|
|
|
|
export async function clearSetupFlag(userId: string): Promise<void> {
|
|
|
|
|
try {
|
|
|
|
|
await pool.query(
|
2026-05-10 23:03:36 -04:00
|
|
|
'UPDATE "user" SET requires_setup = false, "updatedAt" = NOW() WHERE id = $1',
|
feat: add authentication, user management, and admin features
Added comprehensive authentication and authorization system:
Authentication System:
- Better Auth integration with session management
- Login/logout pages and API routes
- Middleware for route protection
- Auth utilities and client libraries
User Management:
- User list, detail, and invite pages
- User API endpoints (CRUD operations)
- Session management for users
- Profile settings page
Role-Based Access Control:
- Role management pages (list, create, edit)
- Permission system with granular controls
- Role assignment to users
- Role API endpoints
Admin Features:
- Audit log page for tracking system events
- Admin settings page
- Audit service for logging user actions
Additional Features:
- Quotes management pages and components
- SalesBldr API integration
- Email service for notifications
Configuration & Documentation:
- Updated docker-compose.yml
- MCP server configuration (mcp.json)
- CVE-2025-55182 security review documentation
- Standards guide and PRD documents
- Re-enabling authentication documentation
Database Migrations:
- 012: Auth tables (users, sessions, accounts, verifications)
- 013: Role tables (roles, permissions, role_permissions, user_roles)
- 014: Admin settings table
UI Updates:
- Updated dashboard layout
- Enhanced app layout with auth integration
2026-01-31 12:43:14 -05:00
|
|
|
[userId]
|
|
|
|
|
);
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error("Failed to clear setup flag:", error);
|
|
|
|
|
}
|
|
|
|
|
}
|