174 lines
4.1 KiB
PHP
174 lines
4.1 KiB
PHP
<?php
|
|
// phpcs:ignoreFile
|
|
|
|
/**
|
|
* Authentication helpers for grower accounts.
|
|
*/
|
|
function auth_find_member(string $username): ?array
|
|
{
|
|
global $conn;
|
|
|
|
$sql = 'SELECT username, growerid, password, password_hash, email, phone,
|
|
growername, last_login_at, password_last_changed
|
|
FROM members
|
|
WHERE username = ?
|
|
LIMIT 1';
|
|
|
|
$stmt = $conn->prepare($sql);
|
|
|
|
if ($stmt === false) {
|
|
return null;
|
|
}
|
|
|
|
$stmt->bind_param('s', $username);
|
|
$stmt->execute();
|
|
|
|
$result = $stmt->get_result();
|
|
$member = $result !== false ? $result->fetch_assoc() : null;
|
|
|
|
$stmt->close();
|
|
|
|
return $member ?: null;
|
|
}
|
|
|
|
function auth_verify_password(array $member, string $password): bool
|
|
{
|
|
if (!empty($member['password_hash'])) {
|
|
return password_verify($password, $member['password_hash']);
|
|
}
|
|
|
|
return hash_equals((string) $member['password'], $password);
|
|
}
|
|
|
|
function auth_upgrade_legacy_password(string $username, string $password): void
|
|
{
|
|
global $conn;
|
|
|
|
$hash = password_hash($password, PASSWORD_DEFAULT);
|
|
$sql = 'UPDATE members
|
|
SET password_hash = ?, password_last_changed = NOW()
|
|
WHERE username = ?
|
|
LIMIT 1';
|
|
|
|
$stmt = $conn->prepare($sql);
|
|
|
|
if ($stmt === false) {
|
|
return;
|
|
}
|
|
|
|
$stmt->bind_param('ss', $hash, $username);
|
|
$stmt->execute();
|
|
$stmt->close();
|
|
}
|
|
|
|
function auth_record_login(string $username): void
|
|
{
|
|
global $conn;
|
|
|
|
$sql = 'UPDATE members SET last_login_at = NOW() WHERE username = ? LIMIT 1';
|
|
$stmt = $conn->prepare($sql);
|
|
|
|
if ($stmt === false) {
|
|
return;
|
|
}
|
|
|
|
$stmt->bind_param('s', $username);
|
|
$stmt->execute();
|
|
$stmt->close();
|
|
}
|
|
|
|
function auth_attempt_login(string $username, string $password): ?array
|
|
{
|
|
$member = auth_find_member($username);
|
|
|
|
if ($member === null) {
|
|
return null;
|
|
}
|
|
|
|
if (!auth_verify_password($member, $password)) {
|
|
return null;
|
|
}
|
|
|
|
if (empty($member['password_hash'])) {
|
|
auth_upgrade_legacy_password($username, $password);
|
|
$member = auth_find_member($username) ?: $member;
|
|
}
|
|
|
|
auth_record_login($username);
|
|
|
|
return $member;
|
|
}
|
|
|
|
function auth_update_profile(string $username, ?string $email, ?string $growerName, ?string $phone): bool
|
|
{
|
|
global $conn;
|
|
|
|
$sql = "UPDATE members
|
|
SET email = NULLIF(?, ''), growername = NULLIF(?, ''), phone = NULLIF(?, ''), profile_updated_at = NOW()
|
|
WHERE username = ?
|
|
LIMIT 1";
|
|
|
|
$stmt = $conn->prepare($sql);
|
|
|
|
if ($stmt === false) {
|
|
return false;
|
|
}
|
|
|
|
$stmt->bind_param('ssss', $email, $growerName, $phone, $username);
|
|
$success = $stmt->execute();
|
|
$stmt->close();
|
|
|
|
return (bool) $success;
|
|
}
|
|
|
|
function auth_set_password(string $username, string $password): bool
|
|
{
|
|
global $conn;
|
|
|
|
$hash = password_hash($password, PASSWORD_DEFAULT);
|
|
$sql = 'UPDATE members
|
|
SET password_hash = ?, password = "", password_last_changed = NOW()
|
|
WHERE username = ?
|
|
LIMIT 1';
|
|
|
|
$stmt = $conn->prepare($sql);
|
|
|
|
if ($stmt === false) {
|
|
return false;
|
|
}
|
|
|
|
$stmt->bind_param('ss', $hash, $username);
|
|
$success = $stmt->execute();
|
|
$stmt->close();
|
|
|
|
return (bool) $success;
|
|
}
|
|
|
|
function auth_change_password(string $username, string $currentPassword, string $newPassword, string $confirmPassword): array
|
|
{
|
|
if ($newPassword === '' || $confirmPassword === '') {
|
|
return [false, 'Please enter and confirm the new password.'];
|
|
}
|
|
|
|
if ($newPassword !== $confirmPassword) {
|
|
return [false, 'New password and confirmation do not match.'];
|
|
}
|
|
|
|
if (strlen($newPassword) < 8) {
|
|
return [false, 'New password must be at least 8 characters long.'];
|
|
}
|
|
|
|
$member = auth_find_member($username);
|
|
|
|
if ($member === null || !auth_verify_password($member, $currentPassword)) {
|
|
return [false, 'Current password is incorrect.'];
|
|
}
|
|
|
|
if (!auth_set_password($username, $newPassword)) {
|
|
return [false, 'Unable to update the password. Please try again.'];
|
|
}
|
|
|
|
return [true, 'Password updated successfully.'];
|
|
}
|
|
?>
|