Attempt forced restoration for locally missing attachments - #837
Conversation
Validation updateValidated the safe paths on SIP-enabled arm64 macOS 26.5.2 with Node 20.11.1 and npm 10.2.4.
That rejection case was not added to the committed test suite, so the review follow-up remains open. A real purged-attachment restore is also deferred to a SIP-disabled Mac with the Private API enabled and connected; that validation will perform an actual iCloud attachment download. No messages were sent or received during this validation. No screenshot is needed because the relevant evidence is the HTTP response, stream behavior, and sanitized server log. |
Remote validation follow-up for
|
Live SIP-disabled validation follow-up for
|
|
Superseding the earlier validation notes: current head Live restoration is still not a pass: a naturally purged attachment reached the forced-restoration path and Private API helper on the SIP-disabled test host, but did not restore within 10 minutes. It remained locally absent and the request returned the expected fallback |
Summary
404 Not Foundimmediately when no attachment database row existsforceDownloadonly when forcing is allowed and the Private API is enabledforce=false, disabled Private API, incomplete restoration, and a rejectedforceDownloadWhy
The regular attachment download endpoint defaults
forcetotrue, but its recovery branch was attached to the wrong condition. It ran only when the database lookup returned no attachment, even thoughAttachmentInterface.forceDownloadrequires an existing attachment object. The common case—an intact database row whose local file was purged—therefore never reached the restoration path.Behavior
For an eligible missing local file, the endpoint asks the Private API helper to restore the attachment and uses the refreshed row if a file becomes available. Unknown GUIDs remain a deterministic
404;force=falseand disabled-Private-API requests do not attempt restoration. A rejected or incomplete restoration logs safely, creates no file stream, and returns the existing clean missing-disk500.Validation
Validated on current head
58f57f95:npm run test:attachment-download --workspace @bluebubbles/server— 6/6 tests passedFileStream, and the clean500fallbackgit diff --checkpassedLive-validation limitation
This is not an end-to-end live-restoration pass. On a SIP-disabled Intel Sequoia host, a naturally purged incoming attachment reached the forced-restoration path and Private API helper, but did not restore within the 10-minute completion wait. The request returned the expected clean fallback
500; the database row remained incomplete and the local file remained absent. This validates routing and fallback behavior, not successful restoration in that environment.The broader server type-check still reaches the pre-existing unrelated
ScheduledService.ts:39NodeJS.Timer/clearIntervalerror.Fixes #749