80 lines
3.4 KiB
PHP
80 lines
3.4 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature;
|
|
|
|
use App\Models\GameAccount;
|
|
use App\Services\VMangosSrpService;
|
|
use Illuminate\Database\Schema\Blueprint;
|
|
use Illuminate\Support\Carbon;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Schema;
|
|
use Tests\TestCase;
|
|
|
|
class LauncherGameTicketFeatureTest extends TestCase
|
|
{
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
|
|
config(['auth.guards.api' => [
|
|
'driver' => 'session',
|
|
'provider' => 'game_accounts_eloquent',
|
|
]]);
|
|
config([
|
|
'moonwell.auth_connection' => 'vmangos_auth',
|
|
'database.connections.vmangos_auth' => ['driver' => 'sqlite', 'database' => ':memory:', 'prefix' => ''],
|
|
]);
|
|
DB::purge('vmangos_auth');
|
|
Schema::connection('vmangos_auth')->create('launcher_ticket', function (Blueprint $table): void {
|
|
$table->unsignedInteger('account_id')->primary();
|
|
$table->binary('generation_id');
|
|
$table->binary('srp_salt');
|
|
$table->binary('srp_verifier');
|
|
$table->unsignedSmallInteger('client_build');
|
|
$table->binary('launcher_session_hash');
|
|
$table->dateTime('issued_at');
|
|
$table->dateTime('expires_at');
|
|
$table->binary('claim_nonce')->nullable();
|
|
});
|
|
}
|
|
|
|
public function test_game_ticket_is_issued_and_replaces_previous_generation(): void
|
|
{
|
|
config(['moonwell.timezone' => 'Europe/Samara']);
|
|
$this->travelTo(Carbon::parse('2026-10-04 12:00:00', 'UTC'));
|
|
$account = new GameAccount;
|
|
$account->id = 7;
|
|
$account->username = 'PLAYERONE';
|
|
$this->actingAs($account, 'api');
|
|
|
|
$response = $this->withToken('launcher-token')->postJson('/api/launcher/game-ticket', ['client_build' => 5875])->assertOk();
|
|
$first = $response->json('ticket');
|
|
$this->assertMatchesRegularExpression('/^[A-Z0-9]{16}$/', $first);
|
|
$this->assertSame('PLAYERONE', $response->json('account'));
|
|
$row = DB::connection('vmangos_auth')->table('launcher_ticket')->where('account_id', 7)->first();
|
|
$this->assertSame('2026-10-04 12:00:00.000000', $row->issued_at);
|
|
$this->assertSame('2026-10-04 12:01:00.000000', $row->expires_at);
|
|
$this->assertSame('2026-10-04T12:01:00Z', $response->json('expires_at'));
|
|
$this->assertTrue(app(VMangosSrpService::class)->credentialsMatch('PLAYERONE', $first, strtoupper(bin2hex($row->srp_salt)), strtoupper(bin2hex($row->srp_verifier))));
|
|
$generation = $row->generation_id;
|
|
|
|
$this->withToken('launcher-token')->postJson('/api/launcher/game-ticket', ['client_build' => 5875])->assertOk();
|
|
$this->assertSame(1, DB::connection('vmangos_auth')->table('launcher_ticket')->count());
|
|
$this->assertNotSame($generation, DB::connection('vmangos_auth')->table('launcher_ticket')->value('generation_id'));
|
|
}
|
|
|
|
public function test_ticket_rejects_wrong_build(): void
|
|
{
|
|
$account = new GameAccount;
|
|
$account->id = 7;
|
|
$account->username = 'PLAYERONE';
|
|
$this->actingAs($account, 'api');
|
|
$this->withToken('launcher-token')->postJson('/api/launcher/game-ticket', ['client_build' => 12340])->assertUnprocessable();
|
|
}
|
|
|
|
public function test_game_ticket_still_requires_launcher_authentication(): void
|
|
{
|
|
$this->postJson('/api/launcher/game-ticket', ['client_build' => 5875])->assertUnauthorized();
|
|
}
|
|
}
|