feat: password rotation, PPSK management, VLAN/AP groups
- Add password rotation: RotatePasswords console command + migration + service updates - Add PPSK management: UnifiPpsk model, migration, SyncPpskSchedules console - Add VLAN groups and AP groups: VlanGroupController, ApGroupController, model, migration - Add RebootAllAps console command - Add in_alert column to device states - Wire new features through service provider, routes, and existing controllers/services Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('unifi_password_rotations', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('name'); // display name (e.g. "Staff WiFi")
|
||||
$table->json('wlan_ids'); // array of WLAN IDs to rotate
|
||||
$table->text('wordlist')->nullable(); // one password per line
|
||||
$table->boolean('enabled')->default(true);
|
||||
$table->string('frequency')->default('weekly'); // daily | weekly
|
||||
$table->tinyInteger('day_of_week')->nullable(); // 0=Sun ... 6=Sat (weekly only)
|
||||
$table->tinyInteger('hour')->default(1);
|
||||
$table->tinyInteger('minute')->default(0);
|
||||
$table->timestamp('last_rotated_at')->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('unifi_password_rotations');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('unifi_vlan_groups', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('name'); // e.g. "Students"
|
||||
$table->unsignedSmallInteger('vlan_id'); // 1–4094
|
||||
$table->string('description')->nullable(); // optional note
|
||||
$table->unsignedSmallInteger('sort_order')->default(0);
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('unifi_vlan_groups');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('unifi_device_states', function (Blueprint $table) {
|
||||
// Tracks whether an active device_offline alert has been sent for this device.
|
||||
// device_online ("resolved") only fires when in_alert = true.
|
||||
// This prevents orphan "back online" alerts and duplicate offline alerts.
|
||||
$table->boolean('in_alert')->default(false)->after('was_online');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('unifi_device_states', function (Blueprint $table) {
|
||||
$table->dropColumn('in_alert');
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('unifi_ppsks', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('wlan_id', 36)->index(); // UniFi WLAN _id
|
||||
$table->string('unifi_id', 36)->nullable()->index(); // null when held (not currently in UniFi)
|
||||
$table->string('name', 100);
|
||||
$table->string('x_passphrase', 63);
|
||||
$table->unsignedSmallInteger('vlan')->nullable();
|
||||
$table->enum('state', ['active', 'held'])->default('active')->index();
|
||||
$table->boolean('rotate_password')->default(false);
|
||||
$table->json('schedule')->nullable(); // 336 booleans [day*48+slot], null = unscheduled
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('unifi_ppsks');
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user