Files
nat-as-server/change_password.php
2026-04-15 10:19:42 +02:00

104 lines
3.2 KiB
PHP

<?php
// /var/www/html/change_password.php
require_once __DIR__ . '/db_init.php';
header('Content-Type: application/json; charset=UTF-8');
$raw = file_get_contents("php://input");
$in = json_decode($raw, true) ?: [];
$username = trim($in['username'] ?? '');
$oldPassword = (string)($in['old_password'] ?? '');
$newPassword = (string)($in['new_password'] ?? '');
// Require a Bearer token (temp or normal) so password changes are bound to a session
$bearerToken = get_bearer_token();
if (!$bearerToken) {
http_response_code(401);
echo json_encode(["success" => false, "message" => "Bearer token required"]);
exit;
}
$tokenRec = token_get_record($bearerToken);
if (!$tokenRec) {
http_response_code(403);
echo json_encode(["success" => false, "message" => "Invalid or expired token"]);
exit;
}
if ($username === '' || $oldPassword === '' || $newPassword === '') {
http_response_code(400);
echo json_encode(["success" => false, "message" => "Missing fields"]);
exit;
}
if (strlen($newPassword) < 6) {
http_response_code(400);
echo json_encode(["success" => false, "message" => "New password too short (min 6 characters)."]);
exit;
}
// Verify the token belongs to the user requesting the change
if (($tokenRec['userID'] ?? '') === '') {
http_response_code(403);
echo json_encode(["success" => false, "message" => "Token not associated with a user"]);
exit;
}
try {
[$pdo, $tmpDb, $lockFp] = qdb_open(true);
$stmt = $pdo->prepare(
"SELECT userID, passwordHash, role, entityID FROM users WHERE username = :u"
);
$stmt->execute([':u' => $username]);
$user = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$user) {
qdb_discard($tmpDb, $lockFp);
http_response_code(401);
echo json_encode(["success" => false, "message" => "Invalid credentials."]);
exit;
}
if ($user['userID'] !== $tokenRec['userID']) {
qdb_discard($tmpDb, $lockFp);
http_response_code(403);
echo json_encode(["success" => false, "message" => "Token does not match user"]);
exit;
}
if (!password_verify($oldPassword, $user['passwordHash'])) {
qdb_discard($tmpDb, $lockFp);
http_response_code(401);
echo json_encode(["success" => false, "message" => "Old password incorrect."]);
exit;
}
$newHash = password_hash($newPassword, PASSWORD_DEFAULT);
$upd = $pdo->prepare(
"UPDATE users SET passwordHash = :h, mustChangePassword = 0 WHERE userID = :uid"
);
$upd->execute([':h' => $newHash, ':uid' => $user['userID']]);
$pdo = null;
qdb_save($tmpDb, $lockFp);
$token = bin2hex(random_bytes(32));
token_add($token, 30 * 24 * 60 * 60, [
'role' => $user['role'],
'entityID' => $user['entityID'],
'userID' => $user['userID'],
]);
echo json_encode([
"success" => true,
"message" => "Password changed.",
"token" => $token,
"user" => $username,
"role" => $user['role'],
]);
} catch (Throwable $e) {
if (isset($tmpDb, $lockFp)) qdb_discard($tmpDb, $lockFp);
http_response_code(500);
echo json_encode(["success" => false, "message" => "Server error"]);
}