diff --git a/src/settings-proxy/settings-proxy.service.ts b/src/settings-proxy/settings-proxy.service.ts index 54ce0e3..bc111ce 100644 --- a/src/settings-proxy/settings-proxy.service.ts +++ b/src/settings-proxy/settings-proxy.service.ts @@ -116,9 +116,10 @@ export class SettingsProxyService { } /** - * Prefer per-tenant Bearer; else same shared HMAC used by SMS remote. - * Canonical path is always /api/super/settings so product middleware can verify - * regardless of /server prefix on nodeServer. + * Auth to product: + * 1) Tenant remoteApiToken as Bearer (per-tenant) + * 2) Else SMS shared secret as Bearer (CDN-safe; same secret as SMS) + * + optional HMAC headers for non-CDN installs */ private buildAuthHeaders( tenant: { @@ -137,22 +138,28 @@ export class SettingsProxyService { const shared = String( this.config.get('SMS_REMOTE_SHARED_SECRET') || '', ).trim(); - const domain = this.resolveTenantDomain(tenant); - if (!shared || !domain) { + if (!shared) { return null; } - const timestamp = String(Math.floor(Date.now() / 1000)); - const payload = `${timestamp}.${method}.${SUPER_SETTINGS_CANONICAL_PATH}.${domain}`; - const signature = createHmac('sha256', shared) - .update(payload, 'utf8') - .digest('hex'); - - return { - 'X-Abshode-Domain': domain, - 'X-Abshode-Timestamp': timestamp, - 'X-Abshode-Signature': signature, + // Bearer with shared secret survives CDNs that strip custom X-* headers. + const headers: Record = { + Authorization: `Bearer ${shared}`, }; + + const domain = this.resolveTenantDomain(tenant); + if (domain) { + const timestamp = String(Math.floor(Date.now() / 1000)); + const payload = `${timestamp}.${method}.${SUPER_SETTINGS_CANONICAL_PATH}.${domain}`; + const signature = createHmac('sha256', shared) + .update(payload, 'utf8') + .digest('hex'); + headers['X-Abshode-Domain'] = domain; + headers['X-Abshode-Timestamp'] = timestamp; + headers['X-Abshode-Signature'] = signature; + } + + return headers; } private resolveTenantDomain(tenant: {