vcard4reseller/backend/src/Controller/TlsCheckController.php
Thomas Peterson b8f9a50731 White-Label Phase 1: Host→Tenant-Auflösung + Branding
- Domain-Entity polymorph (Reseller ODER Firma)
- TenantResolver: Host → Plattform / reseller.portal / firma.reseller.portal
  / verifizierte Custom-Domain
- Öffentliches GET /api/branding (Name, Ebene, Farben, Logo) nach Host
- TLS-Gate nutzt TenantResolver (nur bekannte Hosts → Zertifikat)
- Frontend: Branding-Store lädt vor Mount, färbt Theme um, TenantBrand-
  Komponente (Logo/Name je Tenant), Login zeigt Tenant
- Vite-Proxy reicht Original-Host durch (lokales White-Label-Testing)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 12:58:20 +02:00

34 lines
1.1 KiB
PHP

<?php
namespace App\Controller;
use App\Service\TenantResolver;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
/**
* On-Demand-TLS-Autorisierung für Caddy (KONZEPT §11): Caddy fragt vor dem
* Ausstellen eines Let's-Encrypt-Zertifikats hier nach, ob die Domain erlaubt ist.
* Erlaubt = jeder Host, den der TenantResolver kennt (Portal-Domain, Reseller-/
* Firmen-Standard-Subdomain oder verifizierte Custom-Domain).
* 200 → ausstellen, sonst ablehnen (verhindert unbegrenzte Zertifikatsanfragen).
*/
final class TlsCheckController
{
#[Route('/internal/tls-allowed', name: 'tls_allowed', methods: ['GET'])]
public function __invoke(Request $request, TenantResolver $resolver): Response
{
$host = (string) $request->query->get('domain');
if ('' === trim($host)) {
return new Response('missing domain', 400);
}
if (null !== $resolver->resolve($host)) {
return new Response('ok', 200);
}
return new Response('not allowed', 403);
}
}