- Shipped
- October 19, 2026 at 3:43 AM UTC
- Author
- Kamo
- Commit
- 8eda899
VOIPService stored only the words of an inbound MMS, so nobody (person or SI) could see what was texted in. Now every inbound rail reads its media and VOIPService keeps it: - Parsers: Twilio (MediaUrlN), Telnyx (payload.media, carrier and phone-server rail), Flowroute (JSON:API included media), RingCentral (MmsAttachment parts, message-store content address on the instance's platform), JustCall (sms_info.mms), on-premise phone systems (media[]). - Credentials only to the provider's own https host, asked per hop (Twilio Basic on api.twilio.com, RingCentral Bearer on *.ringcentral.com, JustCall key:secret on *.justcall.io); never to the CDN a link redirects to. - SSRF guard: https on 443 only, no user info; the HTTP client's DNS resolver refuses any name with a **************** answer, so the address checked is the one connected to; at most 3 redirects, each re-checked; 10 MiB cap (declared and streamed); connect 5 s, read 15 s, whole fetch 60 s. - Type from the bytes: pictures, PDF, audio, video and vCards only (no SVG); a page dressed as a picture is refused. - After the text commits, never in its way: parts are recorded in their own transaction and fetched by a small pool; a one-minute sweep retries (5 attempts over ~3 h) and takes over a dead pod's claim (one conditional UPDATE decides between replicas). A carrier redelivery re-offers parts the first delivery never recorded. - Stored through **************** (imaging bucket, org dedup scope, never an unwritten dat), keyed by the dat's real extension. - Thread page: each message carries attachments {id, status, mimeType, fileName, sizeBytes, url}; GET **************** serves one (ACCESS_VOIP + the thread's own member, Range, nosniff, sandbox CSP). The list row and the lead timeline show the paperclip; the live frame says attachmentsPending. Table VOIP_MESSAGE_ATTACHMENT: **************** applied.
