There was no packaging target anywhere, no artifact, and no `key` in
`manifest/chrome.json` — so an unpacked Chrome load derived its extension
id, and therefore its `chrome.storage.local` partition, from the absolute
checkout path. Moving or re-cloning the checkout presented an empty
wallet, with no error and nothing in the UI to say so.
`manifest/chrome.json` now carries a fixed `key`: the public half of an
RSA keypair, which pins the extension id to
`gipbhkogfopeahplcjhipkgpcimdpkip`. The private half is a credential and
is not in this repo; no target generates one into the working tree, and
`tests/extensionId.test.js` fails if a `.pem` is ever committed. Changing
`key` changes the id and orphans every wallet stored under the old one.
`make package` (script/package) runs `make build` — the only audited path
to a release build — and writes one self-contained, versioned archive per
browser into `release/`, plus `SHA256SUMS`. The archives are deterministic:
entries sorted, timestamps fixed, compression level fixed, so two builds
of one commit are byte-identical. Self-containment is checked rather than
assumed: every path the manifests and the popup HTML reference is resolved
and required to be inside the archive, a reference that climbs out of the
extension root is a hard failure, and files left at the `dist/` root —
`dist/styles.css`, which build.js copies into each browser directory — are
reported as deliberately not shipped rather than dropped by a glob. The
archive is then read back off disk and compared member by member against
the directory it was built from. The zip writer and reader are stdlib zlib
in `script/lib/zip.js`; no new dependency, and nothing unpinned.
One version, enforced rather than generated. `script/lib/version.js`
requires `package.json`, `manifest/chrome.json` and `manifest/firefox.json`
to agree and fails the build naming each file and what it said, instead of
reading from one of the three. `BUILD_COMMIT` now carries `-dirty` when the
working tree does not match `HEAD`, and `-unknown` when git cannot say;
the full hash behind the About screen's commit link stays clean so the link
still resolves.
Two real-browser observations, both run through the pinned harnesses:
- `tests/e2e/storagePartition.js` loads the build from two different paths
in one Chrome profile. With `key`: same id, and the second load reads the
first load's storage. Without `key`: different ids, and the second load
sees an empty partition. Loading both keyed copies at once yields one id,
not two.
- `tests/e2e/firefox/reinstall.js` installs the packaged XPI in a real
Firefox, creates a wallet, quits the browser, restarts on the same
profile, adds the add-on again, and decrypts the vault back to the
original recovery phrase. It then observes that an explicit uninstall
DESTROYS that storage — correct browser behaviour, but for a wallet it
means Remove is irreversible except from the recovery phrase, so
README.md says so.
Firefox ships an UNSIGNED XPI. README.md states plainly that release
Firefox and ESR will refuse it, that Developer Edition, Nightly or an
Unbranded build is required, and that a temporary add-on does not survive
a browser restart. AMO signing, CRX packing, tagging and any upload are
deliberately out of scope.
## Summary
Add a new well at the bottom of the settings view displaying application info (license, author, version, build date, git commit hash linked to Gitea), and an easter egg that reveals a debug mode toggle after clicking the version number 10 times.
## Changes
- **`src/popup/index.html`**: Added About well with license, author, version, build date, and linked commit hash. Added hidden debug well with debug mode toggle.
- **`src/popup/views/settings.js`**: Populate About well from build-time constants. Implement version click counter (10 clicks reveals debug well). Wire up debug mode toggle to state and runtime logger.
- **`src/shared/buildInfo.js`** (new): Module exporting build-time constants (`BUILD_VERSION`, `BUILD_LICENSE`, `BUILD_AUTHOR`, `BUILD_COMMIT`, `BUILD_DATE`, `GITEA_COMMIT_URL`) injected by esbuild define.
- **`build.js`**: Read git commit hash (short + full) and version from package.json, pass as esbuild `define` constants. Also reads `GIT_COMMIT_SHORT`/`GIT_COMMIT_FULL` env vars for Docker builds.
- **`Dockerfile`**: Accept `GIT_COMMIT_SHORT` and `GIT_COMMIT_FULL` build args, set as env vars for the build step.
- **`Makefile`**: Pass git commit hashes as Docker build args.
- **`src/shared/state.js`**: Add `debugMode` boolean to state (persisted).
- **`src/shared/log.js`**: Add runtime debug flag that supplements the compile-time `DEBUG` constant. Debug mode toggle updates this flag immediately.
closes#144
Co-authored-by: clawbot <clawbot@noreply.git.eeqj.de>
Co-authored-by: clawbot <clawbot@sneak.cloud>
Co-authored-by: user <user@Mac.lan guest wan>
Co-authored-by: clawbot <clawbot@eeqj.de>
Co-authored-by: sneak <sneak@sneak.berlin>
Reviewed-on: #145
Co-authored-by: clawbot <clawbot@noreply.example.org>
Co-committed-by: clawbot <clawbot@noreply.example.org>
Makefile, Dockerfile, CI workflow, prettier config, manifests for
Chrome (MV3) and Firefox (MV2), source directory structure, and
minimal test suite. All checks pass.