182 lines
5.9 KiB
PHP
182 lines
5.9 KiB
PHP
<?php
|
|
|
|
if (LOGGED_IN) {
|
|
// http_response_code(303);
|
|
// header("Location: /");
|
|
// die();
|
|
}
|
|
|
|
$title = "Reset Password";
|
|
$description = "Request a password reset email.";
|
|
|
|
if (isset($_GET["hash"])) {
|
|
$stmt = $db["data"]->prepare(
|
|
"SELECT member_id FROM password_resets WHERE hash = :hash"
|
|
);
|
|
$stmt->execute([
|
|
"hash" => $_GET["hash"] ?? null,
|
|
]);
|
|
|
|
$is_valid_hash = $stmt->fetch(PDO::FETCH_COLUMN) ? true : false;
|
|
|
|
if (!$is_valid_hash) {
|
|
$_SESSION["alert_message"] =
|
|
"This password reset link is expired or invalid.";
|
|
}
|
|
}
|
|
|
|
if ($_SERVER["REQUEST_METHOD"] === "POST"):
|
|
define(
|
|
"IS_RESET_REQUEST",
|
|
$_SERVER["REQUEST_METHOD"] === "POST" && isset($_POST["email"])
|
|
);
|
|
define(
|
|
"IS_NEW_PASSWORD",
|
|
$_SERVER["REQUEST_METHOD"] === "POST" && isset($_POST["new-password"])
|
|
);
|
|
|
|
$errors = [];
|
|
|
|
if (IS_NEW_PASSWORD) {
|
|
if (mb_strlen(trim($_POST["new-password"])) === 0) {
|
|
$errors["new-password"] = "You can't have an empty password.";
|
|
}
|
|
|
|
if ($_POST["new-password"] !== $_POST["new-password-confirm"]) {
|
|
$errors["new-password"] =
|
|
"The newly-entered passwords do not match.";
|
|
}
|
|
|
|
if (count($errors) === 0) {
|
|
// get id from has lookup
|
|
$stmt = $db["data"]->prepare(
|
|
"SELECT member_id FROM password_resets WHERE hash = :hash"
|
|
);
|
|
$stmt->execute([
|
|
"hash" => $_POST["hash"],
|
|
]);
|
|
|
|
$member_id = $stmt->fetch(PDO::FETCH_COLUMN);
|
|
|
|
// update password
|
|
$stmt = $db["data"]->prepare(
|
|
"UPDATE members SET password = :password WHERE id = :id;"
|
|
);
|
|
|
|
$stmt->execute([
|
|
"id" => $member_id,
|
|
"password" => password_hash(
|
|
$_POST["new-password"],
|
|
PASSWORD_ARGON2ID
|
|
),
|
|
]);
|
|
|
|
$stmt = $db["data"]->prepare(
|
|
"DELETE FROM password_resets WHERE hash = :hash;"
|
|
);
|
|
|
|
$stmt->execute([
|
|
"hash" => $_POST["hash"],
|
|
]);
|
|
|
|
$_SESSION["alert_message"] =
|
|
"Your password has been successfully reset.";
|
|
|
|
http_response_code(303);
|
|
header("Location: /login");
|
|
die();
|
|
}
|
|
}
|
|
|
|
if (IS_RESET_REQUEST) {
|
|
if (mb_strlen(trim($_POST["email"])) === 0) {
|
|
$errors["email"] = "Please enter an email address.";
|
|
} else {
|
|
$stmt = $db["data"]->prepare(
|
|
"SELECT id FROM members WHERE LOWER(email) = LOWER(:email)"
|
|
);
|
|
$stmt->execute([
|
|
"email" => $_POST["email"],
|
|
]);
|
|
$member_id = $stmt->fetch(PDO::FETCH_COLUMN);
|
|
|
|
if ($member_id) {
|
|
$stmt = $db["data"]->prepare(
|
|
"INSERT OR REPLACE INTO password_resets (hash, member_id) VALUES (:hash, :member_id)"
|
|
);
|
|
$stmt->execute([
|
|
"hash" => bin2hex(random_bytes(32)),
|
|
"member_id" => $member_id,
|
|
]);
|
|
|
|
// send password reset
|
|
|
|
// $_SESSION["alert_message"] =
|
|
// "A password reset email will be sent if an account with the provided email exists.";
|
|
http_response_code(303);
|
|
header("Location: /forgot-password");
|
|
die();
|
|
}
|
|
}
|
|
}
|
|
endif;
|
|
|
|
include "partials/head.php";
|
|
?>
|
|
<body>
|
|
<?php include "partials/header.php"; ?>
|
|
<main id="main" class="flow">
|
|
<header>
|
|
<h1><?= $title ?></h1>
|
|
</header>
|
|
<?php if (isset($_SESSION["alert_message"])) { ?>
|
|
<aside class="alert">
|
|
<p><?= $_SESSION["alert_message"] ?></p>
|
|
<?php unset($_SESSION["alert_message"]); ?>
|
|
</aside>
|
|
<?php } ?>
|
|
<form action="<?= $_SERVER[
|
|
"REQUEST_URI"
|
|
] ?>" method="post" class="flow">
|
|
<?php if (isset($is_valid_hash) && $is_valid_hash): ?>
|
|
<?php if (
|
|
isset($errors) &&
|
|
isset($errors["new-password"])
|
|
) { ?><p><mark><?= $errors[
|
|
"new-password"
|
|
] ?></mark></p><?php } ?>
|
|
<label>
|
|
<span>New password</span>
|
|
<input type="password" name="new-password" value='<?= $_POST[
|
|
"new-password"
|
|
] ?? "" ?>'/>
|
|
</label>
|
|
<label>
|
|
<span>Confirm new password</span>
|
|
<input type="password" name="new-password-confirm" value='<?= $_POST[
|
|
"new-password-confirm"
|
|
] ?? "" ?>'/>
|
|
</label>
|
|
<input type='hidden' name='hash' value='<?= $_GET[
|
|
"hash"
|
|
] ?>'/>
|
|
<button type="submit">Reset password</button>
|
|
<?php else: ?>
|
|
<aside class="alert">
|
|
<p><b>This form doesn't work yet.</b> Please mail <code>sixfold [at] sixfold.org</code> to request a reset link.</p>
|
|
</aside>
|
|
<label>
|
|
<span>Email address <small>(email@example.com)</small></span>
|
|
<?php if (
|
|
isset($errors) &&
|
|
isset($errors["email"])
|
|
) { ?><span><mark><?= $errors[
|
|
"email"
|
|
] ?></mark></span><?php } ?>
|
|
<input type="email" name="email"/>
|
|
</label>
|
|
<button type="submit">Send reset email</button>
|
|
<?php endif; ?>
|
|
</form>
|
|
</main>
|
|
<?php include "partials/footer.php"; ?>
|