This commit is contained in:
2026-07-21 23:39:19 +02:00
commit b33b217bdb
217 changed files with 32076 additions and 0 deletions

View File

@@ -0,0 +1,169 @@
<?php
namespace App\Providers;
use App\Models\ApiClient;
use App\Support\Settings;
use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Database\Eloquent\Relations\Relation;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\ServiceProvider;
use LdapRecord\Connection;
use LdapRecord\Container;
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*/
public function register(): void
{
//
}
/**
* Bootstrap any application services.
*/
public function boot(): void
{
$this->applyLdapSettingsOverride();
$this->applyMailSettingsOverride();
$this->applySessionSettingsOverride();
$this->applyTimezoneSettingsOverride();
$this->configureApiRateLimiting();
Relation::enforceMorphMap(['api_client' => ApiClient::class]);
}
/**
* API keys get a generous per-key budget; unauthenticated requests (which
* only ever hit the guard before rejecting with 401) get a much smaller
* per-IP one so a single misconfigured client can't exhaust it for everyone.
*/
protected function configureApiRateLimiting(): void
{
RateLimiter::for('api', function (Request $request) {
$clientId = $request->user()?->id;
return $clientId
? Limit::perMinute(120)->by('api-client:'.$clientId)
: Limit::perMinute(30)->by('ip:'.$request->ip());
});
}
/**
* Avoid touching the DB during artisan commands that run before the
* `settings` table exists (e.g. `migrate` itself), or before it can be
* queried at all shared by every settings-driven config override below.
*/
protected function settingsTableUsable(): bool
{
if ($this->app->runningInConsole() && ! $this->app->runningUnitTests()) {
return false;
}
try {
return Schema::hasTable('settings');
} catch (\Throwable) {
return false;
}
}
/**
* Let the Admin -> Konfiguracja -> LDAP/AD screen override the .env-based
* LDAP connection at runtime, so changes take effect without a redeploy.
*/
protected function applyLdapSettingsOverride(): void
{
if (! $this->settingsTableUsable()) {
return;
}
$host = Settings::get('ldap_host');
if (! $host) {
return;
}
$config = Config::get('ldap.connections.default', []);
$config['hosts'] = [$host];
$config['port'] = (int) Settings::get('ldap_port', $config['port'] ?? 389);
$config['base_dn'] = Settings::get('ldap_base_dn', $config['base_dn'] ?? '');
$config['username'] = Settings::get('ldap_bind_dn', $config['username'] ?? '');
$config['password'] = Settings::get('ldap_bind_password') ?? $config['password'] ?? '';
$config['use_tls'] = Settings::bool('ldap_use_ssl');
Config::set('ldap.connections.default', $config);
Container::addConnection(new Connection($config), 'default');
}
/**
* Let the Admin -> Konfiguracja -> E-mail (SMTP) screen override the
* .env-based mail transport/sender at runtime. Sender address/name and
* footer apply regardless; the SMTP transport itself only when the admin
* has explicitly enabled it (otherwise the .env `MAIL_MAILER` stands).
*/
protected function applyMailSettingsOverride(): void
{
if (! $this->settingsTableUsable()) {
return;
}
if (Settings::bool('mail_smtp_enabled') && Settings::get('mail_smtp_host')) {
Config::set('mail.default', 'smtp');
Config::set('mail.mailers.smtp.host', Settings::get('mail_smtp_host'));
Config::set('mail.mailers.smtp.port', (int) Settings::get('mail_smtp_port', '587'));
Config::set('mail.mailers.smtp.username', Settings::get('mail_smtp_username') ?: null);
Config::set('mail.mailers.smtp.password', Settings::get('mail_smtp_password'));
Config::set('mail.mailers.smtp.scheme', match (Settings::get('mail_smtp_encryption')) {
'ssl' => 'smtps',
'tls' => 'smtp',
default => null,
});
}
if ($address = Settings::get('mail_from_address')) {
Config::set('mail.from.address', $address);
Config::set('mail.from.name', Settings::get('mail_from_name') ?: Settings::get('company_name'));
}
}
/**
* Let the Admin -> Konfiguracja -> "Czas wygaśnięcia sesji" field override
* the .env-based session lifetime. Only affects sessions created/renewed
* after the change already-active sessions keep their existing expiry.
*/
protected function applySessionSettingsOverride(): void
{
if (! $this->settingsTableUsable()) {
return;
}
$minutes = Settings::get('session_lifetime_minutes');
if ($minutes) {
Config::set('session.lifetime', (int) $minutes);
}
}
/**
* Let the Admin -> Konfiguracja -> "Strefa czasowa" field override the
* .env-based app timezone at runtime, so every date shown or stored
* (ticket timestamps, SLA deadlines, "x minutes ago" labels, ...)
* reflects the admin's chosen zone instead of the container's UTC default.
*/
protected function applyTimezoneSettingsOverride(): void
{
if (! $this->settingsTableUsable()) {
return;
}
$timezone = Settings::timezone();
Config::set('app.timezone', $timezone);
date_default_timezone_set($timezone);
}
}