feat(bootstrap): update tenant bootstrap endpoint to accept domain and path as query parameters, enhancing tenant resolution logic
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user