From 9e8d235fdf026838a7896688ae841440d313b744 Mon Sep 17 00:00:00 2001 From: Ian Clarke Date: Mon, 28 Sep 2026 09:26:07 -0500 Subject: [PATCH 1/4] feat(ghostkey): make the vault findable, and keep it off try.freenet.org The Ghost Key vault was linked only from low on /ghostkey/ and from the donation success page, both as raw localhost links that dead-end for anyone without a running peer. - /ghostkey/ hero: "Already have one? Open your vault". - /ghostkey/ vault button and the Apps page entry now go through /open, so a visitor without a peer gets "Get Freenet" instead of a dead link. The import button stays a direct localhost link: its fragment carries the signing key. - /open gains a LOCAL_ONLY list. For the vault it replaces "Use in your browser" with a note: try.freenet.org is for trying Freenet out, and a Ghost Key kept there lives on a peer we host. /ghostkey/ says the same. Tested, including a hashchange back to an ordinary id. - Success page no longer claims nothing else links to the vault. - Correct the stale IPv6-only comment in donation-success.js (freenet-core#4332 serves both loopbacks). Claude-Session: https://claude.ai/code/session_011kgp91jp3UiWjo5eHAQfyq --- hugo-site/content/apps/_index.md | 2 +- hugo-site/content/build/manual/share-links.md | 4 +- hugo-site/content/ghostkey/_index.md | 15 ++++-- hugo-site/content/ghostkey/success/_index.md | 6 +-- hugo-site/static/js/donation-success.js | 7 +-- hugo-site/tests/open-link-vectors.test.mjs | 52 +++++++++++++++++-- .../freenet/layouts/shortcodes/open-link.html | 23 +++++++- 7 files changed, 90 insertions(+), 19 deletions(-) diff --git a/hugo-site/content/apps/_index.md b/hugo-site/content/apps/_index.md index 5b010d12..a307ee76 100644 --- a/hugo-site/content/apps/_index.md +++ b/hugo-site/content/apps/_index.md @@ -91,7 +91,7 @@ Anonymous, Sybil-resistant identity certificates. Donate a small amount to mint a key; apps can verify the certificate without learning who you are. Used across Freenet apps as a spam- and abuse-resistance primitive. -→ [Get a Ghost Key](/ghostkey/) · [github.com/freenet/ghostkeys](https://github.com/freenet/ghostkeys) +→ [Get a Ghost Key](/ghostkey/) · [Open your vault](/open/#DLog47hEsrtuGT4N5XCeMBG45m4n1aWM89tBZXue2E1N/) · [github.com/freenet/ghostkeys](https://github.com/freenet/ghostkeys) ### freenet-scaffold {#freenet-scaffold} diff --git a/hugo-site/content/build/manual/share-links.md b/hugo-site/content/build/manual/share-links.md index d9da9ace..c77bc7e8 100644 --- a/hugo-site/content/build/manual/share-links.md +++ b/hugo-site/content/build/manual/share-links.md @@ -50,7 +50,9 @@ https://freenet.org/open#6FzSeAUKcqJrveKyU8RJgGKc5jRB1Z2juvxXtwTA4Em9/#store=Ab3 visitor's own local peer (`http://127.0.0.1:7509/v1/contract/web//...`), for anyone who already has Freenet installed and running. - **Use in your browser** -- the same target on `try.freenet.org`, a peer we host, for anyone who - wants to look without installing anything. + wants to look without installing anything. Apps that hold keys a visitor should keep on their own + peer, currently just the Ghost Key vault, get a note saying so instead of this button; the list is + `LOCAL_ONLY` in `open-link.html`. - **Open in Freenet** -- `freenet:/...`, which the visitor's own Freenet opens on their local peer. The handler ([freenet-core#5726](https://github.com/freenet/freenet-core/issues/5726)) ships in the first release after 0.2.139, so until peers have updated this button is styled and diff --git a/hugo-site/content/ghostkey/_index.md b/hugo-site/content/ghostkey/_index.md index 46172090..034418d4 100644 --- a/hugo-site/content/ghostkey/_index.md +++ b/hugo-site/content/ghostkey/_index.md @@ -14,6 +14,7 @@ hold a scarce, donation-backed identity, without ever learning who you are.
Get a Ghost Key

$1 minimum. Freenet Project Inc is a 501(c)(3) nonprofit.

+

Already have one? Open your vault.

## The short version @@ -206,15 +207,19 @@ new node later. ### Opening your vault -If you have a Freenet node running on this computer, your Ghost Keys are here: +Your Ghost Keys live in the vault on your own Freenet peer:
-Open your Ghost Key vault -

Requires a Freenet node running on this computer. The link will not resolve otherwise.

+Open your Ghost Key vault +

Opens the vault on the Freenet peer running on this computer, or shows you how to install one.

-That address is your own machine, not a website — the vault runs inside your node, and the page is -served locally. Bookmark it if you use Ghost Keys regularly. +The vault runs inside your peer, not on a website, so its address is on your own machine: +[`http://127.0.0.1:7509/v1/contract/web/DLog47hEsrtuGT4N5XCeMBG45m4n1aWM89tBZXue2E1N/`](http://127.0.0.1:7509/v1/contract/web/DLog47hEsrtuGT4N5XCeMBG45m4n1aWM89tBZXue2E1N/). +Bookmark it if you use Ghost Keys regularly. + +Keep your Ghost Keys on your own peer rather than on [try.freenet.org](/try/). That hosted peer is +for trying Freenet out, and a key kept there lives on a machine we run instead of yours. For developers, everything is open source: diff --git a/hugo-site/content/ghostkey/success/_index.md b/hugo-site/content/ghostkey/success/_index.md index 9d8310d6..98bd522c 100644 --- a/hugo-site/content/ghostkey/success/_index.md +++ b/hugo-site/content/ghostkey/success/_index.md @@ -30,8 +30,8 @@ from one at any time. **Your vault lives at** [localhost:7509/v1/contract/web/DLog47hEs…](http://localhost:7509/v1/contract/web/DLog47hEsrtuGT4N5XCeMBG45m4n1aWM89tBZXue2E1N/), -on this computer rather than on the web. Importing opens it for you, but the -address is worth bookmarking — it is how you reach your keys later, and nothing -else links to it. +on this computer rather than on the web. Importing opens it for you. Bookmark +the address, since it is how you reach your keys later, or find it again from +the [Ghost Key page](/ghostkey/#opening-your-vault). {{< bulma-button href="/ghostkey/" color="#339966" >}}Ghost Key FAQ{{< /bulma-button >}} diff --git a/hugo-site/static/js/donation-success.js b/hugo-site/static/js/donation-success.js index 71cf1b22..58b72674 100644 --- a/hugo-site/static/js/donation-success.js +++ b/hugo-site/static/js/donation-success.js @@ -315,9 +315,10 @@ function displayCertificate(armoredCertificate, armoredSigningKey) { const certB64 = urlSafeBase64(armoredCertificate); const skB64 = urlSafeBase64(armoredSigningKey); const contractId = 'DLog47hEsrtuGT4N5XCeMBG45m4n1aWM89tBZXue2E1N'; - // Use localhost rather than the literal 127.0.0.1: the node binds its - // API on the IPv6 loopback by default, so on Windows "localhost" (::1) - // is reachable while the literal IPv4 address is refused. + // localhost rather than the literal 127.0.0.1 dates from when the node + // served its API on the IPv6 loopback only, so Windows refused the + // IPv4 literal. Nodes serve both since freenet-core#4332; localhost + // still reaches peers older than that. // If the donor arrived from an app, hand the vault the way back so it // can offer a one-click return once the key has actually landed. // Re-validated here because it has been through a Stripe redirect; diff --git a/hugo-site/tests/open-link-vectors.test.mjs b/hugo-site/tests/open-link-vectors.test.mjs index 781f943b..f7a6c0f2 100644 --- a/hugo-site/tests/open-link-vectors.test.mjs +++ b/hugo-site/tests/open-link-vectors.test.mjs @@ -31,16 +31,23 @@ function runPage(hash) { getElementById: el, addEventListener: (ev, fn) => (listeners[ev] = fn), }; + const windowListeners = {}; const window = { location: { hash }, - addEventListener: () => {}, + addEventListener: (ev, fn) => (windowListeners[ev] = fn), }; vm.runInNewContext(match[1], { document, window }); listeners.DOMContentLoaded(); - const shown = ["open-link-missing", "open-link-invalid", "open-link-valid"].find( - (id) => el(id).style.display === "", - ); - return { shown, el }; + const shown = () => + ["open-link-missing", "open-link-invalid", "open-link-valid"].find( + (id) => el(id).style.display === "", + ); + const navigate = (newHash) => { + window.location.hash = newHash; + windowListeners.hashchange(); + return shown(); + }; + return { shown: shown(), el, navigate }; } const { vectors } = JSON.parse( @@ -70,6 +77,41 @@ for (const v of vectors) { console.error(`FAIL ${JSON.stringify(v.raw.slice(0, 80))} (${v.note}): ${problem}`); } } + +// Local-only apps (the Ghost Key vault): no try.freenet.org button, a note +// saying why instead, and the local button unaffected. Driven through a +// hashchange to an ordinary id too, since both states must be reset. +const VAULT = "DLog47hEsrtuGT4N5XCeMBG45m4n1aWM89tBZXue2E1N"; +const OTHER = "6FzSeAUKcqJrveKyU8RJgGKc5jRB1Z2juvxXtwTA4Em9"; +{ + const check = (cond, what) => { + if (!cond) { + failures++; + console.error(`FAIL local-only: ${what}`); + } + }; + const tryHidden = (el) => el("open-link-try-option").style.display === "none"; + const noteShown = (el) => + el("open-link-local-only").style.display === "" && + el("open-link-local-only").textContent.length > 0; + + const { shown, el, navigate } = runPage("#" + VAULT + "/"); + check(shown === "open-link-valid", `vault link showed ${shown}`); + check(tryHidden(el), "try option visible for the vault"); + check(noteShown(el), "no local-only note for the vault"); + check( + el("open-link-local").href === `http://127.0.0.1:7509/v1/contract/web/${VAULT}/`, + `vault local button ${el("open-link-local").href}`, + ); + + check(navigate("#" + OTHER + "/") === "open-link-valid", "other id not valid"); + check(!tryHidden(el), "try option still hidden after leaving the vault"); + check(el("open-link-local-only").style.display === "none", "note still shown after leaving the vault"); + + const fresh = runPage("#" + OTHER + "/"); + check(!tryHidden(fresh.el), "try option hidden for an ordinary id"); +} + console.log(`${vectors.length} vectors, ${failures} failures`); if (vectors.length < 40) { console.error("vector file looks truncated"); diff --git a/hugo-site/themes/freenet/layouts/shortcodes/open-link.html b/hugo-site/themes/freenet/layouts/shortcodes/open-link.html index 335e7956..5b373615 100644 --- a/hugo-site/themes/freenet/layouts/shortcodes/open-link.html +++ b/hugo-site/themes/freenet/layouts/shortcodes/open-link.html @@ -107,12 +107,13 @@

Open this link

Use this if Freenet is already installed and running on this computer.

-