Fix R15: no weak admin fallback in prod; validate device room update
- DatabaseSeeder throws outside local/testing when HOMEOS_ADMIN_PASSWORD is unset, instead of silently seeding the documented `homeos-dev` password (bootstrap always runs migrate --seed, so a prod misconfig must fail loudly). - Devices\Show::saveRoom validates roomId as nullable|exists:rooms,id, so a crafted request can no longer trigger a foreign-key 500. Added a feature test. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>feat/phase-1-bootstrap
parent
f00a1ac069
commit
dc27b1686c
|
|
@ -37,6 +37,7 @@ class Show extends Component
|
||||||
|
|
||||||
public function saveRoom(): void
|
public function saveRoom(): void
|
||||||
{
|
{
|
||||||
|
$this->validate(['roomId' => ['nullable', 'integer', 'exists:rooms,id']]);
|
||||||
$this->device->update(['room_id' => $this->roomId ?: null]);
|
$this->device->update(['room_id' => $this->roomId ?: null]);
|
||||||
$this->flashMessage(__('devices.saved'));
|
$this->flashMessage(__('devices.saved'));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,9 +15,17 @@ class DatabaseSeeder extends Seeder
|
||||||
*/
|
*/
|
||||||
public function run(): void
|
public function run(): void
|
||||||
{
|
{
|
||||||
// `?:` (not env's 2nd arg) so a present-but-empty HOMEOS_ADMIN_PASSWORD can never
|
// The admin password must be explicit outside local/testing — never silently seed a
|
||||||
// seed a blank-password admin — it falls back to a non-empty dev default.
|
// known credential in production. The dev fallback only applies to local/testing.
|
||||||
$adminPassword = env('HOMEOS_ADMIN_PASSWORD') ?: 'homeos-dev';
|
$adminPassword = env('HOMEOS_ADMIN_PASSWORD');
|
||||||
|
|
||||||
|
if (blank($adminPassword)) {
|
||||||
|
if (! app()->environment('local', 'testing')) {
|
||||||
|
throw new \RuntimeException('HOMEOS_ADMIN_PASSWORD must be set to seed the admin account outside local/testing.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$adminPassword = 'homeos-dev';
|
||||||
|
}
|
||||||
|
|
||||||
User::updateOrCreate(
|
User::updateOrCreate(
|
||||||
['email' => env('HOMEOS_ADMIN_EMAIL', 'admin@homeos.local')],
|
['email' => env('HOMEOS_ADMIN_EMAIL', 'admin@homeos.local')],
|
||||||
|
|
|
||||||
|
|
@ -2,12 +2,14 @@
|
||||||
|
|
||||||
namespace Tests\Feature;
|
namespace Tests\Feature;
|
||||||
|
|
||||||
|
use App\Livewire\Devices\Show;
|
||||||
use App\Models\Device;
|
use App\Models\Device;
|
||||||
use App\Models\DeviceState;
|
use App\Models\DeviceState;
|
||||||
use App\Models\Entity;
|
use App\Models\Entity;
|
||||||
use App\Models\Room;
|
use App\Models\Room;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||||
|
use Livewire\Livewire;
|
||||||
use Tests\TestCase;
|
use Tests\TestCase;
|
||||||
|
|
||||||
class HomeTest extends TestCase
|
class HomeTest extends TestCase
|
||||||
|
|
@ -55,4 +57,18 @@ class HomeTest extends TestCase
|
||||||
->assertSee(__('dashboard.warnings_title'))
|
->assertSee(__('dashboard.warnings_title'))
|
||||||
->assertSee('Türsensor');
|
->assertSee('Türsensor');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function test_device_room_update_rejects_invalid_room(): void
|
||||||
|
{
|
||||||
|
$device = Device::create(['name' => 'Lampe', 'status' => 'active', 'last_seen_at' => now()]);
|
||||||
|
|
||||||
|
$this->actingAs(User::factory()->create());
|
||||||
|
|
||||||
|
Livewire::test(Show::class, ['device' => $device])
|
||||||
|
->set('roomId', 999999)
|
||||||
|
->call('saveRoom')
|
||||||
|
->assertHasErrors('roomId');
|
||||||
|
|
||||||
|
$this->assertNull($device->fresh()->room_id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue