aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-hub/src/meshbay_hub/static
diff options
context:
space:
mode:
authorChristophe Besson <cbesson@gmail.com>2026-09-28 18:22:07 +0200
committerChristophe Besson <cbesson@gmail.com>2026-09-28 18:22:07 +0200
commitf63104b82da24ff3f406c53346300bd50788796f (patch)
tree1bd4466385e4298a2e2936d188b01047a4a7a8a6 /packages/meshbay-hub/src/meshbay_hub/static
parenta4b36e5fe31cb671a4cbbdaad75746cd68b601fe (diff)
downloadmeshbay-f63104b82da24ff3f406c53346300bd50788796f.tar.gz
refactor: remove dead code across packages
Unused modules, functions, constants and client helpers with no caller, the unreachable hub:probe IPC handler, and the CSAM hash matching. Behaviour unchanged; the dispatch golden loses only the two removed message types. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'packages/meshbay-hub/src/meshbay_hub/static')
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/app.js7
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/crypto.js57
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/downloads.js7
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/files-app.js1
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/i18n.js4
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/keyderive.js20
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/transfers.js7
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/transport-chat.js1
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/transport.js11
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/video-player.js6
10 files changed, 9 insertions, 112 deletions
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/app.js b/packages/meshbay-hub/src/meshbay_hub/static/app.js
index 3101be7..bcd5999 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/app.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/app.js
@@ -3,7 +3,7 @@
import { clearPending, loadPending } from './invite-link.js';
import {
html, render, useState, useEffect, useLayoutEffect, useCallback, useRef,
- createContext, useContext,
+ createContext,
} from './vendor/htm-preact.js';
import { t, getLocale, setLocale, initLocale, LOCALES } from './i18n.js';
import { ZipStream, entriesUnder } from './zipstream.js';
@@ -72,7 +72,6 @@ function useRoute() {
// ── Context ──────────────────────────────────────────────────────────────────
const AuthContext = createContext(null);
-function useAuth() { return useContext(AuthContext); }
// The M of the wordmark is a picture; the rest is text. Resolved from this
// module's own URL so the hub's fingerprinted path and the application's
@@ -645,10 +644,6 @@ function LazyCreateGroupPage(props) {
return html`<${_CreateGroupPage} ...${props} />`;
}
-// ── Settings Page ───────────────────────────────────────────────────────────
-
-const THEME_OPTIONS = ['light', 'dark', 'system'];
-
// ── Profile Page ────────────────────────────────────────────────────────────
//
// ── Lazy-loaded Admin page (admin/moderator only) ─────────────────────────
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/crypto.js b/packages/meshbay-hub/src/meshbay_hub/static/crypto.js
index a3680ce..b74732c 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/crypto.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/crypto.js
@@ -1,20 +1,12 @@
/**
- * MeshBay Browser Crypto — AES-256-GCM private group decryption.
- * Uses WebCrypto SubtleCrypto API (available in all modern browsers).
- *
- * Handles groups with cipher="aes-256-gcm" (browser-accessible groups).
- * ChaCha20-Poly1305 groups (cipher="chacha20-poly1305") require the
- * native client (node) for decryption — not supported in browser.
+ * MeshBay Browser Crypto — AES-256-GCM, through WebCrypto's SubtleCrypto API.
+ * The one content cipher, for every client (meshbay_common/webcrypto.py).
*
* Usage:
* const gek = await importGEK(gekB64);
* const plaintext = await decryptChunkBin(gek, fileHashHex, chunkIndex, nonce, ct);
*/
-const CIPHER_INFO_PREFIX = new TextEncoder().encode('file:');
-const CIPHER_INFO_SUFFIX_AES = new TextEncoder().encode(':aes');
-
-
// ── Key derivation ────────────────────────────────────────────────────────────
/**
@@ -284,38 +276,7 @@ async function verifyChatSignature(deviceRaw, groupId, epoch, nonce, ct, sig) {
}
-// ── GEK generation + ECIES wrapping ──────────────────────────────────────────
-
-function generateGEK() {
- return crypto.getRandomValues(new Uint8Array(32));
-}
-
-async function wrapGEK(gek, pkXRaw) {
- const skEph = await crypto.subtle.generateKey({ name: 'X25519' }, true, ['deriveBits']);
- const pkEphRaw = new Uint8Array(await crypto.subtle.exportKey('raw', skEph.publicKey));
-
- const pkRecip = await crypto.subtle.importKey('raw', pkXRaw, { name: 'X25519' }, false, []);
- const sharedBits = await crypto.subtle.deriveBits(
- { name: 'X25519', public: pkRecip }, skEph.privateKey, 256);
-
- const sharedKey = await crypto.subtle.importKey(
- 'raw', sharedBits, 'HKDF', false, ['deriveKey']);
- const wrapKey = await crypto.subtle.deriveKey(
- { name: 'HKDF', hash: 'SHA-256', salt: pkEphRaw,
- info: new TextEncoder().encode('meshbay:gek_wrap:v1:aes') },
- sharedKey,
- { name: 'AES-GCM', length: 256 }, false, ['encrypt']);
-
- const nonce = crypto.getRandomValues(new Uint8Array(12));
- const ct = await crypto.subtle.encrypt(
- { name: 'AES-GCM', iv: nonce, additionalData: pkXRaw }, wrapKey, gek);
-
- return {
- pk_eph_b64: btoa(String.fromCharCode(...pkEphRaw)),
- nonce_b64: btoa(String.fromCharCode(...nonce)),
- wrapped_b64: btoa(String.fromCharCode(...new Uint8Array(ct))),
- };
-}
+// ── GEK unwrapping (ECIES) ─────────────────────────────────────────────────────
async function unwrapGEK(bundle, skXPkcs8, pkXRaw) {
const pkEphRaw = b64decode(bundle.pk_eph_b64);
@@ -342,16 +303,6 @@ async function unwrapGEK(bundle, skXPkcs8, pkXRaw) {
return new Uint8Array(plain);
}
-// ── Chunk encryption (for upload) ────────────────────────────────────────────
-
-async function encryptChunk(gek, fileHashHex, chunkIndex, plaintext) {
- const chunkKey = await deriveChunkKey(gek, fileHashHex, chunkIndex);
- const nonce = crypto.getRandomValues(new Uint8Array(12));
- const ct = await crypto.subtle.encrypt(
- { name: 'AES-GCM', iv: nonce }, chunkKey, plaintext);
- return { nonce, ct: new Uint8Array(ct) };
-}
-
function b64encode(bytes) {
return btoa(String.fromCharCode(...bytes));
}
@@ -583,7 +534,7 @@ async function verifyNodeSignature(nodePkB64, sigB64, transcript) {
window.MeshBayCrypto = {
importGEK, deriveChunkKey, decryptChunkBin,
openGroup, sealGroup,
- generateGEK, wrapGEK, unwrapGEK, encryptChunk, b64encode, b64decode,
+ unwrapGEK, b64encode, b64decode,
adminTranscript, handshakeTranscript, handshakeProof, webrtcBinding,
challengeTranscript, joinTranscript, verifyNodeSignature, constantTimeEqual,
deviceRequestTranscript, deviceAddTranscript, deviceHelloTranscript,
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/downloads.js b/packages/meshbay-hub/src/meshbay_hub/static/downloads.js
index 9c23d3c..50bca46 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/downloads.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/downloads.js
@@ -193,13 +193,6 @@ export async function openTarget(filename) {
};
}
-/**
- * Below this, a download with no granted folder and no service worker is
- * collected in memory and handed to the browser. Above it that would mean
- * holding gigabytes in a tab, so it is worth one Save As dialog instead.
- */
-export const BLOB_LIMIT = 512 * 1024 * 1024;
-
// ── Streaming to disk without the File System Access API ────────────────────
const SW_PATH = '/sw.js';
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/files-app.js b/packages/meshbay-hub/src/meshbay_hub/static/files-app.js
index ac978e2..775e2e3 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/files-app.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/files-app.js
@@ -893,7 +893,6 @@ function FilesPanel({
// ── File Preview (text, images) ─────────────────────────────────────────
-const TEXT_EXTS = /\.(txt|md|json|csv|log|xml|yaml|yml|ini|conf|py|js|html|css|sh|c|h|java|rs|go|rb|toml)$/i;
const IMAGE_EXTS = /\.(jpg|jpeg|png|gif|webp|svg|bmp|ico)$/i;
function FilePreview({ entry, transportRef, gekRef, onClose, onDownload }) {
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/i18n.js b/packages/meshbay-hub/src/meshbay_hub/static/i18n.js
index 56d35f7..bc78266 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/i18n.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/i18n.js
@@ -131,10 +131,6 @@ export function setLocale(code) {
return true;
}
-export function addLocale(code, strings) {
- _strings[code] = strings;
-}
-
function _pluralRules(locale) {
if (!_plurals[locale]) _plurals[locale] = new Intl.PluralRules(locale);
return _plurals[locale];
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/keyderive.js b/packages/meshbay-hub/src/meshbay_hub/static/keyderive.js
index 879f56f..33b1cf2 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/keyderive.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/keyderive.js
@@ -256,15 +256,9 @@ async function deriveRecoveryKey(R, username) {
// ── Bundle encryption ─────────────────────────────────────────────────────────
/**
- * Encrypt the keypair bundle with the password-derived AES key.
- * Bundle format: JSON { skEd: base64(pkcs8), skX: base64(pkcs8) }
+ * Encrypt the keypair bundle with a bundle key derived at sign-in. Always
+ * writes v2. Bundle format: JSON { skEd: base64(pkcs8), skX: base64(pkcs8) }
*/
-async function encryptBundle(skEdRaw, skXRaw, password, username) {
- const aesKey = await deriveEncryptionKey(password, username);
- return encryptBundleWithKey(skEdRaw, skXRaw, aesKey);
-}
-
-/** Same, when the key was already derived at sign-in. Always writes v2. */
async function encryptBundleWithKey(skEdRaw, skXRaw, aesKey) {
const nonce = crypto.getRandomValues(new Uint8Array(12));
const data = new TextEncoder().encode(JSON.stringify({
@@ -289,16 +283,6 @@ function bundleVersion(bundleB64) {
} catch { return 1; }
}
-/**
- * Decrypt a keypair bundle. Throws if password is wrong.
- */
-async function decryptBundle(bundleB64, password, username) {
- const key = bundleVersion(bundleB64) === 2
- ? await deriveEncryptionKey(password, username)
- : await deriveEncryptionKeyV1(password, username);
- return decryptBundleWithKey(bundleB64, key);
-}
-
// ── Registration ──────────────────────────────────────────────────────────────
/**
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/transfers.js b/packages/meshbay-hub/src/meshbay_hub/static/transfers.js
index 9a1455a..bde382f 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/transfers.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/transfers.js
@@ -29,13 +29,6 @@ function _live(status) {
|| status === 'paused';
}
-/** Raised by `run` when it stopped because the transfer was paused. */
-function _pausedError() {
- const err = new Error('Paused');
- err.name = 'PausedError';
- return err;
-}
-
function _abortError() {
const err = new Error('Cancelled');
err.name = 'AbortError';
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/transport-chat.js b/packages/meshbay-hub/src/meshbay_hub/static/transport-chat.js
index d6d733f..270c76e 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/transport-chat.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/transport-chat.js
@@ -212,7 +212,6 @@ extendTransport(class {
if (msg.epoch) this.chatEpoch = msg.epoch;
this._chatKeys = null;
this._chatKeysInFlight = null;
- if (this._onChatEpoch) this._onChatEpoch(this.chatEpoch);
}
/**
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/transport.js b/packages/meshbay-hub/src/meshbay_hub/static/transport.js
index 97b2293..0f3f3b8 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/transport.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/transport.js
@@ -571,9 +571,6 @@ class MeshBayTransport {
set onIndexDelta(fn) { this._onIndexDelta = fn; }
set onRootsChanged(fn) { this._onRootsChanged = fn; }
- /** The MNP version the connected node declared, or '' before a handshake. */
- get nodeVersion() { return this._nodeVersion || ''; }
-
/** This member's own caps in this group, or null when the node said nothing. */
get transferLimits() { return this._transferLimits; }
@@ -582,7 +579,6 @@ class MeshBayTransport {
set onChatDirectory(fn) { this._onChatDirectory = fn; }
set onChatLinkPreview(fn) { this._onChatLinkPreview = fn; }
set onSearchListed(fn) { this._onSearchListed = fn; }
- set onChatEpoch(fn) { this._onChatEpoch = fn; }
set onTmdbConfig(fn) { this._onTmdbConfig = fn; }
set onTmdbEnabled(fn) { this._onTmdbEnabled = fn; }
set onMusicbrainzEnabled(fn) { this._onMusicbrainzEnabled = fn; }
@@ -941,12 +937,9 @@ class MeshBayTransport {
if (reply.type === 'handshake_challenge') {
// The node's half of the range. Checked before anything else in this
// block, because everything below — the join, the proof, the sealed ack
- // — assumes both sides mean the same thing by each message.
+ // — assumes both sides mean the same thing by each message. Nothing else
+ // reads the node's version: a peer this admits speaks every message here.
_checkNodeVersion(reply);
- // Kept for diagnostics only. Nothing branches on it: the range check
- // above is what decides whether these two can talk at all, and a peer it
- // admits speaks every message in this file.
- this._nodeVersion = String(reply.v || '');
if (!window.MeshBayCrypto) {
throw new Error('Node requires GEK proof but no crypto available');
}
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/video-player.js b/packages/meshbay-hub/src/meshbay_hub/static/video-player.js
index 2b274b5..fa10d15 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/video-player.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/video-player.js
@@ -270,12 +270,6 @@ function reconnectPlan(playhead, range, ended, castActive) {
return { mode: 'seek', at: playhead };
}
-function _mseSupported(codec) {
- if (!window.MediaSource) return false;
- const mime = `video/mp4; codecs="${codec}"`;
- return MediaSource.isTypeSupported(mime);
-}
-
/** Seconds as h:mm:ss, or m:ss under an hour. */
function formatClock(seconds) {
const s = Math.max(0, Math.floor(seconds || 0));