169 lines
5.5 KiB
PHP
169 lines
5.5 KiB
PHP
<?php
|
|
|
|
namespace App\Providers;
|
|
|
|
use App\Broadcasting\ExpoPushChannel;
|
|
use App\Mail\ResetPasswordMail;
|
|
use App\Mail\VerifyAccount;
|
|
use App\Models\User;
|
|
use Illuminate\Auth\Notifications\ResetPassword;
|
|
use Illuminate\Auth\Notifications\VerifyEmail;
|
|
use Illuminate\Cache\RateLimiting\Limit;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Gate;
|
|
use Illuminate\Support\Facades\Notification;
|
|
use Illuminate\Support\Facades\RateLimiter;
|
|
use Illuminate\Support\Facades\URL;
|
|
use Illuminate\Support\ServiceProvider;
|
|
use Spatie\Health\Checks\Checks\DatabaseCheck;
|
|
use Spatie\Health\Checks\Checks\DebugModeCheck;
|
|
use Spatie\Health\Checks\Checks\EnvironmentCheck;
|
|
use Spatie\Health\Checks\Checks\HorizonCheck;
|
|
use Spatie\Health\Checks\Checks\MeilisearchCheck;
|
|
use Spatie\Health\Checks\Checks\OptimizedAppCheck;
|
|
use Spatie\Health\Checks\Checks\RedisCheck;
|
|
use Spatie\Health\Checks\Checks\ScheduleCheck;
|
|
use Spatie\Health\Checks\Checks\UsedDiskSpaceCheck;
|
|
use Spatie\Health\Facades\Health;
|
|
|
|
class AppServiceProvider extends ServiceProvider
|
|
{
|
|
/**
|
|
* Register any application services.
|
|
*/
|
|
public function register(): void
|
|
{
|
|
//
|
|
}
|
|
|
|
/**
|
|
* Bootstrap any application services.
|
|
*/
|
|
public function boot(): void
|
|
{
|
|
$this->configureRateLimiting();
|
|
|
|
if ($this->app->environment('production')) {
|
|
URL::forceScheme('https');
|
|
}
|
|
|
|
Notification::extend('expo', fn ($app) => $app->make(ExpoPushChannel::class));
|
|
|
|
VerifyEmail::createUrlUsing(function (User $notifiable): string {
|
|
$relativeUrl = URL::temporarySignedRoute(
|
|
'verification.verify',
|
|
now()->addMinutes((int) config('auth.verification.expire', 60)),
|
|
[
|
|
'id' => $notifiable->getKey(),
|
|
'hash' => sha1($notifiable->getEmailForVerification()),
|
|
],
|
|
absolute: false,
|
|
);
|
|
|
|
return url($relativeUrl);
|
|
});
|
|
|
|
VerifyEmail::toMailUsing(
|
|
fn (User $notifiable, string $verificationUrl): VerifyAccount => (new VerifyAccount($notifiable, $verificationUrl))
|
|
->to($notifiable->getEmailForVerification())
|
|
);
|
|
|
|
$passwordResetUrl = function (User $notifiable, string $token): string {
|
|
return route('password.reset', [
|
|
'email' => $notifiable->getEmailForPasswordReset(),
|
|
'token' => $token,
|
|
]);
|
|
};
|
|
|
|
ResetPassword::createUrlUsing($passwordResetUrl);
|
|
|
|
ResetPassword::toMailUsing(
|
|
fn (User $notifiable, string $token): ResetPasswordMail => (new ResetPasswordMail($notifiable, $passwordResetUrl($notifiable, $token)))
|
|
->to($notifiable->getEmailForPasswordReset())
|
|
);
|
|
|
|
Gate::define('viewApiDocs', fn (?User $user): bool => $user?->isAdmin() === true);
|
|
|
|
Health::checks([
|
|
DatabaseCheck::new(),
|
|
UsedDiskSpaceCheck::new(),
|
|
RedisCheck::new(),
|
|
ScheduleCheck::new(),
|
|
HorizonCheck::new(),
|
|
OptimizedAppCheck::new(),
|
|
EnvironmentCheck::new(),
|
|
DebugModeCheck::new(),
|
|
MeilisearchCheck::new()
|
|
->url('http://meilisearch:7700/health'),
|
|
|
|
]);
|
|
}
|
|
|
|
private function configureRateLimiting(): void
|
|
{
|
|
RateLimiter::for('auth', fn (Request $request): array => [
|
|
Limit::perMinute(20)->by('ip:'.$request->ip()),
|
|
Limit::perMinute(5)->by($this->loginRateLimitKey($request)),
|
|
]);
|
|
|
|
RateLimiter::for(
|
|
'account-action',
|
|
fn (Request $request): Limit => Limit::perMinute(5)->by($this->userRateLimitKey($request))
|
|
);
|
|
|
|
RateLimiter::for(
|
|
'content-write',
|
|
fn (Request $request): Limit => Limit::perMinute(30)->by($this->userRateLimitKey($request))
|
|
);
|
|
|
|
RateLimiter::for(
|
|
'engagement',
|
|
fn (Request $request): Limit => Limit::perMinute(60)->by($this->userRateLimitKey($request))
|
|
);
|
|
|
|
RateLimiter::for('ai-analysis', fn (Request $request): array => [
|
|
Limit::perMinute(5)->by('minute:'.$this->userRateLimitKey($request)),
|
|
Limit::perHour(30)->by('hour:'.$this->userRateLimitKey($request)),
|
|
]);
|
|
|
|
RateLimiter::for(
|
|
'external-service',
|
|
fn (Request $request): Limit => Limit::perMinute(10)->by($this->userRateLimitKey($request))
|
|
);
|
|
|
|
RateLimiter::for(
|
|
'device-token',
|
|
fn (Request $request): Limit => Limit::perMinute(30)->by($this->userRateLimitKey($request))
|
|
);
|
|
|
|
RateLimiter::for(
|
|
'rewarded-ad',
|
|
fn (Request $request): Limit => Limit::perMinute(10)->by($this->userRateLimitKey($request))
|
|
);
|
|
|
|
RateLimiter::for(
|
|
'notifications',
|
|
fn (Request $request): Limit => Limit::perMinute(3)->by($this->userRateLimitKey($request))
|
|
);
|
|
|
|
RateLimiter::for(
|
|
'reports',
|
|
fn (Request $request): Limit => Limit::perMinute(10)->by($this->userRateLimitKey($request))
|
|
);
|
|
}
|
|
|
|
private function loginRateLimitKey(Request $request): string
|
|
{
|
|
$email = strtolower((string) $request->input('email', ''));
|
|
|
|
return $email !== '' ? 'email:'.$email : 'ip:'.$request->ip();
|
|
}
|
|
|
|
private function userRateLimitKey(Request $request): string
|
|
{
|
|
$userId = $request->user()?->getAuthIdentifier();
|
|
|
|
return $userId !== null ? 'user:'.$userId : 'ip:'.$request->ip();
|
|
}
|
|
}
|