feat(admin): 增加玩家密码管理与角色边界
This commit is contained in:
@@ -1,15 +1,18 @@
|
||||
<?php
|
||||
|
||||
use App\Models\Player;
|
||||
use App\Lottery\ErrorCode;
|
||||
use Illuminate\Support\Str;
|
||||
use App\Models\PlayerWallet;
|
||||
use App\Support\PlayerAuthSource;
|
||||
use App\Support\PlayerFundingMode;
|
||||
use Database\Seeders\CurrencySeeder;
|
||||
use Database\Seeders\LotterySettingsSeeder;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Database\Seeders\CurrencySeeder;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Database\Seeders\LotterySettingsSeeder;
|
||||
use App\Services\Player\PlayerNativeAuthService;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
|
||||
uses(RefreshDatabase::class);
|
||||
|
||||
@@ -257,7 +260,7 @@ test('credit player wallet transfer in is rejected', function (): void {
|
||||
'status' => 0,
|
||||
]);
|
||||
|
||||
$auth = app(\App\Services\Player\PlayerNativeAuthService::class);
|
||||
$auth = app(PlayerNativeAuthService::class);
|
||||
$token = $auth->issueToken($player);
|
||||
|
||||
$response = $this->withHeader('Authorization', 'Bearer '.$token)
|
||||
@@ -293,7 +296,7 @@ test('sso wallet player balance does not use credit when site credit mode on', f
|
||||
'status' => 0,
|
||||
]);
|
||||
|
||||
\App\Models\PlayerWallet::query()->create([
|
||||
PlayerWallet::query()->create([
|
||||
'player_id' => $player->id,
|
||||
'wallet_type' => 'lottery',
|
||||
'currency_code' => 'NPR',
|
||||
@@ -311,3 +314,108 @@ test('sso wallet player balance does not use credit when site credit mode on', f
|
||||
->assertJsonPath('data.funding_mode', PlayerFundingMode::WALLET)
|
||||
->assertJsonPath('data.available_balance', 12000);
|
||||
});
|
||||
|
||||
test('native player can change password and previous tokens are invalidated', function (): void {
|
||||
$site = DB::table('admin_sites')->where('is_default', true)->first();
|
||||
$rootId = (int) DB::table('agent_nodes')->where('depth', 0)->value('id');
|
||||
|
||||
$player = Player::query()->create([
|
||||
'site_code' => (string) $site->code,
|
||||
'agent_node_id' => $rootId,
|
||||
'site_player_id' => 'native:password-change',
|
||||
'auth_source' => PlayerAuthSource::LOTTERY_NATIVE,
|
||||
'funding_mode' => PlayerFundingMode::CREDIT,
|
||||
'username' => 'password_change_user',
|
||||
'password_hash' => Hash::make('old-secret'),
|
||||
'default_currency' => 'NPR',
|
||||
'status' => 0,
|
||||
]);
|
||||
|
||||
$oldToken = app(PlayerNativeAuthService::class)->issueToken($player);
|
||||
|
||||
$this->withHeader('Authorization', 'Bearer '.$oldToken)
|
||||
->putJson('/api/v1/player/password', [
|
||||
'current_password' => 'old-secret',
|
||||
'password' => 'new-secret',
|
||||
'password_confirmation' => 'new-secret',
|
||||
])
|
||||
->assertOk()
|
||||
->assertJsonPath('data.password_changed', true);
|
||||
|
||||
$player->refresh();
|
||||
expect(Hash::check('new-secret', (string) $player->password_hash))->toBeTrue()
|
||||
->and($player->native_token_version)->toBe(1);
|
||||
|
||||
$this->withHeader('Authorization', 'Bearer '.$oldToken)
|
||||
->getJson('/api/v1/player/me')
|
||||
->assertStatus(401)
|
||||
->assertJsonPath('code', ErrorCode::PlayerTokenInvalid->value);
|
||||
|
||||
$this->postJson('/api/v1/player/auth/login', array_merge([
|
||||
'username' => 'password_change_user',
|
||||
'password' => 'old-secret',
|
||||
], playerLoginCaptcha()))
|
||||
->assertStatus(401)
|
||||
->assertJsonPath('code', ErrorCode::PlayerCredentialsInvalid->value);
|
||||
|
||||
$this->postJson('/api/v1/player/auth/login', array_merge([
|
||||
'username' => 'password_change_user',
|
||||
'password' => 'new-secret',
|
||||
], playerLoginCaptcha()))
|
||||
->assertOk()
|
||||
->assertJsonPath('data.player.id', $player->id);
|
||||
});
|
||||
|
||||
test('native player password change validates current password', function (): void {
|
||||
$site = DB::table('admin_sites')->where('is_default', true)->first();
|
||||
$rootId = (int) DB::table('agent_nodes')->where('depth', 0)->value('id');
|
||||
|
||||
$player = Player::query()->create([
|
||||
'site_code' => (string) $site->code,
|
||||
'agent_node_id' => $rootId,
|
||||
'site_player_id' => 'native:password-current',
|
||||
'auth_source' => PlayerAuthSource::LOTTERY_NATIVE,
|
||||
'funding_mode' => PlayerFundingMode::CREDIT,
|
||||
'username' => 'password_current_user',
|
||||
'password_hash' => Hash::make('old-secret'),
|
||||
'default_currency' => 'NPR',
|
||||
'status' => 0,
|
||||
]);
|
||||
|
||||
$token = app(PlayerNativeAuthService::class)->issueToken($player);
|
||||
|
||||
$this->withHeader('Authorization', 'Bearer '.$token)
|
||||
->putJson('/api/v1/player/password', [
|
||||
'current_password' => 'wrong-secret',
|
||||
'password' => 'new-secret',
|
||||
'password_confirmation' => 'new-secret',
|
||||
])
|
||||
->assertStatus(422)
|
||||
->assertJsonPath('msg', 'The current password is incorrect.');
|
||||
|
||||
expect($player->fresh()->native_token_version)->toBe(0)
|
||||
->and(Hash::check('old-secret', (string) $player->fresh()->password_hash))->toBeTrue();
|
||||
});
|
||||
|
||||
test('sso player cannot use native password management', function (): void {
|
||||
$site = DB::table('admin_sites')->where('is_default', true)->first();
|
||||
|
||||
$player = Player::query()->create([
|
||||
'site_code' => (string) $site->code,
|
||||
'site_player_id' => 'sso-no-password',
|
||||
'auth_source' => PlayerAuthSource::MAIN_SITE_SSO,
|
||||
'funding_mode' => PlayerFundingMode::WALLET,
|
||||
'username' => 'sso_no_password',
|
||||
'default_currency' => 'NPR',
|
||||
'status' => 0,
|
||||
]);
|
||||
|
||||
$this->withHeader('Authorization', 'Bearer dev:'.$player->id)
|
||||
->putJson('/api/v1/player/password', [
|
||||
'current_password' => 'old-secret',
|
||||
'password' => 'new-secret',
|
||||
'password_confirmation' => 'new-secret',
|
||||
])
|
||||
->assertStatus(422)
|
||||
->assertJsonPath('msg', 'Main-site SSO players do not use a lottery password.');
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user