mirror of
https://github.com/DorkSquadRR/DorkNet.git
synced 2026-10-25 23:18:44 -07:00
feat: Enhance domain configuration to support hyphen subdomains and update related methods
This commit is contained in:
@@ -12,14 +12,22 @@ public sealed class DomainConfig
|
||||
{
|
||||
public string Apex { get; }
|
||||
public string Scheme { get; }
|
||||
public string HostStyle { get; }
|
||||
public bool UsesHyphenSubdomains => HostStyle == "hyphen";
|
||||
|
||||
public DomainConfig(string apex, string scheme = "https")
|
||||
public DomainConfig(string apex, string scheme = "https", string hostStyle = "dot")
|
||||
{
|
||||
Apex = apex;
|
||||
Scheme = NormalizeScheme(scheme);
|
||||
HostStyle = NormalizeHostStyle(hostStyle);
|
||||
}
|
||||
|
||||
public string Sub(string prefix)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(prefix)) return Apex;
|
||||
return UsesHyphenSubdomains ? $"{prefix}-{Apex}" : $"{prefix}.{Apex}";
|
||||
}
|
||||
|
||||
public string Sub(string prefix) => $"{prefix}.{Apex}";
|
||||
public string Url(string prefix, string path = "")
|
||||
{
|
||||
var host = string.IsNullOrEmpty(prefix) ? Apex : Sub(prefix);
|
||||
@@ -28,11 +36,18 @@ public sealed class DomainConfig
|
||||
}
|
||||
|
||||
public static bool MatchesSubdomain(string host, string prefix)
|
||||
=> host.StartsWith(prefix + ".", StringComparison.OrdinalIgnoreCase);
|
||||
=> host.StartsWith(prefix + ".", StringComparison.OrdinalIgnoreCase)
|
||||
|| host.StartsWith(prefix + "-", StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
private static string NormalizeScheme(string? value)
|
||||
{
|
||||
var scheme = string.IsNullOrWhiteSpace(value) ? "https" : value.Trim().TrimEnd(':', '/', '\\').ToLowerInvariant();
|
||||
return scheme is "http" or "https" ? scheme : "https";
|
||||
}
|
||||
|
||||
private static string NormalizeHostStyle(string? value)
|
||||
{
|
||||
var style = string.IsNullOrWhiteSpace(value) ? "dot" : value.Trim().ToLowerInvariant();
|
||||
return style is "hyphen" or "dash" or "flat" ? "hyphen" : "dot";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ public static class MiddlewarePipelineExtensions
|
||||
// Public-facing site at the apex (e.g. localhost + www variant).
|
||||
// React-router routes are client-side so spaFallback must be true.
|
||||
app.MountStaticHost(domainCfg.Apex, "site", spaFallback: true);
|
||||
app.MountStaticHost($"www.{domainCfg.Apex}", "site", spaFallback: true);
|
||||
app.MountStaticHost(domainCfg.Sub("www"), "site", spaFallback: true);
|
||||
// Old feed.* subdomain kept as legacy; new visitors land on the apex.
|
||||
app.MountStaticHost(domainCfg.Sub("feed"), "feed");
|
||||
|
||||
|
||||
@@ -115,7 +115,23 @@ public static class ServiceCollectionExtensions
|
||||
?? Environment.GetEnvironmentVariable("DORKNET_DOMAIN")
|
||||
?? "localhost";
|
||||
var scheme = builder.Configuration["Domain:Scheme"] ?? "https";
|
||||
var allowedHosts = new List<string> { apex, $"*.{apex}", "localhost", "127.0.0.1" };
|
||||
var hostStyle =
|
||||
builder.Configuration["Domain:HostStyle"]
|
||||
?? Environment.GetEnvironmentVariable("DORKNET_DOMAIN_STYLE")
|
||||
?? "dot";
|
||||
var domain = new DomainConfig(apex, scheme, hostStyle);
|
||||
var allowedHosts = new List<string> { apex, "localhost", "127.0.0.1" };
|
||||
if (domain.UsesHyphenSubdomains)
|
||||
{
|
||||
allowedHosts.AddRange(KnownServiceSubdomains
|
||||
.Where(s => !string.IsNullOrWhiteSpace(s))
|
||||
.Select(domain.Sub));
|
||||
allowedHosts.Add(domain.Sub("www"));
|
||||
}
|
||||
else
|
||||
{
|
||||
allowedHosts.Add($"*.{apex}");
|
||||
}
|
||||
var bootstrapApex = builder.Configuration["Domain:BootstrapApex"];
|
||||
if (!string.IsNullOrWhiteSpace(bootstrapApex))
|
||||
{
|
||||
@@ -123,16 +139,57 @@ public static class ServiceCollectionExtensions
|
||||
allowedHosts.Add($"*.{bootstrapApex}");
|
||||
}
|
||||
|
||||
builder.Services.AddSingleton(new DomainConfig(apex, scheme));
|
||||
builder.Services.AddSingleton(domain);
|
||||
builder.Services.Configure<Microsoft.AspNetCore.HostFiltering.HostFilteringOptions>(opt =>
|
||||
{
|
||||
opt.AllowedHosts = allowedHosts.Distinct(StringComparer.OrdinalIgnoreCase).ToArray();
|
||||
opt.AllowEmptyHosts = true;
|
||||
opt.IncludeFailureMessage = true;
|
||||
});
|
||||
Console.WriteLine($"[domain] apex={apex}, allowedHosts=[{string.Join(", ", allowedHosts)}]");
|
||||
Console.WriteLine($"[domain] apex={apex}, style={domain.HostStyle}, allowedHosts=[{string.Join(", ", allowedHosts)}]");
|
||||
}
|
||||
|
||||
private static readonly string[] KnownServiceSubdomains =
|
||||
{
|
||||
"admin",
|
||||
"api",
|
||||
"accounts",
|
||||
"auth",
|
||||
"bugreporting",
|
||||
"cards",
|
||||
"cdn",
|
||||
"chat",
|
||||
"clubs",
|
||||
"cms",
|
||||
"commerce",
|
||||
"data",
|
||||
"datacollection",
|
||||
"discovery",
|
||||
"econ",
|
||||
"feed",
|
||||
"gamelogs",
|
||||
"geo",
|
||||
"img",
|
||||
"leaderboard",
|
||||
"link",
|
||||
"lists",
|
||||
"match",
|
||||
"moderation",
|
||||
"notify",
|
||||
"ns",
|
||||
"platformnotifications",
|
||||
"playersettings",
|
||||
"roomcomments",
|
||||
"roomieintegrations",
|
||||
"rooms",
|
||||
"storage",
|
||||
"strings",
|
||||
"strings-cdn",
|
||||
"studio",
|
||||
"thorn",
|
||||
"videos",
|
||||
};
|
||||
|
||||
// ── Services ──────────────────────────────────────────────────────────────
|
||||
private static void AddCoreServices(IServiceCollection services)
|
||||
{
|
||||
|
||||
@@ -54,11 +54,18 @@ export function adminApex(): string {
|
||||
|
||||
const host = window.location.hostname.toLowerCase();
|
||||
if (host === 'localhost' || host.endsWith('.localhost')) return 'localhost';
|
||||
if (host.endsWith('-dev.dork.sh')) return 'dev.dork.sh';
|
||||
|
||||
const parts = host.split('.');
|
||||
return parts.length > 2 ? parts.slice(1).join('.') : host;
|
||||
}
|
||||
|
||||
function serviceHost(subdomain: string, apex: string): string {
|
||||
return apex === 'dev.dork.sh'
|
||||
? `${subdomain}-${apex}`
|
||||
: `${subdomain}.${apex}`;
|
||||
}
|
||||
|
||||
function subdomainUrl(subdomain: string, path: string | null | undefined, query?: string, preserveSlashes = false): string | null {
|
||||
if (!path) return null;
|
||||
const apex = adminApex();
|
||||
@@ -67,7 +74,7 @@ function subdomainUrl(subdomain: string, path: string | null | undefined, query?
|
||||
const encodedPath = preserveSlashes
|
||||
? path.split('/').map(encodeURIComponent).join('/')
|
||||
: encodeURIComponent(path);
|
||||
return `${scheme}://${subdomain}.${apex}/${encodedPath}${suffix}`;
|
||||
return `${scheme}://${serviceHost(subdomain, apex)}/${encodedPath}${suffix}`;
|
||||
}
|
||||
|
||||
export interface Room {
|
||||
|
||||
Reference in New Issue
Block a user