refactor: odstraneni PSR-1 SideEffects warningu
- Handler funkce extrahovany z API souboru do api/admin/handlers/ - config.php rozdeleny na helpers.php (funkce) a constants.php (konstanty) - require_once odstranen z class souboru (AuditLog, JWTAuth, LeaveNotification) - vendor/autoload.php presunuto do config.php bootstrap - totp-handlers.php: pridany use deklarace pro TwoFactorAuth - phpstan.neon: bootstrapFiles, scanDirectories, dynamicConstantNames - Opraveny chybejici routing bloky v totp.php a session.php Vysledek: phpcs 0 errors 0 warnings, PHPStan 0 errors, ESLint 0 errors Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -14,6 +14,7 @@ declare(strict_types=1);
|
||||
require_once dirname(__DIR__) . '/config.php';
|
||||
require_once dirname(__DIR__) . '/includes/JWTAuth.php';
|
||||
require_once dirname(__DIR__) . '/includes/AuditLog.php';
|
||||
require_once __DIR__ . '/handlers/users-handlers.php';
|
||||
|
||||
// Set headers
|
||||
setCorsHeaders();
|
||||
@@ -70,273 +71,3 @@ try {
|
||||
errorResponse('Chyba databáze', 500);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* GET - List all users
|
||||
*/
|
||||
function handleGetUser(PDO $pdo): void
|
||||
{
|
||||
$stmt = $pdo->query('
|
||||
SELECT
|
||||
u.id,
|
||||
u.username,
|
||||
u.email,
|
||||
u.first_name,
|
||||
u.last_name,
|
||||
u.role_id,
|
||||
u.is_active,
|
||||
u.last_login,
|
||||
u.created_at,
|
||||
r.name as role_name,
|
||||
r.display_name as role_display_name
|
||||
FROM users u
|
||||
LEFT JOIN roles r ON u.role_id = r.id
|
||||
ORDER BY u.created_at DESC
|
||||
');
|
||||
$users = $stmt->fetchAll();
|
||||
|
||||
// Get roles for dropdown
|
||||
$stmt = $pdo->query('SELECT id, name, display_name FROM roles ORDER BY id');
|
||||
$roles = $stmt->fetchAll();
|
||||
|
||||
successResponse([
|
||||
'users' => $users,
|
||||
'roles' => $roles,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* POST - Create new user
|
||||
*
|
||||
* @param array<string, mixed> $authData
|
||||
*/
|
||||
function handleCreateUser(PDO $pdo, array $authData): void
|
||||
{
|
||||
$input = getJsonInput();
|
||||
|
||||
// Validate required fields
|
||||
$requiredFields = [
|
||||
'username' => 'Uživatelské jméno',
|
||||
'email' => 'E-mail',
|
||||
'password' => 'Heslo',
|
||||
'first_name' => 'Jméno',
|
||||
'last_name' => 'Příjmení',
|
||||
'role_id' => 'Role',
|
||||
];
|
||||
foreach ($requiredFields as $field => $label) {
|
||||
if (empty($input[$field])) {
|
||||
errorResponse("$label je povinné");
|
||||
}
|
||||
}
|
||||
|
||||
$username = sanitize($input['username']);
|
||||
$email = sanitize($input['email']);
|
||||
$password = $input['password'];
|
||||
$firstName = sanitize($input['first_name']);
|
||||
$lastName = sanitize($input['last_name']);
|
||||
$roleId = (int) $input['role_id'];
|
||||
$isActive = isset($input['is_active']) ? ($input['is_active'] ? 1 : 0) : 1;
|
||||
|
||||
// Non-admin nesmí přiřadit admin roli
|
||||
if (!($authData['user']['is_admin'] ?? false)) {
|
||||
$stmt = $pdo->prepare('SELECT name FROM roles WHERE id = ?');
|
||||
$stmt->execute([$roleId]);
|
||||
$targetRole = $stmt->fetch();
|
||||
if ($targetRole && $targetRole['name'] === 'admin') {
|
||||
errorResponse('Nemáte oprávnění přiřadit roli administrátora', 403);
|
||||
}
|
||||
}
|
||||
|
||||
// Validate email format
|
||||
if (!isValidEmail($email)) {
|
||||
errorResponse('Neplatný formát e-mailu');
|
||||
}
|
||||
|
||||
// Validate password length
|
||||
if (strlen($password) < 8) {
|
||||
errorResponse('Heslo musí mít alespoň 8 znaků');
|
||||
}
|
||||
|
||||
// Check username uniqueness
|
||||
$stmt = $pdo->prepare('SELECT id FROM users WHERE username = ?');
|
||||
$stmt->execute([$username]);
|
||||
if ($stmt->fetch()) {
|
||||
errorResponse('Uživatelské jméno již existuje');
|
||||
}
|
||||
|
||||
// Check email uniqueness
|
||||
$stmt = $pdo->prepare('SELECT id FROM users WHERE email = ?');
|
||||
$stmt->execute([$email]);
|
||||
if ($stmt->fetch()) {
|
||||
errorResponse('E-mail již existuje');
|
||||
}
|
||||
|
||||
// Validate role exists
|
||||
$stmt = $pdo->prepare('SELECT id FROM roles WHERE id = ?');
|
||||
$stmt->execute([$roleId]);
|
||||
if (!$stmt->fetch()) {
|
||||
errorResponse('Neplatná role');
|
||||
}
|
||||
|
||||
// Hash password
|
||||
$passwordHash = password_hash($password, PASSWORD_BCRYPT, ['cost' => BCRYPT_COST]);
|
||||
|
||||
// Insert user
|
||||
$stmt = $pdo->prepare('
|
||||
INSERT INTO users (username, email, password_hash, first_name, last_name, role_id, is_active)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?)
|
||||
');
|
||||
$stmt->execute([$username, $email, $passwordHash, $firstName, $lastName, $roleId, $isActive]);
|
||||
|
||||
$newUserId = (int)$pdo->lastInsertId();
|
||||
|
||||
// Audit log
|
||||
AuditLog::logCreate('user', $newUserId, [
|
||||
'username' => $username,
|
||||
'email' => $email,
|
||||
'first_name' => $firstName,
|
||||
'last_name' => $lastName,
|
||||
'role_id' => $roleId,
|
||||
'is_active' => $isActive,
|
||||
], "Vytvořen uživatel '$username'");
|
||||
|
||||
successResponse(['id' => $newUserId], 'Uživatel byl úspěšně vytvořen');
|
||||
}
|
||||
|
||||
/**
|
||||
* PUT - Update user
|
||||
*
|
||||
* @param array<string, mixed> $authData
|
||||
*/
|
||||
function handleUpdateUser(PDO $pdo, int $userId, int $currentUserId, array $authData): void
|
||||
{
|
||||
// Get existing user
|
||||
$stmt = $pdo->prepare('SELECT * FROM users WHERE id = ?');
|
||||
$stmt->execute([$userId]);
|
||||
$existingUser = $stmt->fetch();
|
||||
|
||||
if (!$existingUser) {
|
||||
errorResponse('Uživatel nebyl nalezen', 404);
|
||||
}
|
||||
|
||||
$input = getJsonInput();
|
||||
|
||||
$username = isset($input['username']) ? sanitize($input['username']) : $existingUser['username'];
|
||||
$email = isset($input['email']) ? sanitize($input['email']) : $existingUser['email'];
|
||||
$firstName = isset($input['first_name']) ? sanitize($input['first_name']) : $existingUser['first_name'];
|
||||
$lastName = isset($input['last_name']) ? sanitize($input['last_name']) : $existingUser['last_name'];
|
||||
$roleId = isset($input['role_id']) ? (int) $input['role_id'] : $existingUser['role_id'];
|
||||
$isActive = isset($input['is_active']) ? ($input['is_active'] ? 1 : 0) : $existingUser['is_active'];
|
||||
|
||||
// Validate email format
|
||||
if (!isValidEmail($email)) {
|
||||
errorResponse('Neplatný formát e-mailu');
|
||||
}
|
||||
|
||||
// Check username uniqueness (excluding current user)
|
||||
$stmt = $pdo->prepare('SELECT id FROM users WHERE username = ? AND id != ?');
|
||||
$stmt->execute([$username, $userId]);
|
||||
if ($stmt->fetch()) {
|
||||
errorResponse('Uživatelské jméno již existuje');
|
||||
}
|
||||
|
||||
// Check email uniqueness (excluding current user)
|
||||
$stmt = $pdo->prepare('SELECT id FROM users WHERE email = ? AND id != ?');
|
||||
$stmt->execute([$email, $userId]);
|
||||
if ($stmt->fetch()) {
|
||||
errorResponse('E-mail již existuje');
|
||||
}
|
||||
|
||||
// Validate role exists
|
||||
$stmt = $pdo->prepare('SELECT id, name FROM roles WHERE id = ?');
|
||||
$stmt->execute([$roleId]);
|
||||
$targetRole = $stmt->fetch();
|
||||
if (!$targetRole) {
|
||||
errorResponse('Neplatná role');
|
||||
}
|
||||
|
||||
// Non-admin nesmí přiřadit admin roli
|
||||
if (!($authData['user']['is_admin'] ?? false) && $targetRole['name'] === 'admin') {
|
||||
errorResponse('Nemáte oprávnění přiřadit roli administrátora', 403);
|
||||
}
|
||||
|
||||
// Update user
|
||||
if (!empty($input['password'])) {
|
||||
// Validate password length
|
||||
if (strlen($input['password']) < 8) {
|
||||
errorResponse('Heslo musí mít alespoň 8 znaků');
|
||||
}
|
||||
|
||||
$passwordHash = password_hash($input['password'], PASSWORD_BCRYPT, ['cost' => BCRYPT_COST]);
|
||||
|
||||
$stmt = $pdo->prepare('
|
||||
UPDATE users
|
||||
SET username = ?, email = ?, password_hash = ?,
|
||||
first_name = ?, last_name = ?, role_id = ?,
|
||||
is_active = ?, password_changed_at = NOW()
|
||||
WHERE id = ?
|
||||
');
|
||||
$stmt->execute([$username, $email, $passwordHash, $firstName, $lastName, $roleId, $isActive, $userId]);
|
||||
} else {
|
||||
$stmt = $pdo->prepare('
|
||||
UPDATE users
|
||||
SET username = ?, email = ?, first_name = ?, last_name = ?, role_id = ?, is_active = ?
|
||||
WHERE id = ?
|
||||
');
|
||||
$stmt->execute([$username, $email, $firstName, $lastName, $roleId, $isActive, $userId]);
|
||||
}
|
||||
|
||||
// Note: With JWT, user data is in the token - no session to update
|
||||
|
||||
// Audit log
|
||||
AuditLog::logUpdate('user', $userId, [
|
||||
'username' => $existingUser['username'],
|
||||
'email' => $existingUser['email'],
|
||||
'first_name' => $existingUser['first_name'],
|
||||
'last_name' => $existingUser['last_name'],
|
||||
'role_id' => $existingUser['role_id'],
|
||||
'is_active' => $existingUser['is_active'],
|
||||
], [
|
||||
'username' => $username,
|
||||
'email' => $email,
|
||||
'first_name' => $firstName,
|
||||
'last_name' => $lastName,
|
||||
'role_id' => $roleId,
|
||||
'is_active' => $isActive,
|
||||
], "Upraven uživatel '$username'");
|
||||
|
||||
successResponse(null, 'Uživatel byl úspěšně aktualizován');
|
||||
}
|
||||
|
||||
/**
|
||||
* DELETE - Delete user
|
||||
*/
|
||||
function handleDeleteUser(PDO $pdo, int $userId, int $currentUserId): void
|
||||
{
|
||||
// Prevent self-deletion
|
||||
if ($userId === $currentUserId) {
|
||||
errorResponse('Nemůžete smazat svůj vlastní účet');
|
||||
}
|
||||
|
||||
// Get user for audit log
|
||||
$stmt = $pdo->prepare('SELECT username FROM users WHERE id = ?');
|
||||
$stmt->execute([$userId]);
|
||||
$user = $stmt->fetch();
|
||||
|
||||
if (!$user) {
|
||||
errorResponse('Uživatel nebyl nalezen', 404);
|
||||
}
|
||||
|
||||
// Delete related records first (refresh tokens for JWT auth)
|
||||
$stmt = $pdo->prepare('DELETE FROM refresh_tokens WHERE user_id = ?');
|
||||
$stmt->execute([$userId]);
|
||||
|
||||
// Delete user
|
||||
$stmt = $pdo->prepare('DELETE FROM users WHERE id = ?');
|
||||
$stmt->execute([$userId]);
|
||||
|
||||
// Audit log
|
||||
AuditLog::logDelete('user', $userId, ['username' => $user['username']], "Smazán uživatel '{$user['username']}'");
|
||||
|
||||
successResponse(null, 'Uživatel byl úspěšně smazán');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user