feat: enhance player authentication and agent management features
Some checks failed
lotterLaravel CI / test (push) Has been cancelled

- Updated AGENTS.md to clarify player interface bindings and agent account restrictions.
- Improved PlayerAuthLoginController to include captcha verification for player login.
- Enhanced AdminPlayerIndexController with permission checks for admin users.
- Refactored AdminPlayerStoreController to enforce agent node restrictions for non-super admins.
- Introduced new error codes for player authentication failures and updated related services.
- Enhanced validation rules for agent profiles to include settlement cycle options.
- Improved AdminCaptchaService to support separate scopes for admin and player captcha handling.
- Updated various services to ensure proper credit management and settlement processes.
This commit is contained in:
2026-06-17 15:27:00 +08:00
parent b496a9457c
commit 2e0b257160
49 changed files with 714 additions and 334 deletions

View File

@@ -6,11 +6,19 @@ use Illuminate\Support\Str;
use Illuminate\Support\Facades\Cache;
/**
* 后台登录图形验证码SVG 产出 + Cache 短时保存答案摘要(单行文本,便于前台用 img[src=data:...] 展示)。
* 图形验证码SVG 产出 + Cache 短时保存答案摘要(admin / player 登录共用渲染逻辑)。
*/
final class AdminCaptchaService
{
private const PREFIX = 'admin_captcha:';
public const SCOPE_ADMIN = 'admin';
public const SCOPE_PLAYER = 'player';
/** @var array<string, string> */
private const PREFIXES = [
self::SCOPE_ADMIN => 'admin_captcha:',
self::SCOPE_PLAYER => 'player_captcha:',
];
private const TTL_SECONDS = 120;
@@ -20,13 +28,13 @@ final class AdminCaptchaService
/**
* @return array{captcha_key: string, image_svg: string, image_base64: string}
*/
public function create(): array
public function create(string $scope = self::SCOPE_ADMIN): array
{
$code = $this->randomCode();
$key = (string) Str::uuid();
Cache::put(
self::PREFIX.$key,
$this->prefix($scope).$key,
$this->digest($code),
now()->addSeconds(self::TTL_SECONDS),
);
@@ -40,14 +48,14 @@ final class AdminCaptchaService
];
}
public function verify(?string $captchaKey, ?string $captchaInput): bool
public function verify(?string $captchaKey, ?string $captchaInput, string $scope = self::SCOPE_ADMIN): bool
{
if ($captchaKey === null || $captchaKey === ''
|| $captchaInput === null || trim($captchaInput) === '') {
return false;
}
$digest = Cache::pull(self::PREFIX.$captchaKey);
$digest = Cache::pull($this->prefix($scope).$captchaKey);
if ($digest === null) {
return false;
}
@@ -57,6 +65,16 @@ final class AdminCaptchaService
return hash_equals($digest, $this->digest($guess));
}
private function prefix(string $scope): string
{
$prefix = self::PREFIXES[$scope] ?? null;
if ($prefix === null) {
throw new \InvalidArgumentException('invalid_captcha_scope');
}
return $prefix;
}
private function digest(string $normalizedCode): string
{
return hash_hmac(