• DcRouter v32.0.0
    Release / build-and-release (push) Successful in 14m49s
    Stable

    jkunz released this 2026-09-18 13:13:05 +00:00 | 87 commits to main since this release

    2026-09-18 - 32.0.0

    Breaking Changes

    • require @serve.zone/interfaces 32.0.0 (deps)
      • Move the dependency from the exact 30.14.0 to ^32.0.0; dcrouter no longer builds or runs against interfaces 31.x and below. The repository version jumps 20.2.0 to 32.0.0: the serve.zone platform repositories share one major from 32 on, and the installed interfaces release is the contract version.
      • The gateway-client, mail, Web Push and CoreMail gateway contracts dcrouter serves are byte-identical in interfaces 32.0.0 and carry no protocol offer, and dcrouter opens no peer session, so no handler, no caller and no wire body gains the protocol handshake with this release.
      • IWebPushNotificationPayload loses schemaVersion. dcrouter refuses a push payload that still carries it, and the payload it sends to a push service no longer contains it, so a hosted-app service worker that reads the field must stop expecting it.
      • TCoreMailCredentialVerifierFormat becomes argon2id and ICoreMailGatewayPeerDesiredState loses schemaVersion. A syncCoreMailGatewayPeer body that still states argon2id-v1 or schemaVersion is refused as an unknown key by the shared normalizer; the verification-hash bytes are unchanged.
    • reseal Web Push envelopes and drop the stored shape versions (webpush)
      • The AES-GCM associated data every Web Push envelope is sealed under loses its schemaVersion member, the envelope itself loses its version member, and WebPushSpoolDoc loses its schemaVersion field. An envelope whose member set is not exactly the sealed one is refused as malformed instead of being read with the extra member ignored.
      • The new migration step webpush-encryption-context (19.1.0 to 19.2.0) reseals every WebPushSpoolDoc subscription and payload envelope and every WebPushBindingDoc VAPID private key and credential-rotation recovery secret: decrypt under the old associated data, re-encrypt under the new one with a fresh nonce, decrypt the result again and compare the plaintext, then write the document. Whether a document still needs resealing is decided by its stored shape, never by trying to decrypt it. The walk is ordered by id and resumes from a step-owned checkpoint cursor that smartmigration clears on success.
      • The step needs DCROUTER_WEB_PUSH_MASTER_KEY_RING to hold the key each existing envelope names. With no Web Push document at all it does nothing and needs no key; with one and no key ring it refuses by name and dcrouter does not start. A spool row whose binding no longer exists is counted and left untouched, because no release can rebuild its associated data.
      • New migration step coremail-peer-verifier-format (19.2.0 to 32.0.0) rewrites CoreMailGatewayPeerDoc.credentials[].format from argon2id-v1 to argon2id, leaving the verification hash and every other member alone.
    • pin the migration ledger floor at the chain start (migrations)
      • oldestSupportedVersion is 17.7.2, and every released step below it is deleted with it. A database whose ledger is older is refused by name with LEDGER_BELOW_OLDEST_SUPPORTED_VERSION on the first ledger read — before the lock and before any write — and the operator is told to run dcrouter 20.2.0 first. 17.7.2 is the highest floor this release can carry: smartmigration requires the floor to be the chain start, and the chain has to start at or below freshInstallVersion because index-service-mail-idempotency and web-push-provider-schema are what create a fresh install's indexes.
      • The live hub's ledger is 18.9.2, comfortably above the floor, so its upgrade plans exactly as it does today and then runs the two new steps.
      • The nested chain registration is replaced by a flat one that stops at targetVersion, and the fourteen hand-written backfill-settings-after-* bridges by one backfill-settings-to-target step that repeats the safeguards the chain reached.
      • @push.rocks/smartmigration moves 1.5.0 to 1.7.0, which is where oldestSupportedVersion exists. Two of its behaviours are answered explicitly: step failures are redacted unless an errorSanitizer is configured, so dcrouter's own refusals now travel as DcRouterMigrationError and reach the operator unchanged while an unknown throw is reported as the step or phase it failed in; and a forward run() plans a reverse run when the ledger is ahead of the target, so createApplicationMigrationRunner reads the ledger first and refuses a database a newer dcrouter wrote instead of letting it be walked back.
    • publish version-tagged images only (docker)
      • Build from Dockerfile_##version## instead of Dockerfile, so tsdocker publishes dcrouter:32.0.0 and never dcrouter:latest again.
      • dcrouter:latest freezes at the 20.2.0 build. Onebox's managed dcrouter still pulls that name and keeps the frozen image until it is moved to a version pin; retiring the frozen tag is a separate registry step.
      • The image smoke test now asserts that the image carries @serve.zone/interfaces 32 beside its existing IdP SDK major assertion.
    Downloads