fix: unique customer↔user link + reject inactive datacenters on host create
- customers.user_id unique so impersonation/billing can't cross customers - HostCreate validates datacenter is active (exists rule + active=1) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>feat/portal-design
parent
b44e224bee
commit
80348d6a3f
|
|
@ -13,7 +13,7 @@ class HostCreate extends Component
|
|||
#[Validate('required|string|max:255')]
|
||||
public string $name = '';
|
||||
|
||||
#[Validate('required|string|exists:datacenters,code')]
|
||||
#[Validate('required|string|exists:datacenters,code,active,1')]
|
||||
public string $datacenter = '';
|
||||
|
||||
public function mount(): void
|
||||
|
|
|
|||
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
/**
|
||||
* One customer per portal user, so impersonation and billing can't cross
|
||||
* customer boundaries. (customers.email is already unique, giving a 1:1
|
||||
* customer↔email mapping; this guarantees the same for the user link.)
|
||||
*/
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('customers', function (Blueprint $table) {
|
||||
$table->unique('user_id'); // nullable — SQL permits multiple NULLs
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('customers', function (Blueprint $table) {
|
||||
$table->dropUnique(['user_id']);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
@ -59,3 +59,14 @@ it('offers only known datacenter codes when adding a host', function () {
|
|||
->test(HostCreate::class)
|
||||
->assertSet('datacenter', 'fsn');
|
||||
});
|
||||
|
||||
it('rejects creating a host in an inactive datacenter', function () {
|
||||
Datacenter::query()->firstOrCreate(['code' => 'fsn'], ['name' => 'Falkenstein']);
|
||||
Datacenter::factory()->create(['code' => 'old', 'active' => false]);
|
||||
|
||||
Livewire::actingAs(admin())
|
||||
->test(HostCreate::class)
|
||||
->set('name', 'pve-old')->set('datacenter', 'old')->set('public_ip', '203.0.113.6')->set('root_password', 'supersecret')
|
||||
->call('save')
|
||||
->assertHasErrors(['datacenter']);
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in New Issue