Skip to content

Latest commit

 

History

History
122 lines (103 loc) · 6.64 KB

README.md

File metadata and controls

122 lines (103 loc) · 6.64 KB

dmsg_connect

connect.dmsg.net, the bridge page of dmsg-connect/1: an application page opens it in a popup, and it hands the page's requests to the user's dMsg devices through the relay. It runs on its own asset canister (dmsg_connect in icp.yaml) and domain, has no login and never touches Internet Identity.

Path Role
/ Direct-visit overview: browser connection guidance, links to open or get dMsg, and this browser's connected accounts; shares the bridge page
/v1/ The bridge window: the hello from window.opener, the origin the browser reports, one nonce and proof per command, results to that origin only
/v1/pair#… The page a device opens to connect this browser to an account; the fragment is cleared as soon as it is read
/app/pair, /app/request Native app links, with a browser fallback to open dMsg or the App Store

All five pages share the restrained palette and Gate logo from the website design system, with light/dark themes, responsive layouts and visible keyboard focus. web/public/ contains the logo variants and SVG/ICO favicons; Vite copies them to the asset root. The SVGs use presentation attributes so they work with the existing CSP without inline styles or external resources.

Modules

Module Role
src/codec.ts Canonical CBOR (cborg), hex, base64 and base64url as the protocol spells them
src/crypto.ts WebCrypto P-256 (non-extractable pairing keys), ES256 COSE_Sign1, HMAC, AES-256-GCM; HPKE with native X25519 (@hpke/core): base mode to devices, auth mode from devices; non-extractable result keys
src/protocol.ts Commands, the proof and operation digests, pairing IDs and MACs, the sealing contexts, invitations and replies
src/certified.ts Certified reads under a pinned IC root: the registry's user homes, an account's devices from its home, an application's registration from commerce (checked with dmsg-sdk)
src/relay.ts The relay's /v1/connect/* routes with a Connect PoP
src/bridge.ts Pairing and grant checks, the eight methods with the §4.5 checks (dmsg-sdk validators), sealing, reply verification and pinning, recovery without a local record
src/store.ts Pairings and operations in IndexedDB dmsg-connect:<environment> (keys stay CryptoKey objects), or in memory
src/page.ts The window's frames (§4.2–§4.3), without DOM
web/ The bridge, pairing and native-link pages (shared.ts, bridge.ts, pair.ts, native.ts), plain DOM, no inline script or style

The bridge trusts only what is signed by the page's session key or certified by the IC; the relay is a mailbox. Replies open only with HPKE in auth mode under a device key from the certified set, and once a device holds an operation, only that device's replies count.

Build

The environment is inlined at build time from a JSON file, DMSG_CONNECT_CONFIG (default connect.config.json):

{
  "environment": "Production",
  "icHost": "https://icp-api.io",
  "apiOrigin": "https://<relay API origin>",
  "canisters": { "handle": "<dmsg_handle>", "commerce": "<dmsg_commerce>" },
  "domains": ["connect.dmsg.net"]
}

Staging and Production builds refuse missing or non-HTTPS values; only a Local build takes rootKey (the replica's root key DER, hex) and loopback HTTP. The build writes dist/.ic-assets.json5 with the headers of connect-v1 §2.2 (the CSP's connect-src is exactly icHost and apiOrigin, COOP unsafe-none, no COEP, frame-ancestors 'none', Referrer-Policy: no-referrer; the asset canister's own security policy is disabled so it injects nothing that conflicts) and dist/.well-known/ic-domains from domains. DMSG_CONNECT_OUT changes the output directory. The build includes dist/index.html for /; upload the rebuilt assets to make the root entry available on an existing deployment.

pnpm --dir packages/dmsg-sdk build           # the bridge imports dmsg-sdk
DMSG_CONNECT_CONFIG=connect.config.json pnpm --dir src/dmsg_connect build
pnpm --dir src/dmsg_connect serve            # dist with the canister's headers and aliases
icp deploy dmsg_connect -e ic                # uploads dist; see Release

The relay must list the page's origin as CONNECT_ORIGIN, and daemons use it as connect_url (default https://connect.dmsg.net).

Release

Every pairing browser runs whatever this canister serves, so each release records what it serves. node scripts/assets.ts manifest [dist] (or pnpm assets manifest) writes the SHA-256 of every file the canister serves, of .ic-assets.json5 (the headers), the build config and the commit, with one sha256 over the listing; two builds of one commit and config give the same manifest. No workflow publishes the bridge page now. The dmsg-connect-v* workflow (.github/workflows/dmsg-connect.yml) that built connect.production.json twice, failed unless both manifests were equal, and released dmsg-connect-assets.json with dmsg-connect-dist.tar.gz has been removed. Build the production dist by hand with DMSG_CONNECT_CONFIG set to the production config, write its manifest, deploy that dist (the canister's own approval flow), then check what the canister serves against the manifest:

pnpm --dir src/dmsg_connect assets verify dmsg-connect-assets.json acjs3-cyaaa-aaaas-qg7da-cai

verify reads the canister's asset list anonymously and fails on any missing, extra or different file. connect.production.json is committed once the relay's production origin is fixed. Before an upgrade, run the desktop browser tests against staging; to roll back, deploy the previous release's dist.

Tests

pnpm --dir src/dmsg_connect test     # connect-v1 vectors; the window's frames (DT20, DT21)
pnpm --dir src/dmsg_connect check

scripts/headless.ts runs the bridge in Node over JSON lines (it trusts the origin its driver names, so it is test-only); scripts/browser.ts drives the real pages and the test application (e2e/app) in Chromium, Firefox or WebKit through Playwright. Both are driven from tests/dmsg_integration/tests/desktop.rs: desktop_web_connect (pairing and phishing, locked devices, approval on another device, cancel and authorize races, two browsers on one operation, lost records, crashes and revocation) and desktop_browser_connect (headers, pairing, an unregistered origin, the handshake, a signature approved on a device, acknowledgement and a closed window, per browser in DMSG_TEST_BROWSERS, default chromium). Install the browsers with pnpm --dir src/dmsg_connect exec playwright install chromium firefox webkit, or point DMSG_TEST_CHROME at an installed Chrome for Testing.