mirror of
https://github.com/myronblair/novacpx
synced 2026-06-30 17:50:41 -05:00
6fdccc6dbd
#9 auth.php: add self-service change-password action (current+new+confirm) accounts.php: fix admin change-password — accept account_id, fetch username for chpasswd (was using int ID), add Auth::require('admin') guard user.js: add Change Password page + navItem + submitChangePassword() #10 EmailManager: store AES-256-CBC enc_password alongside SHA512-CRYPT hash webmail.php: rewrite login-url to use webmail_sso_tokens table novacpx-sso.php: Roundcube SSO bridge (validate token, decrypt, autosubmit) Migration 005: add enc_password column + webmail_sso_tokens table #11 opendkim: installed, configured (/etc/opendkim.conf, signing.table, key.table, trusted.hosts), socket at /var/spool/postfix/opendkim/, Postfix milter wired, service enabled+running, key generation verified #12 files.php: fix safe_path() for non-existent paths (write/mkdir), add safe_path_new() helper using parent-dir realpath check, fix delete guard (block deleting account root dirs), fix rename destination, clamp chmod to 0777 #13 nova.js: api() handles network errors, 429 rate-limit with retry-after, non-JSON responses (PHP fatal pages) — graceful error instead of throw admin/user/reseller index.php: filemtime-based cache-busting on all assets Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
40 lines
2.7 KiB
PHP
40 lines
2.7 KiB
PHP
<?php http_response_code(404); ?>
|
|
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1">
|
|
<title>404 — Page Not Found · NovaCPX</title>
|
|
<style>
|
|
:root{--bg:#0d0f17;--bg2:#131520;--border:#252840;--text:#e2e4f0;--text-muted:#7c7f9a;--primary:#6366f1;--red:#ef4444}
|
|
*{box-sizing:border-box;margin:0;padding:0}
|
|
body{background:var(--bg);color:var(--text);font-family:'Inter',system-ui,sans-serif;min-height:100vh;display:flex;align-items:center;justify-content:center;
|
|
background-image:radial-gradient(ellipse at 30% 20%,rgba(99,102,241,.12) 0%,transparent 60%),radial-gradient(ellipse at 80% 80%,rgba(239,68,68,.07) 0%,transparent 60%)}
|
|
.wrap{text-align:center;padding:2rem;max-width:480px}
|
|
.code{font-size:7rem;font-weight:900;line-height:1;background:linear-gradient(135deg,var(--primary),#0ea5e9);-webkit-background-clip:text;-webkit-text-fill-color:transparent;margin-bottom:.5rem}
|
|
h1{font-size:1.5rem;font-weight:600;margin-bottom:.75rem}
|
|
p{color:var(--text-muted);margin-bottom:2rem;line-height:1.6}
|
|
.btn{display:inline-flex;align-items:center;gap:.5rem;padding:.65rem 1.5rem;background:var(--primary);color:#fff;border-radius:10px;text-decoration:none;font-weight:500;font-size:.9rem}
|
|
.btn:hover{opacity:.85}
|
|
.logo{display:flex;align-items:center;justify-content:center;gap:.5rem;margin-bottom:2.5rem;opacity:.6}
|
|
.logo svg{width:28px;height:28px}
|
|
.logo-text{font-size:1.1rem;font-weight:300}
|
|
.logo-text strong{font-weight:700;background:linear-gradient(135deg,#6366f1,#0ea5e9);-webkit-background-clip:text;-webkit-text-fill-color:transparent}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="wrap">
|
|
<div class="logo">
|
|
<svg viewBox="0 0 40 40" fill="none"><circle cx="20" cy="20" r="18" stroke="url(#g1)" stroke-width="2"/><path d="M12 28L20 8l8 20" stroke="url(#g2)" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/><path d="M14 22h12" stroke="url(#g2)" stroke-width="2" stroke-linecap="round"/><defs><linearGradient id="g1" x1="2" y1="2" x2="38" y2="38"><stop stop-color="#6366f1"/><stop offset="1" stop-color="#0ea5e9"/></linearGradient><linearGradient id="g2" x1="12" y1="8" x2="28" y2="28"><stop stop-color="#6366f1"/><stop offset="1" stop-color="#0ea5e9"/></linearGradient></defs></svg>
|
|
<div class="logo-text">Nova<strong>CPX</strong></div>
|
|
</div>
|
|
<div class="code">404</div>
|
|
<h1>Page Not Found</h1>
|
|
<p>The page you're looking for doesn't exist or has been moved.</p>
|
|
<a href="javascript:history.back()" class="btn">
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="16" height="16"><path d="M19 12H5M12 5l-7 7 7 7"/></svg>
|
|
Go Back
|
|
</a>
|
|
</div>
|
|
</body>
|
|
</html>
|