Public web-only release: SvxPortal front-end + auth backend, install templates and INSTALL.md
Stripped from the internal repo: per-box deploy trees, Go services (nodelist/astmeta/proxy/svxdr), deploy/sync scripts and all secrets. Config templates for nginx, PHP-FPM, Redis and tmpfiles live in install/ with CHANGEME placeholders. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
require __DIR__ . '/lib.php';
|
||||
|
||||
$tid = trim((string)($_GET['tid'] ?? ''));
|
||||
$token = trim((string)($_GET['token'] ?? ''));
|
||||
$error = '';
|
||||
$done = false;
|
||||
|
||||
if ($tid === '' || $token === '') {
|
||||
$error = 'Invalid or missing reset link.';
|
||||
} else {
|
||||
$k = rkey("token:reset:$tid");
|
||||
$h = redis()->hGetAll($k);
|
||||
if (!is_array($h) || empty($h['uid']) || empty($h['hash'])) {
|
||||
$error = 'Reset link has expired or is invalid.';
|
||||
} elseif (!hash_equals((string)$h['hash'], token_hash($token))) {
|
||||
$error = 'Invalid reset token.';
|
||||
} elseif ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$pass1 = (string)($_POST['password'] ?? '');
|
||||
$pass2 = (string)($_POST['password2'] ?? '');
|
||||
if ($pass1 === '' || strlen($pass1) < 6) {
|
||||
$error = 'Password must be at least 6 characters.';
|
||||
} elseif ($pass1 !== $pass2) {
|
||||
$error = 'Passwords do not match.';
|
||||
} else {
|
||||
$uid = (string)$h['uid'];
|
||||
redis()->hSet(acct_key($uid), 'password_hash', password_hash($pass1, PASSWORD_DEFAULT));
|
||||
redis()->del($k);
|
||||
$done = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function he(string $s): string { return htmlspecialchars($s, ENT_QUOTES, 'UTF-8'); }
|
||||
?>
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<title>Reset Password — SvxPortal</title>
|
||||
<style>
|
||||
:root{ color-scheme:dark; --bg:#000; --fg:#00ffff; --fg2:rgba(0,255,255,.75); --line:rgba(0,255,255,.35); }
|
||||
html, body{ height:100%; background:var(--bg); color:var(--fg); margin:0; font-family:system-ui,sans-serif; }
|
||||
.box{ max-width:400px; margin:60px auto; padding:24px; border:1px solid var(--line); border-radius:10px; }
|
||||
input{ background:var(--bg); color:var(--fg); border:1px solid rgba(0,255,255,.5); border-radius:4px; padding:6px 10px; width:100%; margin-bottom:10px; box-sizing:border-box; }
|
||||
input:focus{ outline:none; box-shadow:0 0 0 2px rgba(0,255,255,.25); }
|
||||
button{ background:rgba(0,255,255,.15); color:var(--fg); border:1px solid rgba(0,255,255,.7); border-radius:4px; padding:6px 16px; cursor:pointer; }
|
||||
button:hover{ background:rgba(0,255,255,.25); }
|
||||
.err{ color:#ff8080; font-size:.9rem; margin-bottom:10px; }
|
||||
.ok{ color:#00ff80; font-size:.9rem; }
|
||||
a{ color:var(--fg); }
|
||||
label{ display:block; font-size:.85rem; color:var(--fg2); margin-bottom:4px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="box">
|
||||
<h3 style="margin-top:0;">Reset Password</h3>
|
||||
<?php if ($done): ?>
|
||||
<div class="ok">Password changed successfully!</div>
|
||||
<p><a href="/">Back to SvxPortal</a></p>
|
||||
<?php elseif ($error && ($_SERVER['REQUEST_METHOD'] !== 'POST' || $tid === '' || $token === '')): ?>
|
||||
<div class="err"><?=he($error)?></div>
|
||||
<p><a href="/">Back to SvxPortal</a></p>
|
||||
<?php else: ?>
|
||||
<?php if ($error): ?><div class="err"><?=he($error)?></div><?php endif; ?>
|
||||
<form method="post">
|
||||
<label>New password</label>
|
||||
<input type="password" name="password" autocomplete="new-password" required minlength="6">
|
||||
<label>Confirm password</label>
|
||||
<input type="password" name="password2" autocomplete="new-password" required>
|
||||
<button type="submit">Set New Password</button>
|
||||
</form>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<footer style="text-align:center; padding:16px; color:rgba(0,255,255,.4); font-size:.75rem; border-top:1px solid rgba(0,255,255,.15);">
|
||||
© 2026 SA7AUX. All rights reserved.
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user