mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-17 13:05:32 +09:00
feat(media-proxy): sign attachment URLs and gate origins (#2830)
This commit is contained in:
1 parent
025c01ab13
commit
522cf08e61
108 files changed
+10148
-441
No files matched your search
@@ -144,6 +144,9 @@ function defaultConfig(): MasterConfig {
|
||||
token_ttl_secs: 900,
|
||||
keep_direct_countries: [],
|
||||
},
|
||||
attachment_urls: {
|
||||
secrets_base64: [],
|
||||
},
|
||||
},
|
||||
gateway: {
|
||||
port: 8771,
|
||||
@@ -354,6 +357,28 @@ function validateUploadRelaySecret(value: string, mode: string): void {
|
||||
}
|
||||
}
|
||||
|
||||
function isCanonicalStandardBase64(value: string): boolean {
|
||||
if (!/^[A-Za-z0-9+/]+={0,2}$/u.test(value)) {
|
||||
return false;
|
||||
}
|
||||
return Buffer.from(value, 'base64').toString('base64') === value;
|
||||
}
|
||||
|
||||
function validateAttachmentUrlSecrets(values: Array<string>): void {
|
||||
for (const value of values) {
|
||||
const trimmed = value.trim();
|
||||
if (trimmed.length === 0) {
|
||||
continue;
|
||||
}
|
||||
if (!isCanonicalStandardBase64(trimmed)) {
|
||||
throw new Error('FLUXER_MEDIA_PROXY_ATTACHMENT_URL_SECRETS_BASE64 entries must be standard base64');
|
||||
}
|
||||
if (Buffer.from(trimmed, 'base64').length < 32) {
|
||||
throw new Error('FLUXER_MEDIA_PROXY_ATTACHMENT_URL_SECRETS_BASE64 entries must decode to at least 32 bytes');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function assertBoolean(value: unknown, envName: string): asserts value is boolean {
|
||||
if (typeof value !== 'boolean') {
|
||||
throw new Error(`${envName} must be true or false`);
|
||||
@@ -575,6 +600,7 @@ function normalizeConfig(config: MasterConfig): MasterConfig {
|
||||
requireString(config.s3?.secret_access_key, 'FLUXER_S3_SECRET_ACCESS_KEY');
|
||||
requireString(config.services.media_proxy.secret_key, 'FLUXER_MEDIA_PROXY_SECRET_KEY');
|
||||
validateUploadRelaySecret(config.services.media_proxy.upload_relay.secret_base64, config.services.media_proxy.mode);
|
||||
validateAttachmentUrlSecrets(config.services.media_proxy.attachment_urls.secrets_base64);
|
||||
requireString(config.services.admin.secret_key_base, 'FLUXER_ADMIN_SECRET_KEY_BASE');
|
||||
requireString(config.services.admin.oauth_client_secret, 'FLUXER_ADMIN_OAUTH_CLIENT_SECRET');
|
||||
requireString(config.services.gateway.rpc_auth_token, 'FLUXER_GATEWAY_RPC_AUTH_TOKEN');
|
||||
|
||||
@@ -152,6 +152,9 @@ export interface MasterConfig {
|
||||
token_ttl_secs: number;
|
||||
keep_direct_countries: Array<string>;
|
||||
};
|
||||
attachment_urls: {
|
||||
secrets_base64: Array<string>;
|
||||
};
|
||||
};
|
||||
gateway: {
|
||||
port: number;
|
||||
|
||||
@@ -172,6 +172,10 @@ const NAMED_FLUXER_ENV_OVERRIDES: Record<string, NamedEnvOverride> = {
|
||||
path: ['services', 'media_proxy', 'upload_relay', 'keep_direct_countries'],
|
||||
parse: parseCsv,
|
||||
},
|
||||
FLUXER_MEDIA_PROXY_ATTACHMENT_URL_SECRETS_BASE64: {
|
||||
path: ['services', 'media_proxy', 'attachment_urls', 'secrets_base64'],
|
||||
parse: parseCsv,
|
||||
},
|
||||
FLUXER_ADMIN_PORT: {path: ['services', 'admin', 'port'], parse: parseInteger},
|
||||
FLUXER_ADMIN_BASE_PATH: {path: ['services', 'admin', 'base_path']},
|
||||
FLUXER_ADMIN_SECRET_KEY_BASE: {path: ['services', 'admin', 'secret_key_base']},
|
||||
|
||||
Reference in new issue
Block a user