feat(bootstrap): update tenant bootstrap endpoint to accept domain and path as query parameters, enhancing tenant resolution logic

This commit is contained in:
2026-08-14 15:17:24 -03:00
parent de8da72354
commit c1bfab471c
15 changed files with 344 additions and 37 deletions

View File

@@ -33,4 +33,90 @@ class TenantDomainNormalizer
return strtolower($host);
}
public static function normalizeTenantKey(mixed $domain, mixed $path = null): ?string
{
$host = self::normalize($domain);
if ($host === null) {
return null;
}
if ($path === null && is_string($domain)) {
$decodedDomain = trim(urldecode($domain));
$candidate = str_contains($decodedDomain, '://')
? $decodedDomain
: "//{$decodedDomain}";
$path = parse_url($candidate, PHP_URL_PATH) ?: '/';
}
$normalizedPath = self::normalizePath($path);
if ($normalizedPath === null) {
return null;
}
return $host.($normalizedPath === '/' ? '' : $normalizedPath);
}
public static function normalizePath(mixed $path): ?string
{
if (! is_string($path)) {
return null;
}
$path = trim($path);
if ($path === '' || $path === '/') {
return '/';
}
$path = parse_url(str_starts_with($path, '/') ? $path : "/{$path}", PHP_URL_PATH);
if (! is_string($path)) {
return null;
}
$path = preg_replace('#/+#', '/', $path);
if (! is_string($path)) {
return null;
}
$segments = array_filter(explode('/', $path), static fn (string $segment): bool => $segment !== '');
foreach ($segments as $segment) {
if ($segment === '.' || $segment === '..') {
return null;
}
}
return '/'.implode('/', $segments);
}
/** @return list<string> */
public static function tenantKeyCandidates(mixed $domain, mixed $path): array
{
$host = self::normalize($domain);
$normalizedPath = self::normalizePath($path);
if ($host === null || $normalizedPath === null) {
return [];
}
$segments = array_values(array_filter(
explode('/', $normalizedPath),
static fn (string $segment): bool => $segment !== '',
));
$candidates = [];
while ($segments !== []) {
$candidates[] = $host.'/'.implode('/', $segments);
array_pop($segments);
}
$candidates[] = $host;
return $candidates;
}
}