127 lines
4.5 KiB
PHP
127 lines
4.5 KiB
PHP
<?php
|
||
|
||
namespace App\Console\Commands;
|
||
|
||
use Illuminate\Console\Command;
|
||
|
||
class MigrateEnvReverb extends Command
|
||
{
|
||
protected $signature = 'mailwolt:migrate-env-reverb';
|
||
protected $description = 'Migriert veraltete REVERB_* .env-Werte auf Domain-Basis';
|
||
|
||
public function handle(): int
|
||
{
|
||
$env = base_path('.env');
|
||
if (!file_exists($env)) {
|
||
$this->warn('.env nicht gefunden.');
|
||
return self::SUCCESS;
|
||
}
|
||
|
||
$content = file_get_contents($env);
|
||
|
||
// APP_HOST ermitteln: .env → APP_URL → DB-Setting ui_domain
|
||
$appHost = $this->extractVar($content, 'APP_HOST');
|
||
if (!$appHost || preg_match('/^\d+\.\d+\.\d+\.\d+$/', $appHost)) {
|
||
$appUrl = $this->extractVar($content, 'APP_URL');
|
||
$appHost = parse_url($appUrl ?: '', PHP_URL_HOST) ?: '';
|
||
}
|
||
if (!$appHost || preg_match('/^\d+\.\d+\.\d+\.\d+$/', $appHost)) {
|
||
try {
|
||
$appHost = (string) \App\Models\Setting::get('ui_domain', '');
|
||
} catch (\Throwable) {
|
||
$appHost = '';
|
||
}
|
||
}
|
||
|
||
if (!$appHost || preg_match('/^\d+\.\d+\.\d+\.\d+$/', $appHost)) {
|
||
$this->warn('Kein gültiger Hostname gefunden – Migration übersprungen.');
|
||
return self::SUCCESS;
|
||
}
|
||
|
||
$scheme = $this->detectScheme($appHost, $content);
|
||
$correctPort = $scheme === 'https' ? '443' : '80';
|
||
$viteHost = $this->extractVar($content, 'VITE_REVERB_HOST');
|
||
$currentPort = $this->extractVar($content, 'REVERB_PORT');
|
||
|
||
$hostOk = ($viteHost === '${REVERB_HOST}' || $viteHost === $appHost);
|
||
$portOk = ($currentPort === $correctPort);
|
||
|
||
if ($hostOk && $portOk) {
|
||
$this->info('REVERB-Werte bereits korrekt.');
|
||
return self::SUCCESS;
|
||
}
|
||
|
||
$port = $correctPort;
|
||
|
||
$fixes = [
|
||
'REVERB_HOST' => '${APP_HOST}',
|
||
'REVERB_PORT' => $port,
|
||
'REVERB_SCHEME' => $scheme,
|
||
'REVERB_PATH' => '/ws',
|
||
'REVERB_SERVER_HOST' => '127.0.0.1',
|
||
'REVERB_SERVER_PORT' => '8080',
|
||
'REVERB_SERVER_SCHEME' => 'http',
|
||
'REVERB_SERVER_PATH' => '',
|
||
'VITE_REVERB_HOST' => '${REVERB_HOST}',
|
||
'VITE_REVERB_PORT' => '${REVERB_PORT}',
|
||
'VITE_REVERB_SCHEME' => '${REVERB_SCHEME}',
|
||
'VITE_REVERB_PATH' => '${REVERB_PATH}',
|
||
];
|
||
|
||
foreach ($fixes as $key => $val) {
|
||
if (preg_match("/^{$key}=/m", $content)) {
|
||
$content = preg_replace("/^{$key}=.*/m", "{$key}={$val}", $content);
|
||
} else {
|
||
$content .= "\n{$key}={$val}";
|
||
}
|
||
}
|
||
|
||
// APP_HOST setzen falls fehlend
|
||
if (!$this->extractVar($content, 'APP_HOST')) {
|
||
$content .= "\nAPP_HOST={$appHost}";
|
||
}
|
||
|
||
file_put_contents($env, $content);
|
||
$this->info("REVERB .env migriert für Host: {$appHost}");
|
||
|
||
// Assets neu bauen damit wsHost korrekt eingebacken wird
|
||
$buildLog = base_path('../mailwolt-frontend-build.log');
|
||
exec('cd ' . escapeshellarg(base_path()) . ' && npm run build --silent 2>/dev/null', $out, $rc);
|
||
if ($rc !== 0) {
|
||
$this->warn('npm run build fehlgeschlagen – bitte manuell ausführen.');
|
||
} else {
|
||
$this->info('Assets neu gebaut.');
|
||
}
|
||
|
||
return self::SUCCESS;
|
||
}
|
||
|
||
private function detectScheme(string $host, string $envContent): string
|
||
{
|
||
// 1. APP_URL in .env bereits https?
|
||
$appUrl = $this->extractVar($envContent, 'APP_URL');
|
||
if (str_starts_with($appUrl, 'https://')) return 'https';
|
||
|
||
// 2. nginx-Konfiguration prüfen (world-readable)
|
||
foreach (glob('/etc/nginx/sites-enabled/*') ?: [] as $f) {
|
||
$c = @file_get_contents($f) ?: '';
|
||
if (str_contains($c, $host) && str_contains($c, 'ssl_certificate')) return 'https';
|
||
}
|
||
|
||
// 3. letsencrypt-Pfade (falls doch lesbar)
|
||
if (file_exists("/etc/letsencrypt/renewal/{$host}.conf")
|
||
|| is_dir("/etc/letsencrypt/live/{$host}")
|
||
|| file_exists("/etc/letsencrypt/live/{$host}/fullchain.pem")) {
|
||
return 'https';
|
||
}
|
||
|
||
return 'http';
|
||
}
|
||
|
||
private function extractVar(string $content, string $key): string
|
||
{
|
||
preg_match("/^{$key}=(.*)$/m", $content, $m);
|
||
return trim($m[1] ?? '', " \t\"'");
|
||
}
|
||
}
|