new system prototype
This commit is contained in:
@ -1,97 +1,103 @@
|
||||
<?php
|
||||
// /var/www/html/qdb/change_password.php
|
||||
require_once __DIR__ . '/common.php';
|
||||
// /var/www/html/change_password.php
|
||||
require_once __DIR__ . '/db_init.php';
|
||||
header('Content-Type: application/json; charset=UTF-8');
|
||||
|
||||
// dieselben Defaults wie in login.php
|
||||
$USERS_DEFAULT = [
|
||||
'user01' => 'pw1',
|
||||
'user02' => 'pw2',
|
||||
'Tmp_Daniel' => 'dummy4',
|
||||
'Tmp_Johanna' => 'dummy1',
|
||||
'Tmp_Anke' => 'dummy2',
|
||||
'Tmp_Liliana' => 'dummy3',
|
||||
'Amy_tmp' => 'dummy4',
|
||||
'Brigitte_tmp' => 'dummy5',
|
||||
'Extra1_tmp' => 'dummy6',
|
||||
'Extra2_tmp' => 'dummy7',
|
||||
'Danny' => 'pw1',
|
||||
'User1' => 'pw1',
|
||||
'User2' => 'pw2',
|
||||
'User3' => 'pw3',
|
||||
'User4' => 'pw4',
|
||||
'User5' => 'pw5',
|
||||
'User6' => 'pw6',
|
||||
'User7' => 'pw7',
|
||||
'User8' => 'pw8',
|
||||
'User9' => 'pw9',
|
||||
'User10' => 'pw10',
|
||||
'User11' => 'pw11'
|
||||
];
|
||||
|
||||
$STORE_FILE = __DIR__ . '/users.json';
|
||||
|
||||
function load_store($path) {
|
||||
if (!file_exists($path)) return [];
|
||||
$txt = file_get_contents($path);
|
||||
$arr = json_decode($txt, true);
|
||||
return is_array($arr) ? $arr : [];
|
||||
}
|
||||
function save_store($path, $data) {
|
||||
file_put_contents($path, json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
|
||||
}
|
||||
|
||||
$raw = file_get_contents("php://input");
|
||||
$in = json_decode($raw, true) ?: [];
|
||||
$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" => "Felder fehlen"]);
|
||||
echo json_encode(["success" => false, "message" => "Missing fields"]);
|
||||
exit;
|
||||
}
|
||||
if (strlen($newPassword) < 6) {
|
||||
http_response_code(400);
|
||||
echo json_encode(["success" => false, "message" => "Neues Passwort zu kurz (min. 6 Zeichen)."]);
|
||||
echo json_encode(["success" => false, "message" => "New password too short (min 6 characters)."]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$store = load_store($STORE_FILE);
|
||||
|
||||
// Fall A: User hat schon Hash -> altes Passwort gegen Hash prüfen
|
||||
if (array_key_exists($username, $store) && isset($store[$username]['hash'])) {
|
||||
$hash = (string)$store[$username]['hash'];
|
||||
if (!password_verify($oldPassword, $hash)) {
|
||||
http_response_code(401);
|
||||
echo json_encode(["success" => false, "message" => "Altes Passwort falsch."]);
|
||||
exit;
|
||||
}
|
||||
} else {
|
||||
// Fall B: User hat noch keinen Hash -> gegen Default prüfen
|
||||
if (!array_key_exists($username, $USERS_DEFAULT) || $USERS_DEFAULT[$username] !== $oldPassword) {
|
||||
http_response_code(401);
|
||||
echo json_encode(["success" => false, "message" => "Altes Passwort falsch."]);
|
||||
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;
|
||||
}
|
||||
|
||||
// neuen Hash setzen (bcrypt)
|
||||
$store[$username] = [
|
||||
"hash" => password_hash($newPassword, PASSWORD_DEFAULT),
|
||||
"changedAt" => time()
|
||||
];
|
||||
save_store($STORE_FILE, $store);
|
||||
try {
|
||||
[$pdo, $tmpDb, $lockFp] = qdb_open(true);
|
||||
|
||||
// Nach erfolgreichem Wechsel direkt einloggen (Token erstellen)
|
||||
$token = bin2hex(random_bytes(32));
|
||||
token_add($token, 30 * 24 * 60 * 60);
|
||||
$stmt = $pdo->prepare(
|
||||
"SELECT userID, passwordHash, role, entityID FROM users WHERE username = :u"
|
||||
);
|
||||
$stmt->execute([':u' => $username]);
|
||||
$user = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
echo json_encode([
|
||||
"success" => true,
|
||||
"message" => "Passwort geändert.",
|
||||
"token" => $token,
|
||||
"user" => $username
|
||||
]);
|
||||
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"]);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user