mirror of
https://github.com/coollabsio/coolify.git
synced 2026-11-06 13:10:37 -04:00
Allow validated host file and directory mounts outside resource directories while protecting external paths from deletion. Clean up cancelled deployment containers and clear tracked process IDs. Preserve legacy KeyDB and Dragonfly password parsing, accept server backup paths without extension restrictions, and allow Compose variable proxy ports.
106 lines
4.3 KiB
PHP
106 lines
4.3 KiB
PHP
<?php
|
|
|
|
namespace App\Providers;
|
|
|
|
use Illuminate\Auth\Events\Failed;
|
|
use Illuminate\Auth\Events\Login;
|
|
use Illuminate\Auth\Events\Logout;
|
|
use Illuminate\Auth\Events\PasswordReset;
|
|
use Illuminate\Auth\Events\Registered;
|
|
use Illuminate\Auth\Events\Verified;
|
|
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
|
|
use Illuminate\Support\Facades\Event;
|
|
use Laravel\Fortify\Events\RecoveryCodesGenerated;
|
|
use Laravel\Fortify\Events\TwoFactorAuthenticationConfirmed;
|
|
use Laravel\Fortify\Events\TwoFactorAuthenticationDisabled;
|
|
use Laravel\Fortify\Events\TwoFactorAuthenticationEnabled;
|
|
use SocialiteProviders\Authentik\AuthentikExtendSocialite;
|
|
use SocialiteProviders\Azure\AzureExtendSocialite;
|
|
use SocialiteProviders\Clerk\ClerkExtendSocialite;
|
|
use SocialiteProviders\Discord\DiscordExtendSocialite;
|
|
use SocialiteProviders\Google\GoogleExtendSocialite;
|
|
use SocialiteProviders\Infomaniak\InfomaniakExtendSocialite;
|
|
use SocialiteProviders\Manager\SocialiteWasCalled;
|
|
use SocialiteProviders\Zitadel\ZitadelExtendSocialite;
|
|
|
|
class EventServiceProvider extends ServiceProvider
|
|
{
|
|
protected $listen = [
|
|
SocialiteWasCalled::class => [
|
|
AzureExtendSocialite::class.'@handle',
|
|
AuthentikExtendSocialite::class.'@handle',
|
|
ClerkExtendSocialite::class.'@handle',
|
|
DiscordExtendSocialite::class.'@handle',
|
|
GoogleExtendSocialite::class.'@handle',
|
|
InfomaniakExtendSocialite::class.'@handle',
|
|
ZitadelExtendSocialite::class.'@handle',
|
|
],
|
|
];
|
|
|
|
public function boot(): void
|
|
{
|
|
Event::listen(Login::class, function (Login $event): void {
|
|
auditLog('auth.user.login_succeeded', $this->authContext($event->user));
|
|
});
|
|
Event::listen(Failed::class, function (Failed $event): void {
|
|
auditLog('auth.user.login_failed', [
|
|
'attempted_email' => $this->attemptedEmailForAudit(data_get($event->credentials, 'email')),
|
|
'guard' => $event->guard,
|
|
], 'warning');
|
|
});
|
|
Event::listen(Logout::class, function (Logout $event): void {
|
|
auditLog('auth.user.logged_out', $this->authContext($event->user));
|
|
});
|
|
Event::listen(Registered::class, function (Registered $event): void {
|
|
auditLog('auth.user.registered', $this->authContext($event->user));
|
|
});
|
|
Event::listen(Verified::class, function (Verified $event): void {
|
|
auditLog('auth.user.email_verified', $this->authContext($event->user));
|
|
});
|
|
Event::listen(PasswordReset::class, function (PasswordReset $event): void {
|
|
auditLog('auth.user.password_reset', $this->authContext($event->user));
|
|
});
|
|
Event::listen(TwoFactorAuthenticationEnabled::class, function (TwoFactorAuthenticationEnabled $event): void {
|
|
auditLog('auth.user.two_factor_enabled', $this->authContext($event->user));
|
|
});
|
|
Event::listen(TwoFactorAuthenticationConfirmed::class, function (TwoFactorAuthenticationConfirmed $event): void {
|
|
auditLog('auth.user.two_factor_confirmed', $this->authContext($event->user));
|
|
});
|
|
Event::listen(TwoFactorAuthenticationDisabled::class, function (TwoFactorAuthenticationDisabled $event): void {
|
|
auditLog('auth.user.two_factor_disabled', $this->authContext($event->user));
|
|
});
|
|
Event::listen(RecoveryCodesGenerated::class, function (RecoveryCodesGenerated $event): void {
|
|
auditLog('auth.user.recovery_codes_regenerated', $this->authContext($event->user));
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Users sometimes type a password into the email field, so only a valid email address is stored.
|
|
*/
|
|
private function attemptedEmailForAudit(mixed $email): ?string
|
|
{
|
|
if (blank($email)) {
|
|
return null;
|
|
}
|
|
|
|
return is_string($email) && filter_var($email, FILTER_VALIDATE_EMAIL) !== false ? $email : '[invalid]';
|
|
}
|
|
|
|
private function authContext(?object $user): array
|
|
{
|
|
return [
|
|
'team_id' => $user?->currentTeam()?->id,
|
|
'resource' => 'user',
|
|
'user_name' => $user?->name,
|
|
'actor_id' => $user?->id,
|
|
'actor_name' => $user?->name,
|
|
'actor_email' => $user?->email,
|
|
];
|
|
}
|
|
|
|
public function shouldDiscoverEvents(): bool
|
|
{
|
|
return true;
|
|
}
|
|
}
|