Fix SMS config path resolution and fail-open when config missing

The config loader now searches multiple paths for sms-sites.json
(REPO_ROOT-based, /app/, and CWD-relative) so it works regardless
of deployment environment. When config can't be loaded, the auth
check fails open (allows messages through) rather than blocking
everything. The isOwnNumber check still returns false when config
is unavailable since we can't identify our own numbers without it.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Khalid A
2026-04-17 21:03:15 -05:00
parent ec92b6c7c6
commit 498d873c47
2 changed files with 45 additions and 20 deletions

View File

@@ -44,14 +44,17 @@ async function handleInbound(body: unknown, deps: WebhookSmsRouterDeps) {
}
// Check if sender is authorized for this site
// - null: config loaded, sender NOT authorized → block
// - undefined: config unavailable → allow through (fail open)
// - object: config loaded, sender authorized → allow
const site = findAuthorizedSite(from, to);
if (!site) {
if (site === null) {
logger.info({ event: 'sms.unauthorized', from: maskPhone(from), to: maskPhone(to), messageId }, 'Unauthorized sender');
return;
}
const phoneHash = hashPhone(from);
logger.info({ event: 'sms.received', from: maskPhone(from), hasMedia, messageId, siteId: site.siteId }, 'Inbound SMS');
logger.info({ event: 'sms.received', from: maskPhone(from), hasMedia, messageId, siteId: site?.siteId }, 'Inbound SMS');
// Idempotency check
if (messageId && !claimOnce(`sms:${messageId}`, 3600)) {