The PHP app runs on Cafe24 shared web hosting -- calling it 'cloud' was misleading. Renames the directory, the edge client module, and every doc/script/identifier that used the term. - cloud/ -> server/ (incl. server/deploy/build_cafe24_package.sh paths) - edge/cloudclient.py -> edge/serverclient.py, CloudClient -> ServerClient - cloud/docs/cloud-deploy.md -> server/docs/server-deploy.md - CLOUD_* env/config keys -> SERVER_* - tests renamed to match Tests: PHP 109 pass (4 skipped), pytest 167 pass. dist/ regenerated.
49 lines
1.6 KiB
PHP
49 lines
1.6 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
namespace App\Repository\Pdo;
|
|
|
|
use App\Repository\UserRepository;
|
|
use PDO;
|
|
|
|
final class PdoUserRepository implements UserRepository
|
|
{
|
|
public function __construct(private PDO $pdo) {}
|
|
|
|
public function byUsername(string $username): ?array
|
|
{
|
|
$st = $this->pdo->prepare(
|
|
'SELECT id, username, password_hash, role, site_scope, failed_attempts, locked_until
|
|
FROM move_users WHERE username = ? LIMIT 1'
|
|
);
|
|
$st->execute([$username]);
|
|
$row = $st->fetch();
|
|
if ($row === false) {
|
|
return null;
|
|
}
|
|
return [
|
|
'id' => (int)$row['id'],
|
|
'username' => $row['username'],
|
|
'password_hash' => $row['password_hash'],
|
|
'role' => $row['role'],
|
|
'site_scope' => $row['site_scope'],
|
|
'failed_attempts' => (int)$row['failed_attempts'],
|
|
'locked_until' => (int)$row['locked_until'],
|
|
];
|
|
}
|
|
|
|
public function recordFailure(int $userId, int $lockUntil): void
|
|
{
|
|
// Increment in SQL (not read-then-write in PHP) so concurrent failed
|
|
// logins for the same account can't clobber each other's count.
|
|
$st = $this->pdo->prepare(
|
|
'UPDATE move_users SET failed_attempts = failed_attempts + 1, locked_until = ? WHERE id = ?'
|
|
);
|
|
$st->execute([$lockUntil, $userId]);
|
|
}
|
|
|
|
public function clearFailures(int $userId): void
|
|
{
|
|
$st = $this->pdo->prepare('UPDATE move_users SET failed_attempts = 0, locked_until = 0 WHERE id = ?');
|
|
$st->execute([$userId]);
|
|
}
|
|
}
|