Files
DorkNet/DorkNet.Server/Services/ConfigService.cs
T
Alexa 46e2bb15e4 Single-origin URL rewriting; configurable SQLite path; default InjectAuthValues=false
- ClientMod: add SingleOriginBaseUrl config + URI rewrite path so the
  client can talk to one https://<apex>/__dn/<service>/... base
  instead of demanding wildcard subdomains. ServerHost rewrite still
  the fallback when SingleOriginBaseUrl is empty.
- ClientMod config: InjectAuthValues now defaults to false. The
  server's PhotonCustomAuthController already fail-opens
  (Photon:RequireCustomAuth=false), so anonymous bootstrap is the
  cleaner default and avoids Photon's CustomAuthFailed loop when a
  WAF returns 403 to Photon's probe.
- Server: SQLite path now reads Database:SqlitePath config
  (Database__SqlitePath env). Falls back to <bin>/data/dorknet.db
  so existing Docker / standalone deploys are unchanged. Lets the
  Windows launcher put the db under %APPDATA%\DorkNet.
- Server: DomainConfig + ConfigService updates for the single-origin
  apex.
- .gitignore: exclude local-releases.zip.
2026-05-28 01:39:54 +03:00

127 lines
5.2 KiB
C#

using DorkNet.Models.Config;
namespace DorkNet.Server.Services;
public class ConfigService(IConfiguration config, DomainConfig domain)
{
public RecRoomConfig GetConfig(string baseUrl)
{
var photon = new PhotonConfig
{
AppId = config["Photon:AppId"] ?? string.Empty,
VoiceAppId = config["Photon:VoiceAppId"] ?? string.Empty,
CloudRegion = config["Photon:CloudRegion"] ?? "us",
};
// baseUrl was previously parsed to mirror the request's apex
// back at the client, but with DomainConfig as the single
// source of truth every outbound URL is built off the
// configured deployment apex regardless of which Host header
// the client used to hit us. The baseUrl parameter is kept
// for API stability but is no longer dereferenced.
_ = baseUrl;
return new RecRoomConfig
{
MessageOfTheDay = config["Server:MOTD"] ?? "Welcome to the private server!",
CdnBaseUri = domain.SingleOriginEnabled
? $"{domain.SingleOriginBaseUrl}/__dn/cdn"
: domain.SubUrl("cdn"),
PhotonConfig = photon,
ServiceUrls = BuildServiceUrlMap(domain),
ConfigTable = new Dictionary<string, string>
{
// Season keys the 2019/2020 client checks at startup
["Season"] = "Spring",
["CurrentSeason"] = "Spring",
["SeasonId"] = "1",
["SeasonName"] = "Spring",
["ActiveEvent"] = "None",
["EventName"] = "",
// Feature flags — keep everything on
["FriendsEnabled"] = "true",
["ChatEnabled"] = "true",
["VoiceEnabled"] = "true",
},
};
}
/// <summary>
/// Subdomain → service-name map. The wire response wraps each
/// value with <c>https://</c> + the configured apex domain
/// (<see cref="DomainConfig"/>, driven by DORKNET_DOMAIN) so
/// every URL the client sees comes from one source of truth.
/// </summary>
private static readonly (string Service, string Subdomain)[] ServiceSubdomains = new[]
{
("WWW", ""), // apex
("API", "api"),
("Accounts", "accounts"),
("Auth", "auth"),
("BugReporting", "bugreporting"),
("Cards", "cards"),
("CDN", "cdn"),
("Chat", "chat"),
("Clubs", "clubs"),
("CMS", "cms"),
("Commerce", "commerce"),
("Data", "data"),
("DataCollection", "datacollection"),
("Discovery", "discovery"),
("Econ", "econ"),
("GameLogs", "gamelogs"),
("Geo", "geo"),
("Images", "img"),
("Leaderboard", "leaderboard"),
("Link", "link"),
("Lists", "lists"),
("Matchmaking", "match"),
("Moderation", "moderation"),
("NameServer", "ns"),
("Notifications", "notify"),
("PlatformNotifications", "platformnotifications"),
("PlayerSettings", "playersettings"),
("RoomComments", "roomcomments"),
("RoomieIntegrations", "roomieintegrations"),
("Rooms", "rooms"),
("Storage", "storage"),
("Strings", "strings"),
("StringsCDN", "strings-cdn"),
("Studio", "studio"),
("Thorn", "thorn"),
("Videos", "videos"),
};
/// <summary>Build the service URL map for a specific apex
/// domain. Used by NsController + the client config endpoints;
/// the apex is fed in by the caller (typically
/// <see cref="DomainConfig.Apex"/>) so the map stays a single
/// source of truth.</summary>
public static Dictionary<string, string> BuildServiceUrlMap(string apex)
{
var map = new Dictionary<string, string>(ServiceSubdomains.Length);
foreach (var (service, sub) in ServiceSubdomains)
{
var host = string.IsNullOrEmpty(sub) ? apex : $"{sub}.{apex}";
map[service] = $"https://{host}";
}
return map;
}
public static Dictionary<string, string> BuildServiceUrlMap(DomainConfig domain)
{
var map = new Dictionary<string, string>(ServiceSubdomains.Length);
foreach (var (service, sub) in ServiceSubdomains)
{
if (domain.SingleOriginEnabled)
{
var prefix = string.IsNullOrEmpty(sub) ? "www" : sub;
map[service] = $"{domain.SingleOriginBaseUrl}/__dn/{prefix}";
continue;
}
var host = string.IsNullOrEmpty(sub) ? domain.Apex : domain.Sub(sub);
map[service] = domain.Url(host);
}
return map;
}
}