Davidson CI testing & AI refinement
pauljd/davidson-ci: Davidson CI / quality (push) Successful in 14s
pauljd/davidson-ci: Davidson CI / ai-review (push) Successful in 1m5s

This commit is contained in:
2026-09-11 09:35:31 +01:00
parent af97600709
commit c9d1a42751
2 changed files with 30 additions and 13 deletions
+7 -2
View File
@@ -1,4 +1,7 @@
<?php require_once __DIR__ . '/ticket.php'; ?>
<?php
require_once __DIR__ . '/ticket.php';
$isLoggedIn = isset($_SESSION['user_id']) && isset($_SESSION['username']);
?>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
@@ -9,6 +12,7 @@
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700;800&display=swap" rel="stylesheet">
<link rel="stylesheet" href="/media/output.css?v=<?php echo filemtime(__DIR__ . '/../media/output.css'); ?>">
<script src="https://unpkg.com/lucide@1.41.0/dist/umd/lucide.min.js" integrity="sha384-5hfcTHqJTrDq2YPubIhzTtbnAx6tDcmRrxlfwLEierMHQtmz030891dt1/8VAupY" crossorigin="anonymous"></script>
<?php if ($isLoggedIn): ?>
<script src="https://cdn.paddle.com/paddle/v2/paddle.js"></script>
<script type="text/javascript">
Paddle.Environment.set("sandbox");
@@ -36,8 +40,9 @@
function openCheckout(items){
Paddle.Checkout.open({
items: items,
customData: {user_id: "<?php echo htmlspecialchars(createTicket((int) ($_SESSION['user_id'] ?? 0), 'purchase'), ENT_QUOTES, 'UTF-8'); ?>"}
customData: {user_id: "<?php echo htmlspecialchars(createTicket((int) $_SESSION['user_id'], 'purchase'), ENT_QUOTES, 'UTF-8'); ?>"}
});
}
</script>
<?php endif; ?>
</head>
+23 -11
View File
@@ -30,19 +30,31 @@ if ($tokenIsWellFormed && $_SERVER['REQUEST_METHOD'] === 'POST') {
if (empty($errors)) {
$pdo = getDbConnection();
$userId = consumePasswordResetTicket($pdo, $token);
if ($userId === null) {
$errors['password'] = 'This reset link has already been used or has expired. Please request a new one.';
} else {
$hashedPassword = password_hash($password, PASSWORD_DEFAULT);
// Bumping session_version invalidates every existing session for this user
// (including a stolen one) the next time enforce_session_version() runs.
$stmt = $pdo->prepare('UPDATE users SET password = :password, session_version = session_version + 1 WHERE id = :id');
$stmt->execute(['password' => $hashedPassword, 'id' => $userId]);
// Consuming the ticket and updating the password happen in one transaction so a
// failure between the two can't strand the user: either both take effect, or the
// ticket stays unconsumed and the (still valid) reset link can be used again.
$pdo->beginTransaction();
try {
$userId = consumePasswordResetTicket($pdo, $token);
header('Location: login.php?reset=success');
exit;
if ($userId === null) {
$pdo->rollBack();
$errors['password'] = 'This reset link has already been used or has expired. Please request a new one.';
} else {
$hashedPassword = password_hash($password, PASSWORD_DEFAULT);
// Bumping session_version invalidates every existing session for this user
// (including a stolen one) the next time enforce_session_version() runs.
$stmt = $pdo->prepare('UPDATE users SET password = :password, session_version = session_version + 1 WHERE id = :id');
$stmt->execute(['password' => $hashedPassword, 'id' => $userId]);
$pdo->commit();
header('Location: login.php?reset=success');
exit;
}
} catch (Throwable $e) {
$pdo->rollBack();
throw $e;
}
}
}