openvibers/openvibe.connect Commits

OpenVibe Link: the new name in pages, docs and messages (#69)

OP OpenVibers committed 5 days ago · 28a7c078cd · 9 files, +21 −21

* OpenVibe Link: the new name in pages, docs and messages

OpenVibe Node is now OpenVibe Link. Pages, emails, notifications, docs, READMEs, error messages and tool descriptions say OpenVibe Link (or Link), and installer links point at openvibe.link. Code identifiers, the openvibe-node command, paths, contract ids and the repository name are unchanged.

* Migrations: keep applied files byte-identical (comments unchanged)

Changes

ddiff --git a/README.md b/README.md
iindex a99de51..34de79a 100644
---- a/README.md
++++ b/README.md
@@@ -23,14 +23,14 @@ Live at **[connect.openvibe.website](https://connect.openvibe.website)**. Part o
The client opens one outgoing connection, so it works behind any router or hotspot, and it reconnects by itself. It
only ever connects to `localhost` on the port you gave it.
--### From a computer with OpenVibe Node (no key)
++### From a computer with OpenVibe Link (no key)
--A computer you added on [openvibe.bot/machines](https://openvibe.bot/machines) runs OpenVibe Node and has its own
++A computer you added on [openvibe.bot/machines](https://openvibe.bot/machines) runs OpenVibe Link and has its own
OpenVibe sign-in. On the share's page, pick it under "Or serve it from one of your computers", then on that computer:
```bash
openvibe-node share --share shr_… # serve it now
--sudo openvibe-node share add --share shr_… # or keep it up with the Node service
++sudo openvibe-node share add --share shr_… # or keep it up with the Link service
```
There is no key to copy. The computer proves itself twice at every connection: with its Network node token (subject
@@@ -164,7 +164,7 @@ With a person's OpenVibe token as a Bearer (or the session on connect.openvibe.w
| `POST /api/v1/shares/:id/key` | a new key → `{ share, key }`; the connected computer is disconnected |
| `GET /api/v1/shares/:id/visits` | who opened it in the last 7 days |
| `GET /api/v1/shares/:id/requests` `?after=<seq>` | the last 100 requests through it, newest first (the inspector, below) |
--| `GET /api/v1/machines` | your computers that can serve a share (OpenVibe Node, from Network) |
++| `GET /api/v1/machines` | your computers that can serve a share (OpenVibe Link, from Network) |
| `PUT /api/v1/shares/:id/node` `{ node: 'nod_…' \| null }` | one of your computers serves it (the key stops working) → `{ share }`; `null` lets it go → `{ share, key }` |
A computer, with its Network node token (audience `openvibe.website`) as a Bearer:
@@@ -189,7 +189,7 @@ browser ──https──▶ Cloudflare ──▶ nginx ──▶ Connect (5240)
- `server/edge/inspector.js` — the share page's Requests list (CON-8 v0): the last 100 requests per share, in memory
only, with the method, the path (query values shown as "…"), status, time, bytes and the visitor's name. No headers,
no bodies; a restart forgets them.
--- `server/auth/node-auth.js` — a computer as OpenVibe Node: its node token, and the single-use tunnel tokens (CON-4).
++- `server/auth/node-auth.js` — a computer as OpenVibe Link: its node token, and the single-use tunnel tokens (CON-4).
- `server/machines.js` — the owner's computers, read from Network with the owner's own token.
- `server/hooks.js`, `server/http/hooks.js` — webhook addresses, the sealed kept webhooks, the 1,000-deep queue, the
delivery log and Events' deliveries (CON-15).
ddiff --git a/STATUS.json b/STATUS.json
iindex acaf05b..35abeab 100644
---- a/STATUS.json
++++ b/STATUS.json
@@@ -21,7 +21,7 @@
"The client: hello with a hashed-at-rest key, streams both ways with backpressure, SSE, WebSocket upgrades as a byte pipe, reconnect, takeover, stop on a bad key",
"The gate: /grant with OpenVibe sign-in, one-time codes, __Host-ovc bound to the share and its policy version",
"Durable webhooks (CON-15): an address on each share keeps up to 1,000 webhooks for 72 hours, sealed at rest, replays them in order with x-openvibe-received-at and a delivery log the owner can read",
-- "The OpenVibe Node plugin (CON-4): a share served by the owner's paired computer, no key, with `openvibe-node share <port>` and the share in `openvibe-node status`",
++ "The OpenVibe Link plugin (CON-4): a share served by the owner's paired computer, no key, with `openvibe-node share <port>` and the share in `openvibe-node status`",
"What the app gets: localhost Host, X-Forwarded-Host, X-OpenVibe-User/Subject; Set-Cookie Domain removed; no CDN caching",
"Pages (front door, your shares, a share's page), the API for a person's token, account export/deletion",
"Checks on PGlite and PostgreSQL, including a share end to end through the real client"
ddiff --git a/server/edge/tunnels.js b/server/edge/tunnels.js
iindex 317b26d..45aac7a 100644
---- a/server/edge/tunnels.js
++++ b/server/edge/tunnels.js
@@@ -9,7 +9,7 @@
* tunnel.open({ onRes, onData, onEnd, onAbort, onPause, onResume }) → stream id
* tunnel.send(obj), tunnel.data(id, buf), tunnel.end(id), tunnel.abort(id, code, message), tunnel.release(id)
*
-- * A computer bound to a share as OpenVibe Node (CON-4) says hello with two credentials instead of a key:
++ * A computer bound to a share as OpenVibe Link (CON-4) says hello with two credentials instead of a key:
* { t: 'hello', share: 'shr_…', node_token: <its Network node token>, tunnel: 'ovt_…' } (server/auth/node-auth.js). Its
* node token lasts 300 s, so it sends { t: 'reauth', node_token } with a fresh one before then (answered
* { t: 'reauthed', until }); a tunnel whose token ran out is closed (4000, the computer reconnects), so a computer
@@@ -164,7 +164,7 @@ function createTunnels({ shares, config, log = console, onConnect = null, nodeAu
let share;
let node = null;
if (m.key === undefined && (m.node_token !== undefined || m.tunnel !== undefined)) {
-- // A computer as OpenVibe Node (CON-4): its node token and a tunnel token, both checked.
++ // A computer as OpenVibe Link (CON-4): its node token and a tunnel token, both checked.
if (!nodeAuth) return refuse(ws, 'unavailable', 'Try again in a moment.');
const v = await nodeAuth.verify(m.node_token);
if (!v.ok) return v.status === 503 ? refuse(ws, 'unavailable', 'Try again in a moment.') : refuse(ws, 'node_invalid', 'OpenVibe did not take this computer\'s node token. Pair it with OpenVibe again.');
ddiff --git a/server/http/api.js b/server/http/api.js
iindex e0d1e8f..04e50a6 100644
---- a/server/http/api.js
++++ b/server/http/api.js
@@@ -12,7 +12,7 @@
* goes while the computer is off, one of the sites on the domain (CON-17), '' or null to clear
* DELETE /shares/:id close it (the host answers 410 from then on)
* POST /shares/:id/key a new key → { share, key }; the connected computer is disconnected
-- * PUT /shares/:id/node { node: 'nod_…' } one of your computers serves it, as OpenVibe Node (CON-4): the key
++ * PUT /shares/:id/node { node: 'nod_…' } one of your computers serves it, as OpenVibe Link (CON-4): the key
* stops working → { share }; { node: null } lets the computer go → { share, key } (a new key)
* GET /machines your computers that can serve a share (Network's list of your machines)
* GET /shares/:id/hooks its webhook addresses (CON-15): each kept webhook waits up to 72 hours for the computer
@@@ -115,7 +115,7 @@ function createApi(ctx) {
if (typeof want !== 'string') return fail(res, req, 422, 'share.invalid_node', 'Name one of your computers by its id (nod_…), or null.');
const found = await machines.find(req.principal.token, want);
if (!found.ok) return fail(res, req, 503, 'machines.unavailable', 'Your computers could not be read from OpenVibe just now. Try again in a moment.');
-- if (!found.machine) return fail(res, req, 404, 'share.unknown_node', 'That is not one of your computers. Pair it with OpenVibe Node first.');
++ if (!found.machine) return fail(res, req, 404, 'share.unknown_node', 'That is not one of your computers. Pair it with OpenVibe Link first.');
const { share: updated } = await shares.bindNode(owner(req), share.id, found.machine);
tunnels.close(share.id, 4003, 'now served by one of your computers');
return res.json({ share: shape(updated) });
ddiff --git a/server/http/node-api.js b/server/http/node-api.js
iindex 5097855..26468ae 100644
---- a/server/http/node-api.js
++++ b/server/http/node-api.js
@@@ -1,7 +1,7 @@
'use strict';
/**
-- * /api/v1/node: a person's computer, as OpenVibe Node (CON-4, ADR-057 decision 4). Every call carries the computer's
++ * /api/v1/node: a person's computer, as OpenVibe Link (CON-4, ADR-057 decision 4). Every call carries the computer's
* Network node token (Authorization: Bearer, subject node:nod_…, audience openvibe.website); nothing here answers to a
* person's token or the session.
*
ddiff --git a/server/http/pages.js b/server/http/pages.js
iindex 2c902ac..21d6326 100644
---- a/server/http/pages.js
++++ b/server/http/pages.js
@@@ -148,7 +148,7 @@ function createPageRoutes(ctx) {
}
const found = await machines.find(req.viewer.token, want);
if (!found.ok) return showShare(req, res, share, { error: 'Your computers could not be read from OpenVibe just now. Try again in a moment.' }, 503);
-- if (!found.machine) return showShare(req, res, share, { error: 'That is not one of your computers. Pair it with OpenVibe Node first.' }, 404);
++ if (!found.machine) return showShare(req, res, share, { error: 'That is not one of your computers. Pair it with OpenVibe Link first.' }, 404);
const { share: updated } = await shares.bindNode(owner(req), share.id, found.machine);
tunnels.close(share.id, 4003, 'now served by one of your computers');
return res.redirect(303, `/shares/${encodeURIComponent(share.id)}?served=1`);
ddiff --git a/server/shares.js b/server/shares.js
iindex ad7c3fd..463ebbc 100644
---- a/server/shares.js
++++ b/server/shares.js
@@@ -149,7 +149,7 @@ function createShares(s, { config }) {
status: row.status,
policy_version: Number(row.policy_version),
key_prefix: row.node_id ? null : row.key_prefix,
-- // Served by one of the owner's computers, as OpenVibe Node (CON-4): its Network node principal and name.
++ // Served by one of the owner's computers, as OpenVibe Link (CON-4): its Network node principal and name.
node: row.node_id ? { id: row.node_id, name: row.node_name || 'A computer' } : null,
note: row.note || null,
created_at: iso(row.created_at),
@@@ -262,7 +262,7 @@ function createShares(s, { config }) {
const share = await owned(owner, id);
if (share.status !== 'active') throw new ShareError(410, 'share.revoked', 'That share is closed.');
const key = newKey();
-- // A new key means the key serves it: a computer bound as OpenVibe Node is let go (CON-4).
++ // A new key means the key serves it: a computer bound as OpenVibe Link is let go (CON-4).
await db.exec('UPDATE shares SET key_prefix = $2, key_hash = $3, node_id = NULL, node_name = NULL, updated_at = now() WHERE id = $1', [share.id, key.slice(0, 10), sha256(key)]);
return { share: await get(share.id), key };
}
ddiff --git a/server/views/index.js b/server/views/index.js
iindex 853d6cf..815f0c5 100644
---- a/server/views/index.js
++++ b/server/views/index.js
@@@ -232,7 +232,7 @@ function requestRow(q) {
const MACHINES_URL = 'https://openvibe.bot/machines';
/**
-- * Which computer serves it (CON-4): one of the owner's computers as OpenVibe Node (no key to copy; removing the computer
++ * Which computer serves it (CON-4): one of the owner's computers as OpenVibe Link (no key to copy; removing the computer
* on OpenVibe stops it), or the one-file client with the connect key. `machines` is null when Network could not be read.
*/
function nodeBlock(share, machines, now) {
@@@ -240,15 +240,15 @@ function nodeBlock(share, machines, now) {
const run = `openvibe-node share --share ${share.id}`;
const keep = `sudo openvibe-node share add --share ${share.id}`;
return `<section class="cn-node" aria-labelledby="cn-node-h"><h2 id="cn-node-h">Your computer serves it</h2>
--<p><b>${esc(share.node.name)}</b> serves this share as OpenVibe Node: no key to copy, and removing the computer on OpenVibe stops it within five minutes.</p>
++<p><b>${esc(share.node.name)}</b> serves this share as OpenVibe Link: no key to copy, and removing the computer on OpenVibe stops it within five minutes.</p>
<ol class="cn-steps">
<li><span>On that computer, serve it now:</span><div class="cn-copy"><code id="cn-node-run">${esc(run)}</code><button type="button" class="cn-btn cn-btn-quiet" data-ovk-copy="#cn-node-run" hidden>${kit.icon('copy')} Copy</button></div></li>
--<li><span>Or keep it up with the Node service, across restarts:</span><div class="cn-copy"><code id="cn-node-keep">${esc(keep)}</code><button type="button" class="cn-btn cn-btn-quiet" data-ovk-copy="#cn-node-keep" hidden>${kit.icon('copy')} Copy</button></div></li>
++<li><span>Or keep it up with the Link service, across restarts:</span><div class="cn-copy"><code id="cn-node-keep">${esc(keep)}</code><button type="button" class="cn-btn cn-btn-quiet" data-ovk-copy="#cn-node-keep" hidden>${kit.icon('copy')} Copy</button></div></li>
</ol>
<form method="post" action="/shares/${esc(share.id)}/node"><input type="hidden" name="node" value=""><button class="cn-btn cn-btn-quiet" type="submit">${kit.icon('key')} Use a connect key instead</button><span>The computer stops serving it and a new key is shown once.</span></form>
</section>`;
}
-- const intro = '<p>Pick one of your computers that runs OpenVibe Node and it serves this share with its own sign-in: no key to copy, and removing the computer on OpenVibe stops it. The connect key stops working while a computer serves it.</p>';
++ const intro = '<p>Pick one of your computers that runs OpenVibe Link and it serves this share with its own sign-in: no key to copy, and removing the computer on OpenVibe stops it. The connect key stops working while a computer serves it.</p>';
let list;
if (machines === null) list = '<p class="cn-empty">Your computers could not be read from OpenVibe just now. Reload the page in a moment.</p>';
else if (!machines.length) list = `<p class="cn-empty">No computers yet. <a href="${esc(MACHINES_URL)}">Add one on openvibe.bot/machines</a>, then come back here.</p>`;
@@@ -358,7 +358,7 @@ function sharePage({ share, connected, tunnel = null, visits = [], requests = []
const state = closed ? 'Closed' : connected ? 'Connected' : 'Not connected';
const stateText = closed ? `Closed ${ago(share.revoked_at, now)}. The address answers "closed" and stays yours.`
: connected ? `Connected ${ago(tunnel && tunnel.connectedAt ? new Date(tunnel.connectedAt).toISOString() : share.last_connected_at, now)}${tunnel && tunnel.clientInfo && tunnel.clientInfo.port ? `, serving localhost:${tunnel.clientInfo.port}` : ''}.`
-- : share.last_connected_at ? `Last connected ${ago(share.last_connected_at, now)}. ${share.node ? `Start OpenVibe Node on ${share.node.name}` : 'Run ov-connect on your computer'} to bring it back.` : 'Never connected yet. Run the command below on your computer.';
++ : share.last_connected_at ? `Last connected ${ago(share.last_connected_at, now)}. ${share.node ? `Start OpenVibe Link on ${share.node.name}` : 'Run ov-connect on your computer'} to bring it back.` : 'Never connected yet. Run the command below on your computer.';
const visitRows = visits.length
? `<ul class="cn-visits">${visits.map((v) => `<li><b>${v.username ? `@${esc(v.username)}` : 'someone'}</b><span>${esc(v.requests)} ${v.requests === 1 ? 'request' : 'requests'}${v.denied ? `, ${esc(v.denied)} turned away` : ''} · ${esc(ago(v.last_at, now))}</span></li>`).join('')}</ul>`
: '<p class="cn-empty">Nobody has opened it in the last 7 days.</p>';
@@@ -391,7 +391,7 @@ ${key ? keyBlock(share, key, baseUrl) : ''}
<div><dt>Port</dt><dd>localhost:${esc(share.local_port)}</dd></div>
<div><dt>Requests</dt><dd>${esc(Number(share.requests).toLocaleString('en-US'))}</dd></div>
<div><dt>Data</dt><dd>${esc(fmtBytes(share.bytes_in))} in · ${esc(fmtBytes(share.bytes_out))} out</dd></div>
--${share.node ? `<div><dt>Served by</dt><dd>${esc(share.node.name)} (OpenVibe Node)</dd></div>` : `<div><dt>Key</dt><dd><code>${esc(share.key_prefix)}…</code></dd></div>`}
++${share.node ? `<div><dt>Served by</dt><dd>${esc(share.node.name)} (OpenVibe Link)</dd></div>` : `<div><dt>Key</dt><dd><code>${esc(share.key_prefix)}…</code></dd></div>`}
<div><dt>Made</dt><dd>${esc(ago(share.created_at, now))}</dd></div>
${share.expires_at ? `<div><dt>${closed ? 'Ended' : 'Closes'}</dt><dd><time datetime="${esc(share.expires_at)}">${esc(closed ? ago(share.expires_at, now) : until(share.expires_at, now))}</time></dd></div>` : ''}
</dl>
ddiff --git a/test/node-share.test.js b/test/node-share.test.js
iindex 705b201..6ab4985 100644
---- a/test/node-share.test.js
++++ b/test/node-share.test.js
@@@ -1,6 +1,6 @@
'use strict';
/**
-- * A share served by one of its owner's computers, as OpenVibe Node (CON-4, ADR-057 decision 4): the owner picks the
++ * A share served by one of its owner's computers, as OpenVibe Link (CON-4, ADR-057 decision 4): the owner picks the
* computer from their machines on Network; the computer asks for a tunnel token with its node token and says hello with
* both; a visitor's request reaches it; it sends a fresh node token before the old one runs out, and a tunnel whose token
* ran out is closed. Every refusal: another person's computer, a token for another audience, a spent or late tunnel