| Commit message (Collapse) | Author | Age | Files | Lines |
| ... | |
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
1. indexer.py: streaming blake3 (8MB chunks) instead of read_bytes().
Large files (initrd.img, ISOs, VM images) no longer load into RAM.
2. QE/demo-v1/run_node.py: call indexer.start() not initial_scan().
initial_scan() alone never starts the watchdog observer — files added
after startup were silently ignored. Added indexer.stop() on shutdown.
3. USERGUIDE.md §8: clarify symmetric vs asymmetric.
Ed25519/X25519 = asymmetric (key pairs). ChaCha20-Poly1305 and
AES-256-GCM = symmetric AEAD 256-bit (content encryption).
ChaCha20 is PRIMARY; AES-GCM is optional browser-compat variant only.
4. pyproject.toml: aioquic, websockets, aiosqlite, slowapi added to
proper package deps (were installed manually, now declared).
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
meshbay-node/pyproject.toml: add aioquic>=1.0 (was commented 'v2'),
websockets>=12.0 (revocation push). Both are production code since Phase 5.
meshbay-hub/pyproject.toml: add aiosqlite (tests without PostgreSQL),
slowapi (rate limiting), websockets (revocation push), PyJWT (explicit).
transport/__init__.py: QUIC imports wrapped in try/except — node works
without aioquic (TCP+TLS + HTTP fallback). QUIC_AVAILABLE flag exported.
QUICKSTART.md: replace manual pip list with 'pip install -e' that pulls
all deps from pyproject.toml automatically. Add dependency table.
CLAUDE.md: clarify that all deps go in pyproject.toml, not manual installs.
81/81 tests.
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
CLAUDE.md: add QE/ to structure, key modules table, server state reference,
security rule updated (QE/ not keypair files), meshbay.org inventory pointer.
devel-phases.md: add milestones 6.6-6.9 (keyderive, bundle, demo scripts,
QUICKSTART rewrite). 81/81 tests.
docs/meshbay-draft-v3.md §6.1.1: new section documenting 3 key generation
strategies (Argon2id CLI, WebCrypto browser+bundle, keystore file) and the
algorithm mismatch caveat between CLI and web registration paths.
docs/USERGUIDE.md §2 Register+Login: replace "generate and persist before
registering" warning with the two clean strategies (derive_keys_from_password
for CLI, keyderive.js + keypair_bundle for browser). Login response updated
with keypair_bundle field.
hub/models.py + users.py + Alembic migration: keypair_bundle column on User,
stored at registration, returned at login (web clients only).
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
keyderive.py: derive Ed25519+X25519 from username+password via Argon2id.
Same credentials → same keys on any device. Encrypt/decrypt keypair
bundle (AES-256-GCM) for hub storage (web clients).
7/7 tests. Full suite: 81/81.
keyderive.js: browser counterpart using PBKDF2-SHA512 + random keypairs
encrypted for hub storage. Avoids algorithm mismatch with Python.
hub/models.py + users.py: keypair_bundle field added to User, stored on
registration, returned in login response for web client key recovery.
QUICKSTART.md: fully rewritten. 3 operational scripts in QE/demo-v1/:
setup_demo.py — create accounts, group, distribute GEK
run_node.py — start HTTP node (watches shared/ directory)
download.py — bob login → GEK fetch → decrypt → save
All tested locally end-to-end. No invented URLs.
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
6.1 Double Ratchet (meshbay_common/ratchet.py):
Forward secrecy, break-in recovery, out-of-order delivery.
Signal-spec KDF_RK/KDF_CK via HKDF-SHA256. 11/11 tests.
6.2 Multi-group node (config.py):
[[groups]] TOML array, per-group ports, back-compat [group].
6.3 MHP federation persistence (db/models.py FederatedGroup + SwarmSource):
receive_directory() now persists to federated_groups table.
list_public_groups() includes federated results with source attribution.
6.4 Content replication (node/replication.py + hub SwarmSource):
ContentReplicator: fetch-index, download, hash-verify, register-swarm.
Hub: POST /v1/swarm/register, GET /v1/swarm/{hash} for multi-source.
6.5 Browser private group (webcrypto.py + static/crypto.js):
AES-256-GCM variant of GEK for WebCrypto-compatible groups.
crypto.js: SubtleCrypto importGEK + deriveChunkKey + decryptChunk.
Keys distinct from ChaCha20 via :aes HKDF info suffix. 4/4 tests.
74/74 tests total.
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
|
| |
Config now supports [[groups]] array (N groups) alongside back-compat
[group] single section. Each group has independent port/quic_port/http_port
and visibility. GroupConfig gains quic_port, http_port, visibility fields.
NodeConfig gains quic_port and http_port defaults. 70/70 tests.
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
RatchetState: full Signal-spec Double Ratchet (DH ratchet + symmetric
ratchet). KDF_RK/KDF_CK via HKDF-SHA256. AES-256-GCM message encryption.
MKSKIP for out-of-order delivery (max 1000 skipped keys).
ChatMessage dataclass with to_dict/from_dict for wire serialisation.
Properties validated by tests:
✓ Forward secrecy (consumed keys unreplayable)
✓ Out-of-order delivery
✓ Associated data binding
✓ Break-in recovery (post-ratchet keys independent)
✓ 100-message stress test
11/11 tests in 0.06s.
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
CSAMChecker: loads blake3 hash database from file (NCMEC/IWF format).
check_content_hash(): used before serving public content.
/v1/admin/csam/status: hash count + DB path.
/v1/admin/csam/check: admin-only hash check (no hash logged).
Hash database NOT included — hub operators must obtain access
from NCMEC (US) or IWF (EU). Instructions in csam.py header.
59/59 tests.
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
Federation (MHP 0.1): /mhp/info, /mhp/directory (GET=export, POST=receive),
/mhp/revoke (propagation), /mhp/peers (admin registration).
Peer auth: JWT EdDSA signed by requesting hub's key.
Explicit peer allowlist — no auto-discovery.
Relay (5.3): /v1/relays (GET=list), /v1/relays/register (relay keepalive),
/v1/relays/approve (admin pre-approval). Relays pre-approved by admin,
then self-register with signed endpoint. Nodes query when hole punch fails.
59/59 tests.
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
|
|
|
| |
DB: ContentReport + ContentBlocklist tables.
POST /v1/reports: public endpoint, auto-blocks after 2 reports.
GET /v1/blocklist/check: node sync check before serving public content.
GET /v1/blocklist: full list for node startup sync.
GET|POST|DELETE /v1/admin/blocklist: admin management.
6/6 tests. Full suite: 59/59.
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
Hub: /v1/nodes/ws WebSocket endpoint for persistent node connections.
/v1/admin/revoke marks user/group revoked in DB, signs JWT revocation
token (EdDSA), broadcasts to all connected nodes.
Node: RevocationSubscriber maintains WS connection, verifies
incoming revocation tokens offline (hub Ed25519 PK), adds to
local blocklist (_revoked_users/_revoked_groups sets).
53/53 tests.
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
QuicChunkServer/QuicChunkClient: same MNP protocol over QUIC/UDP.
Enables hole-punching (Spike 4 Cone NAT validated). Uses aioquic 1.3.0.
Bug found+fixed: asyncio.Event race condition in client recv loop
(quic_event_received overwrote _stream_events[0] after _recv
created it). Fixed with asyncio.Queue (no shared mutable state).
Server uses synchronous handlers in quic_event_received (avoids
ensure_future transmit timing issue). 3/3 tests. Full suite: 50/50.
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
|
|
| |
webapp.py: serves / (HTML SPA) and /app.js (JS client).
app.js: login, hub API calls, node HTTP API integration,
file browser, HLS video streaming via <video> tag.
groups.py: GET /v1/groups — public group listing (no auth).
Deployed on https://meshbay.org — 200 OK. 47/47 tests.
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
FastAPI app on port 19001: GET / (node info), GET /index (public
group index JSON), GET /file/{id} (full download), GET /file/{id}/{n}
(encrypted or plaintext chunk), GET /hls/{id}/playlist.m3u8 +
GET /hls/{id}/{n}.ts (HLS streaming via ffmpeg).
Public groups: index browsable without auth, files downloadable.
Private groups: chunks encrypted with GEK, auth required.
7/7 tests passing. Full suite: 47/47.
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
config.py: TOML + env var priority. auth.py: Argon2id passwords,
JWT EdDSA with jti, refresh token hashed (blake3). Routers:
hub (info/pubkey), users (register/login/refresh/pubkeys),
nodes (announce/get), groups (create/gek-bundle/gek-retrieve).
Rate limiting via slowapi. app.py factory with lifespan.
All 40 tests pass (SQLite in-memory, no PostgreSQL required).
Fix: remove tests/__init__.py to resolve namespace conflicts.
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
| |
Models: User, Node, Group, GroupMember, GEKBundle, RefreshToken, IPLog.
Engine configurable via MESHBAY_DATABASE_URL (asyncpg/aiosqlite).
Alembic async env.py + initial_schema migration autogenerated.
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
|
|
|
| |
config.py: TOML + env var overrides, sane defaults.
daemon.py: full startup sequence (keystore→hub→GEK→indexer→
server→UI), SIGINT/SIGTERM shutdown, calibrate-argon2 command.
ui/app.py: FastAPI on localhost:18000, status+files JSON API,
HTML status page (auto-refresh 10s). All bound to 127.0.0.1.
Full suite: 29/29 tests.
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
|
|
| |
Self-signed TLS cert (RSA-2048, TLS 1.3 min). Server: JWT offline
verify, index sync, file_request → encrypt+sign chunk pipeline.
Client: handshake, fetch_index, fetch_chunk with Ed25519 verify +
blake3 hash check + GEK decrypt. Integration test: 2MB file served
in 2 chunks, reassembled == original. 3/3 tests. Full suite: 29/29.
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
|
| |
GroupIndex: msgpack→zstd→GEK-encrypt→sign for private groups,
plaintext+sign for public groups. DirectoryIndexer: watchdog-based
watcher, async initial scan via thread pool, on_change callback.
Delta support (diff between versions). 10/10 tests passing.
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
| |
Register/login/announce/token-refresh/GEK-unwrap. JWT jti and
pk_user verified at login. Hub PK cached after first fetch.
6/6 tests passing with httpx.MockTransport (no network).
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
| |
Argon2id + AES-256-GCM encryption at rest. Unlock via env var
(MESHBAY_UNLOCK_KEY), unlock.key file (chmod 600), or interactive
getpass. 10/10 tests passing.
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
|
|
|
3-package layout: meshbay-common (shared crypto/protocol),
meshbay-hub (FastAPI server), meshbay-node (local daemon).
Includes validated POC spikes 1-6 in poc/, architecture drafts
v1/v2 in docs/, and CLAUDE.md project conventions.
All cryptographic primitives extracted from POC into
meshbay_common/crypto.py (GEK wrap/unwrap, chunk key derivation,
keystore encryption, chunk signing).
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
|