added password reset

This commit is contained in:
tom.hempel
2026-06-01 21:23:33 +02:00
parent 82a1614a58
commit 890232f58f
5 changed files with 432 additions and 21 deletions

View File

@ -170,12 +170,87 @@ case 'POST':
case 'PUT':
case 'PATCH':
$body = read_json_body();
$targetUserID = trim($body['userID'] ?? '');
$newPassword = (string)($body['password'] ?? $body['newPassword'] ?? '');
if ($newPassword !== '') {
if ($targetUserID === '') {
json_error('MISSING_FIELDS', 'userID is required', 400);
}
if ($targetUserID === ($tokenRec['userID'] ?? '')) {
json_error('FORBIDDEN', 'Cannot reset your own password', 400);
}
if (strlen($newPassword) < 6) {
json_error('PASSWORD_TOO_SHORT', 'Password must be at least 6 characters', 400);
}
$mustChange = isset($body['mustChangePassword']) ? (int)(bool)$body['mustChangePassword'] : 1;
try {
[$pdo, $tmpDb, $lockFp] = qdb_open(true);
$row = $pdo->prepare(
"SELECT u.userID, u.username, u.role, u.entityID, c.supervisorID
FROM users u
LEFT JOIN coach c ON c.coachID = u.entityID AND u.role = 'coach'
WHERE u.userID = :uid"
);
$row->execute([':uid' => $targetUserID]);
$target = $row->fetch(PDO::FETCH_ASSOC);
if (!$target) {
qdb_discard($tmpDb, $lockFp);
json_error('NOT_FOUND', 'User not found', 404);
}
$targetRole = $target['role'] ?? '';
if ($callerRole === 'admin') {
if (!in_array($targetRole, ['supervisor', 'coach'], true)) {
qdb_discard($tmpDb, $lockFp);
json_error('FORBIDDEN', 'Admins may only reset passwords for supervisors and coaches', 403);
}
} elseif ($callerRole === 'supervisor') {
if ($targetRole !== 'coach') {
qdb_discard($tmpDb, $lockFp);
json_error('FORBIDDEN', 'Supervisors may only reset passwords for their coaches', 403);
}
$chk = $pdo->prepare(
'SELECT coachID FROM coach WHERE coachID = :cid AND supervisorID = :svid'
);
$chk->execute([':cid' => $target['entityID'], ':svid' => $callerEntityID]);
if (!$chk->fetch()) {
qdb_discard($tmpDb, $lockFp);
json_error('FORBIDDEN', 'Coach is not under your supervision', 403);
}
} else {
qdb_discard($tmpDb, $lockFp);
json_error('FORBIDDEN', 'Not allowed to reset passwords', 403);
}
$hash = password_hash($newPassword, PASSWORD_DEFAULT);
$pdo->prepare(
'UPDATE users SET passwordHash = :h, mustChangePassword = :mcp WHERE userID = :uid'
)->execute([':h' => $hash, ':mcp' => $mustChange, ':uid' => $targetUserID]);
qdb_save($tmpDb, $lockFp);
json_success([
'userID' => $targetUserID,
'username' => $target['username'],
'mustChangePassword' => $mustChange,
]);
} catch (Throwable $e) {
if (isset($tmpDb, $lockFp)) qdb_discard($tmpDb, $lockFp);
error_log($e->getMessage());
json_error('SERVER_ERROR', 'Server error', 500);
}
break;
}
if ($callerRole !== 'admin') {
json_error('FORBIDDEN', 'Only admins can reassign coaches', 403);
}
$body = read_json_body();
$targetUserID = trim($body['userID'] ?? '');
$supervisorID = trim($body['supervisorID'] ?? '');
if ($targetUserID === '' || $supervisorID === '') {