Framework-independent Dropbox webhook verification and notification decoding.
Notifications contain account IDs, not file changes. Enqueue those IDs and
use each account's client and saved cursor with Magpie.Storage.continue_list/3.
Respond promptly; serialize workers per account and apply pages idempotently.
This module provides no persistence, queue, deduplication or replay protection.
See the incremental and webhook guide.
Summary
Functions
Returns {:ok, %{status: 200, headers: headers, body: challenge}} for a
non-empty binary challenge, otherwise {:error, :invalid_challenge}.
Headers are content-type: text/plain and x-content-type-options: nosniff.
Echo the decoded query value as plain text without HTML interpolation.
Validates the signature before decoding JSON; returns {:ok, [account_id]},
{:ok, :ignored}, {:error, :invalid_signature} or
{:error, :invalid_payload}.
Checks the hexadecimal X-Dropbox-Signature using HMAC-SHA256 over original binary body bytes and the app secret. Compares equal-sized digests in constant time. Returns false for absent, malformed or invalid signatures/arguments. Never encode parsed JSON to reconstruct the signed body.
Functions
Returns {:ok, %{status: 200, headers: headers, body: challenge}} for a
non-empty binary challenge, otherwise {:error, :invalid_challenge}.
Headers are content-type: text/plain and x-content-type-options: nosniff.
Echo the decoded query value as plain text without HTML interpolation.
@spec notification(binary(), term(), binary()) :: {:ok, [binary()] | :ignored} | {:error, :invalid_signature | :invalid_payload}
Validates the signature before decoding JSON; returns {:ok, [account_id]},
{:ok, :ignored}, {:error, :invalid_signature} or
{:error, :invalid_payload}.
A signed JSON object without list_folder is an unsupported notification:
return {:ok, :ignored} so the endpoint can acknowledge it without enqueueing
accounts. Consumers may observe this result to detect formats they don't handle.
This acknowledges receipt, not support for Business/team notifications.
When list_folder is present, accounts must be a list of non-empty binary
IDs. Malformed JSON, non-object JSON and malformed recognized notifications
return :invalid_payload. Empty lists are valid; order and repeated IDs are
preserved. Extra fields, including legacy delta, are ignored.
Checks the hexadecimal X-Dropbox-Signature using HMAC-SHA256 over original binary body bytes and the app secret. Compares equal-sized digests in constant time. Returns false for absent, malformed or invalid signatures/arguments. Never encode parsed JSON to reconstruct the signed body.