feat: replace token-based impersonation with enterprise-grade header-based system
Replaces the insecure token-in-localStorage approach with a header-based impersonation system backed by cache sessions and MFA verification. Key changes: - New impersonation_sessions audit table (immutable, ULID PK) - MFA verification required to start impersonation (TOTP/email/backup) - X-Impersonate-User header + HandleImpersonation middleware - Per-request auth context swap (admin session never modified) - IP pinning, sensitive route blocking, no nesting, sliding 60-min TTL - Activity log auto-tagged with impersonated_by during sessions - Frontend: sessionStorage, BroadcastChannel sync, countdown timer - ImpersonateDialog with reason + MFA verification flow - 26 comprehensive tests covering core, middleware, audit, lifecycle Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -8,6 +8,7 @@ use App\Models\Person;
|
||||
use App\Observers\PersonObserver;
|
||||
use Illuminate\Auth\Notifications\ResetPassword;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Spatie\Activitylog\Models\Activity;
|
||||
|
||||
class AppServiceProvider extends ServiceProvider
|
||||
{
|
||||
@@ -23,5 +24,24 @@ class AppServiceProvider extends ServiceProvider
|
||||
ResetPassword::createUrlUsing(function ($user, string $token) {
|
||||
return config('crewli.portal_url') . '/wachtwoord-resetten?token=' . $token . '&email=' . urlencode($user->email);
|
||||
});
|
||||
|
||||
// Tag activity log entries with impersonation context
|
||||
Activity::saving(function (Activity $activity) {
|
||||
$request = request();
|
||||
|
||||
$impersonator = $request->attributes->get('impersonator');
|
||||
$session = $request->attributes->get('impersonation_session');
|
||||
|
||||
if ($impersonator && $session) {
|
||||
$properties = $activity->properties?->toArray() ?? [];
|
||||
$properties['impersonated_by'] = [
|
||||
'user_id' => $impersonator->id,
|
||||
'name' => $impersonator->full_name,
|
||||
'email' => $impersonator->email,
|
||||
];
|
||||
$properties['impersonation_session_id'] = $session->id;
|
||||
$activity->properties = collect($properties);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user