Files

92 lines
3.9 KiB
PHP

<?php
/*
* Reflector Dashboard — web front-end for SvxReflector
* Copyright (C) 2026 SA7AUX (Björn)
* SPDX-License-Identifier: AGPL-3.0-or-later
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version. See the LICENSE file for details.
*/
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 — Reflector Dashboard</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 Reflector Dashboard</a></p>
<?php elseif ($error && ($_SERVER['REQUEST_METHOD'] !== 'POST' || $tid === '' || $token === '')): ?>
<div class="err"><?=he($error)?></div>
<p><a href="/">Back to Reflector Dashboard</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);">
&copy; 2026 SA7AUX. All rights reserved.
</footer>
</body>
</html>