From 53fb5ab638820f1be385786507d0816d806aa56f Mon Sep 17 00:00:00 2001 From: Nico Krause Date: Thu, 30 Jul 2026 11:28:42 +0200 Subject: [PATCH] chore(release): 0.4.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 0.3.1 is already on npm, so the release path needs a bump before it can publish anything. main now carries a breaking change — credentials yield the authenticator's real public key, so the derived did:key differs from 0.3.x — which pre-1.0 makes this a minor bump. Writes up the five merged PRs and folds in the entries that had accumulated under Unreleased since 0.3.1. Also hardens the publish step. setup-node with registry-url writes `_authToken=${NODE_AUTH_TOKEN}` into .npmrc; with an empty value npm can attempt token auth and fail rather than falling back to trusted publishing. The publish job drops registry-url (registry.npmjs.org is the default) and sets an auth token only when auth: token is chosen, so the OIDC path leaves no empty credential behind. Worth getting right before the first real release run rather than after it fails. Co-Authored-By: Claude Opus 5 --- .github/workflows/release.yml | 19 +++++++-- CHANGELOG.md | 79 +++++++++++++++++++++++++++++++++++ package.json | 2 +- 3 files changed, 95 insertions(+), 5 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 10069be..fae2885 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -102,11 +102,14 @@ jobs: with: version: 10 + # Deliberately no registry-url here. It makes setup-node write + # `_authToken=${NODE_AUTH_TOKEN}` into .npmrc, and an empty value can make + # npm attempt token auth and fail instead of falling back to trusted + # publishing. registry.npmjs.org is the default anyway. - uses: actions/setup-node@v6 with: node-version: '22.x' cache: 'pnpm' - registry-url: 'https://registry.npmjs.org' - name: Install dependencies run: pnpm install --frozen-lockfile @@ -116,11 +119,19 @@ jobs: - name: Use an npm that supports trusted publishing run: npm install -g npm@latest - # prepublishOnly would otherwise re-run the gate the `test` job just ran. + # --ignore-scripts: prepublishOnly would re-run the gate the `test` job + # just cleared. - name: Publish - run: npm publish --access public --provenance --ignore-scripts + run: | + if [ "${{ inputs.auth }}" = "token" ]; then + echo "authenticating with NPM_TOKEN" + npm config set //registry.npmjs.org/:_authToken "$NPM_TOKEN" + else + echo "authenticating with trusted publishing (OIDC)" + fi + npm publish --access public --provenance --ignore-scripts env: - NODE_AUTH_TOKEN: ${{ inputs.auth == 'token' && secrets.NPM_TOKEN || '' }} + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} notify: name: Report outcome diff --git a/CHANGELOG.md b/CHANGELOG.md index b95b718..8672491 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,85 @@ ## Unreleased +## 0.4.0 + +### Breaking + +- WebAuthn credentials now yield the authenticator's actual public key, so the + derived `did:key` **changes** for anyone who registered against 0.3.x or + earlier. Existing OrbitDB identities keyed on the old DID will not match, and + databases gated on it become unwritable under the new DID. `extractPublicKey()` + never took its intended path: `cbor-web` returns byte strings as views into + the enclosing buffer, so reading `credentialIdLength` through `authData.buffer` + without honouring `byteOffset` read bytes from inside `rpIdHash` and yielded + 43690 for every credential. The COSE slice was then empty, `cbor` threw + `Insufficient data`, and the `catch` silently returned a synthetic key derived + from `SHA-256(credentialId)`. + +### Fixed + +- Keep the identity document stable across reloads. `signIdentity()` reuses the + proof it already produced instead of running a fresh WebAuthn assertion, which + changed `signatures.publicKey` — and therefore the content address of the + identity document — on every page load. Peers then dropped entries: + `verifiedIdentitiesCache` in `@orbitdb/core` is keyed on the deterministic + `signatures.id`, so two documents from one keystore collide on a single cache + entry and `isEqual()` rejects whichever was not verified first. The symptom was + a database replicating some entries and silently never receiving the rest. +- Remove the `timestamp` field from the proof envelope and the 24-hour expiry + check that read it. Both were wrong for a value embedded in content-addressed, + permanent history: the timestamp changed the document hash on every call, and + the expiry would have invalidated the identity behind every entry ever signed + under it. Compatible in both directions — proofs that still carry a timestamp + verify fine, and 0.3.1 verifying a proof without one computes `NaN`, which + fails its `> maxAge` test. +- Prefer `response.getPublicKey()` (WebAuthn L2) over parsing the attestation + object, and correct the parser: honour `byteOffset`, validate the AT flag, + bounds-check `credentialIdLength`, and decode only the first CBOR item so + trailing extension data (the ED flag, set when PRF is requested) no longer + throws. The synthetic fallback is now marked `synthetic: true`. +- Fix an ambiguous locator in `ed25519-keystore-did`: `getByLabel` matches + substrings, and the demo's worker toggle is labelled + "Use worker-backed Ed25519 keystore". + +### Added + +- Two-peer OrbitDB replication tests: real libp2p over loopback TCP, Helia with + bitswap, gossipsub, two OrbitDB instances, driven by a software WebAuthn + authenticator with a real P-256 keypair, an incrementing signature counter and + randomised signatures. Covers identity-document stability across reloads, + replication of entries written before and after a reload, and that two devices + sharing a passkey keep distinct, independently valid identities. +- Attestation-parsing unit tests: credential ID lengths 16/20/32/64/128, + trailing extension data, missing AT flag, non-P-256 COSE keys and truncated + coordinates. 13 of the 14 fail against 0.3.1. + +### Changed + +- CI now runs all eleven test files. Five never ran: `webauthn-unit`, + `webauthn-verification`, `standalone-toolkit`, `ed25519-keystore-did` and + `simple-encryption-integration`. `webauthn-unit` imports through Vite's `/@fs` + endpoint, which only the dev server exposes, so its step runs against `dev` + rather than the `preview` build CI otherwise uses. +- Publishing moves into CI. A `v*` tag runs the full suite and then publishes + via npm Trusted Publishing (OIDC), with provenance. A manual run defaults to a + check mode that verifies tag/version agreement and packaging without + publishing. +- `test:ci`, which `preversion` and `prepublishOnly` run, now points at the + Node-context suites via `playwright.node.config.js` — 32 tests in about ten + seconds. It previously ran `webauthn-verification` alone: five tests that check + regexes against hardcoded DID literals and one fully mocked database object, + none of which creates a credential, touches the keystore or opens an OrbitDB. +- Restore the `security-audit`, `package-validation` and `notify` jobs. The + enforced audit gate is `--prod --audit-level=critical`; auditing the full tree + at `moderate` reports 86 advisories from the helia and libp2p dev tree, and + even `--prod` reports 5 through `iso-web > iso-kv > conf > ajv`, so both wider + audits run informational until that chain is bumped. + +### Also shipping in this release + +Entries that had accumulated under Unreleased since 0.3.1: + - Add `SECURITY.md` with vulnerability reporting and supported-version policy. - Rename `changes.md` to `CHANGELOG.md` and include it in the published package. - Add public TypeScript declarations for the root, standalone, verification, diff --git a/package.json b/package.json index add5aa6..2a4e67a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@le-space/orbitdb-identity-provider-webauthn-did", - "version": "0.3.1", + "version": "0.4.0", "description": "WebAuthn-based DID identity provider for OrbitDB for hardware-secured wallets and biometric Passkey authentication", "main": "src/index.js", "types": "types/index.d.ts",