Deploy 2: 2FA (App + Email) + REST API + CSV import-export + auto backup
- Filament v5 multiFactorAuthentication enabled on both panels (App + Email) - HasAppAuthentication + HasEmailAuthentication on User and SuperAdmin - Migration: app_authentication_secret + recovery_codes + email_authentication_at - Sanctum REST API: /api/v1/login, /me, clients, vehicles, work-orders - EnsureTokenMatchesTenant middleware blocks cross-tenant token usage - CsvImportExport service: clients + vehicles bulk via plain CSV - Import/Export buttons on Client + Vehicle list pages - ApiTokens page in tenant panel (generate/revoke + last-used) - BackupAllTenantsCommand + scheduler (daily 03:00, retain 14 days) - Background scheduler in entrypoint.sh
This commit is contained in:
@@ -2,21 +2,27 @@
|
||||
|
||||
namespace App\Models\Central;
|
||||
|
||||
use Filament\Auth\MultiFactor\App\Contracts\HasAppAuthentication;
|
||||
use Filament\Auth\MultiFactor\App\Contracts\HasAppAuthenticationRecovery;
|
||||
use Filament\Auth\MultiFactor\Email\Contracts\HasEmailAuthentication;
|
||||
use Filament\Models\Contracts\FilamentUser;
|
||||
use Filament\Panel;
|
||||
use Illuminate\Contracts\Auth\MustVerifyEmail;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
use Laravel\Sanctum\HasApiTokens;
|
||||
|
||||
class SuperAdmin extends Authenticatable implements FilamentUser
|
||||
class SuperAdmin extends Authenticatable implements FilamentUser, HasAppAuthentication, HasAppAuthenticationRecovery, HasEmailAuthentication
|
||||
{
|
||||
use HasFactory, Notifiable;
|
||||
use HasApiTokens, HasFactory, Notifiable;
|
||||
|
||||
protected $table = 'super_admins';
|
||||
|
||||
protected $fillable = [
|
||||
'name', 'email', 'password', 'is_active', 'last_login_at',
|
||||
'email_authentication_at',
|
||||
'app_authentication_secret', 'app_authentication_recovery_codes',
|
||||
];
|
||||
|
||||
protected $hidden = [
|
||||
@@ -28,8 +34,11 @@ class SuperAdmin extends Authenticatable implements FilamentUser
|
||||
return [
|
||||
'email_verified_at' => 'datetime',
|
||||
'last_login_at' => 'datetime',
|
||||
'email_authentication_at' => 'datetime',
|
||||
'password' => 'hashed',
|
||||
'is_active' => 'boolean',
|
||||
'app_authentication_secret' => 'encrypted',
|
||||
'app_authentication_recovery_codes' => 'encrypted:array',
|
||||
];
|
||||
}
|
||||
|
||||
@@ -37,4 +46,41 @@ class SuperAdmin extends Authenticatable implements FilamentUser
|
||||
{
|
||||
return $panel->getId() === 'central' && $this->is_active;
|
||||
}
|
||||
|
||||
public function hasEmailAuthentication(): bool
|
||||
{
|
||||
return $this->email_authentication_at !== null;
|
||||
}
|
||||
|
||||
public function toggleEmailAuthentication(bool $condition): void
|
||||
{
|
||||
$this->forceFill([
|
||||
'email_authentication_at' => $condition ? now() : null,
|
||||
])->saveQuietly();
|
||||
}
|
||||
|
||||
public function getAppAuthenticationSecret(): ?string
|
||||
{
|
||||
return $this->app_authentication_secret;
|
||||
}
|
||||
|
||||
public function saveAppAuthenticationSecret(?string $secret): void
|
||||
{
|
||||
$this->forceFill(['app_authentication_secret' => $secret])->saveQuietly();
|
||||
}
|
||||
|
||||
public function getAppAuthenticationHolderName(): string
|
||||
{
|
||||
return $this->email;
|
||||
}
|
||||
|
||||
public function getAppAuthenticationRecoveryCodes(): ?array
|
||||
{
|
||||
return $this->app_authentication_recovery_codes;
|
||||
}
|
||||
|
||||
public function saveAppAuthenticationRecoveryCodes(?array $codes): void
|
||||
{
|
||||
$this->forceFill(['app_authentication_recovery_codes' => $codes])->saveQuietly();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user