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"; ?>
 |