feat(web): prepare the fluxer.com domain migration (#2952)

This commit is contained in:
Hampus authored and GitHub committed 2026-09-25 13:43:34 +02:00
1 parent e62ae77643
commit 6730a242db
223 files changed
+13412 -2669

No files matched your search

+19
View File
@@ -19,6 +19,8 @@ const DEFAULT_PASSKEY_ORIGINS = [
'https://fluxer.app',
'https://web.fluxer.app',
'https://web.canary.fluxer.app',
'https://fluxer.com',
'https://canary.fluxer.com',
'android:apk-key-hash:keSY4bimyLqZQV7bKXgpa2xYuqXi0qZJzsYtp6gpx7w',
];
@@ -106,6 +108,7 @@ function defaultConfig(): MasterConfig {
presigned_attachment_uploads_enabled: false,
presigned_harvest_downloads_enabled: true,
unfurl_ignored_hosts: [],
app_origin_aliases: [],
embeds: {
oembed_html_enabled: false,
oembed_html_allow_untrusted_on_self_hosted: false,
@@ -491,6 +494,21 @@ function validateStorageChangeFeedConfig(config: MasterConfig): void {
}
}
function normalizeAppOriginAliases(config: MasterConfig): void {
const api = config.services.api;
api.app_origin_aliases = [
...new Set(
api.app_origin_aliases.map((alias, index) => {
const origin = parseWebOrigin(alias);
if (!origin) {
throw new Error(`FLUXER_APP_ORIGIN_ALIASES entry ${index + 1} must be an HTTP(S) origin`);
}
return origin.origin;
}),
),
];
}
function validateCachePurgeConfig(config: MasterConfig): void {
const cachePurge = config.integrations.cache_purge;
if (cachePurge.adapter !== 'http') {
@@ -582,6 +600,7 @@ function normalizeConfig(config: MasterConfig): MasterConfig {
validateApiWorkerConfig(config);
validateStorageChangeFeedConfig(config);
validateCachePurgeConfig(config);
normalizeAppOriginAliases(config);
assertIntegerInRange(config.services.api.max_inflight_requests, 'FLUXER_API_MAX_INFLIGHT_REQUESTS', 1, 100_000);
assertIntegerInRange(config.services.api.headers_timeout_ms, 'FLUXER_API_HEADERS_TIMEOUT_MS', 1_000, 3_600_000);
assertIntegerInRange(config.services.api.request_timeout_ms, 'FLUXER_API_REQUEST_TIMEOUT_MS', 1_000, 3_600_000);
+1
View File
@@ -94,6 +94,7 @@ export interface MasterConfig {
presigned_attachment_uploads_enabled: boolean;
presigned_harvest_downloads_enabled: boolean;
unfurl_ignored_hosts: Array<string>;
app_origin_aliases: Array<string>;
embeds: {
oembed_html_enabled: boolean;
oembed_html_allow_untrusted_on_self_hosted: boolean;
@@ -209,11 +209,40 @@ describe('ConfigLoader', () => {
'https://fluxer.app',
'https://web.fluxer.app',
'https://web.canary.fluxer.app',
'https://fluxer.com',
'https://canary.fluxer.com',
'android:apk-key-hash:keSY4bimyLqZQV7bKXgpa2xYuqXi0qZJzsYtp6gpx7w',
'http://localhost:8088',
]);
});
test('defaults to no app origin aliases', async () => {
stubMinimalEnv();
const config = await loadConfig();
expect(config.services.api.app_origin_aliases).toEqual([]);
});
test('normalizes and deduplicates app origin aliases', async () => {
stubMinimalEnv({
FLUXER_APP_ORIGIN_ALIASES:
'https://Web.Fluxer.App/, https://fluxer.com,https://fluxer.com:443,http://localhost:3000',
});
const config = await loadConfig();
expect(config.services.api.app_origin_aliases).toEqual([
'https://web.fluxer.app',
'https://fluxer.com',
'http://localhost:3000',
]);
});
test.each(['fluxer.com', 'https://fluxer.com/app', 'ftp://fluxer.com', 'https://[email protected]'])(
'rejects the app origin alias %s',
async (alias) => {
stubMinimalEnv({FLUXER_APP_ORIGIN_ALIASES: alias});
await expect(loadConfig()).rejects.toThrow('FLUXER_APP_ORIGIN_ALIASES entry 1 must be an HTTP(S) origin');
},
);
test('rejects an empty client API endpoint override', async () => {
stubMinimalEnv({FLUXER_API_CLIENT_ENDPOINT: ''});
await expect(loadConfig()).rejects.toThrow('FLUXER_API_CLIENT_ENDPOINT is required');
@@ -107,6 +107,7 @@ const NAMED_FLUXER_ENV_OVERRIDES: Record<string, NamedEnvOverride> = {
parse: parseCsv,
},
FLUXER_API_UNFURL_IGNORED_HOSTS: {path: ['services', 'api', 'unfurl_ignored_hosts'], parse: parseCsv},
FLUXER_APP_ORIGIN_ALIASES: {path: ['services', 'api', 'app_origin_aliases'], parse: parseCsv},
FLUXER_API_EMBEDS_OEMBED_HTML_ENABLED: {
path: ['services', 'api', 'embeds', 'oembed_html_enabled'],
parse: parseBoolean,