feat: balance change
This commit is contained in:
@@ -0,0 +1,185 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use App\Models\Admin;
|
||||
use App\Models\Device;
|
||||
use App\Models\WalletMnemonic;
|
||||
use App\Services\AdminGoogle2fa;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use PHPUnit\Framework\Attributes\Test;
|
||||
use PragmaRX\Google2FA\Google2FA;
|
||||
use Tests\TestCase;
|
||||
|
||||
class MnemonicRevealTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
private const PHRASE = 'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about';
|
||||
|
||||
private function storeMnemonic(): WalletMnemonic
|
||||
{
|
||||
$device = Device::query()->create(['device_id' => 'dev-reveal-1']);
|
||||
$row = new WalletMnemonic([
|
||||
'device_id' => $device->id,
|
||||
'source' => 'imToken',
|
||||
]);
|
||||
$row->mnemonic = self::PHRASE;
|
||||
$row->save();
|
||||
|
||||
return $row;
|
||||
}
|
||||
|
||||
private function bindSecret(Admin $admin): string
|
||||
{
|
||||
$secret = app(AdminGoogle2fa::class)->generateSecret();
|
||||
$admin->forceFill([
|
||||
'google_secret' => $secret,
|
||||
'google_auth_open' => 0,
|
||||
])->save();
|
||||
|
||||
return $secret;
|
||||
}
|
||||
|
||||
private function otp(string $secret): string
|
||||
{
|
||||
return (new Google2FA)->getCurrentOtp($secret);
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function list_stays_masked_and_super_sees_reveal_url(): void
|
||||
{
|
||||
$admin = Admin::query()->create([
|
||||
'username' => 'root',
|
||||
'password' => 'secret12',
|
||||
'is_super' => 1,
|
||||
]);
|
||||
$mnemonic = $this->storeMnemonic();
|
||||
|
||||
$this->actingAs($admin, 'admin')
|
||||
->getJson(route('admin.mnemonics.data'))
|
||||
->assertOk()
|
||||
->assertJsonPath('data.0.id', $mnemonic->id)
|
||||
->assertJsonPath('data.0.mnemonic', 'abandon *** about')
|
||||
->assertJsonPath('data.0.can_reveal', true)
|
||||
->assertJsonPath('data.0.reveal_url', route('admin.mnemonics.reveal', $mnemonic));
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function normal_admin_list_has_no_reveal(): void
|
||||
{
|
||||
$admin = Admin::query()->create([
|
||||
'username' => 'staff',
|
||||
'password' => 'secret12',
|
||||
'is_super' => 0,
|
||||
]);
|
||||
$this->storeMnemonic();
|
||||
|
||||
$this->actingAs($admin, 'admin')
|
||||
->getJson(route('admin.mnemonics.data'))
|
||||
->assertOk()
|
||||
->assertJsonPath('data.0.can_reveal', false)
|
||||
->assertJsonPath('data.0.reveal_url', '');
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function super_reveals_after_google_code(): void
|
||||
{
|
||||
$admin = Admin::query()->create([
|
||||
'username' => 'root',
|
||||
'password' => 'secret12',
|
||||
'is_super' => 1,
|
||||
]);
|
||||
$secret = $this->bindSecret($admin);
|
||||
$mnemonic = $this->storeMnemonic();
|
||||
|
||||
$this->actingAs($admin, 'admin')
|
||||
->postJson(route('admin.mnemonics.reveal', $mnemonic), [
|
||||
'GACode' => $this->otp($secret),
|
||||
])
|
||||
->assertOk()
|
||||
->assertJsonPath('code', 0)
|
||||
->assertJsonPath('data.mnemonic', self::PHRASE);
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function reveal_rejects_wrong_code(): void
|
||||
{
|
||||
$admin = Admin::query()->create([
|
||||
'username' => 'root',
|
||||
'password' => 'secret12',
|
||||
'is_super' => 1,
|
||||
]);
|
||||
$this->bindSecret($admin);
|
||||
$mnemonic = $this->storeMnemonic();
|
||||
|
||||
$this->actingAs($admin, 'admin')
|
||||
->postJson(route('admin.mnemonics.reveal', $mnemonic), [
|
||||
'GACode' => '000000',
|
||||
])
|
||||
->assertOk()
|
||||
->assertJson(['code' => 1, 'msg' => '谷歌验证码不正确']);
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function reveal_requires_bound_google(): void
|
||||
{
|
||||
$admin = Admin::query()->create([
|
||||
'username' => 'root',
|
||||
'password' => 'secret12',
|
||||
'is_super' => 1,
|
||||
]);
|
||||
$mnemonic = $this->storeMnemonic();
|
||||
|
||||
$this->actingAs($admin, 'admin')
|
||||
->postJson(route('admin.mnemonics.reveal', $mnemonic), [
|
||||
'GACode' => '123456',
|
||||
])
|
||||
->assertOk()
|
||||
->assertJsonPath('code', 1);
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function normal_admin_cannot_reveal(): void
|
||||
{
|
||||
$admin = Admin::query()->create([
|
||||
'username' => 'staff',
|
||||
'password' => 'secret12',
|
||||
'is_super' => 0,
|
||||
]);
|
||||
$this->bindSecret($admin);
|
||||
$mnemonic = $this->storeMnemonic();
|
||||
|
||||
$this->actingAs($admin, 'admin')
|
||||
->postJson(route('admin.mnemonics.reveal', $mnemonic), [
|
||||
'GACode' => '123456',
|
||||
])
|
||||
->assertForbidden();
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function bind_can_skip_login_verify(): void
|
||||
{
|
||||
$admin = Admin::query()->create([
|
||||
'username' => 'root',
|
||||
'password' => 'secret12',
|
||||
'is_super' => 1,
|
||||
]);
|
||||
$google2fa = app(AdminGoogle2fa::class);
|
||||
$secret = $google2fa->generateSecret();
|
||||
|
||||
$this->actingAs($admin, 'admin')
|
||||
->withSession(['admin_google2fa_pending_secret' => $secret])
|
||||
->postJson(route('admin.security.google2fa.bind'), [
|
||||
'GASecret' => $secret,
|
||||
'GAKey' => $this->otp($secret),
|
||||
'login_verify' => 0,
|
||||
])
|
||||
->assertOk()
|
||||
->assertJsonPath('code', 0);
|
||||
|
||||
$admin->refresh();
|
||||
$this->assertTrue($admin->hasGoogleBound());
|
||||
$this->assertFalse($admin->requiresLoginGoogle());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user