Security architecture upgrade + bug reporting system
Database & Security: - Dual password storage: bcrypt (auth) + pgcrypto AES-256 (recovery) - SUPER_ADMIN master key recovery system (master_keys table) - Row Level Security on customers, leads, opportunities, communications, tasks - SALES_USER: own records only - ADMIN: all records - SUPER_ADMIN: all records (bypasses RLS) - Immutable audit logs (DELETE/UPDATE blocked by triggers) - New audit event types: BUG_CREATED, BUG_UPDATED, BUG_ASSIGNED, BUG_RESOLVED, LOGIN, LOGOUT - Database export logging (database_export_logs table) - Backup logging with pg_dump script (scripts/backup.ps1) - Fixed audit constraint to allow new action types Authentication: - Random JWT secret generated on every dev server start (invalidates all prior sessions after restart) - Session cookie is now session-only (no maxAge) - setSessionContext() for RLS integration Bug Reporting System: - bug_reports table with RLS (insert by all, select/update by admin only) - POST /api/bug-reports (any authenticated user) - GET /api/bug-reports (admin/super_admin only) - PATCH /api/bug-reports/:id (admin/super_admin only) - POST /api/auth/recover (super_admin password recovery) - Audit logging for all bug report actions Other: - Added 'dev' to UserRole type - Bug report modal UI with severity selector - Added bug report button to topbar
This commit is contained in:
@@ -194,6 +194,27 @@ export function mapDbUserToSessionUser(
|
||||
};
|
||||
}
|
||||
|
||||
export async function encryptPassword(password: string): Promise<string> {
|
||||
const result = await query("SELECT encrypt_password($1) AS encrypted", [password]);
|
||||
return result.rows[0]?.encrypted;
|
||||
}
|
||||
|
||||
export async function decryptPassword(encrypted: string): Promise<string | null> {
|
||||
try {
|
||||
const result = await query("SELECT decrypt_password($1) AS decrypted", [encrypted]);
|
||||
return result.rows[0]?.decrypted || null;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export async function setSessionContext(userId: string, ip?: string) {
|
||||
await query("SELECT set_config('app.current_user_id', $1, true)", [userId]);
|
||||
if (ip) {
|
||||
await query("SELECT set_config('app.current_ip', $1, true)", [ip]);
|
||||
}
|
||||
}
|
||||
|
||||
export async function createSession(userId: string, role: string) {
|
||||
const token = await signToken({ userId, role });
|
||||
|
||||
|
||||
Reference in New Issue
Block a user