feat: add delivery sequence numbers + major server/client refactor
Delivery sequence numbers (MLS epoch ordering fix):
- schemas/node.capnp: add Envelope{seq,data} struct; enqueue returns seq:UInt64;
fetch/fetchWait return List(Envelope) instead of List(Data)
- storage.rs: Store trait enqueue returns u64; fetch/fetch_limited return
Vec<(u64, Vec<u8>)>; FileBackedStore gains QueueMapV3 with per-inbox seq
counters and V2→V3 on-disk migration
- migrations/002_add_seq.sql: seq column, delivery_seq_counters table, index
- sql_store.rs: atomic UPSERT counter via RETURNING, ORDER BY seq, SCHEMA_VERSION→3
- node_service/delivery.rs: builds Envelope list; returns seq from enqueue
- client/rpc.rs: enqueue→u64, fetch_all/fetch_wait→Vec<(u64,Vec<u8>)>
- client/commands.rs: sort-by-seq before MLS processing; retry loop in cmd_recv
and receive_pending_plaintexts for correct epoch ordering
Server refactor:
- Split monolithic main.rs into node_service/{mod,delivery,auth_ops,key_ops,p2p_ops}
- Add auth.rs (token validation, rate limiting), config.rs, metrics.rs, tls.rs
- Add SQL migrations runner (001_initial.sql, 002_add_seq.sql)
- OPAQUE PAKE login/registration, sealed-sender mode, queue depth limit (1000)
Client refactor:
- Split lib.rs into client/{commands,rpc,state,retry,hex,mod}
- Add cmd_whoami, cmd_health, cmd_check_key, cmd_ping subcommands
- Add cmd_register_user, cmd_login (OPAQUE), cmd_refresh_keypackage
- Hybrid PQ envelope (X25519 + ML-KEM-768) on all send/recv paths
- E2E test suite expanded
Other:
- quicnprotochat-gui: Tauri 2 desktop GUI skeleton (backend + HTML UI)
- quicnprotochat-p2p: iroh-based P2P transport stub
- quicnprotochat-core: app_message, hybrid_crypto modules; GroupMember API updates
- .github/workflows/size-lint.yml: binary size regression check
- docs: protocol comparison, roadmap updates, fully-operational checklist
This commit is contained in:
54
crates/quicnprotochat-gui/ui/index.html
Normal file
54
crates/quicnprotochat-gui/ui/index.html
Normal file
@@ -0,0 +1,54 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>quicnprotochat</title>
|
||||
<style>
|
||||
body { font-family: system-ui, sans-serif; margin: 1rem; }
|
||||
button { margin: 0.25rem; padding: 0.5rem 1rem; cursor: pointer; }
|
||||
#output { white-space: pre-wrap; background: #f0f0f0; padding: 0.75rem; margin-top: 1rem; min-height: 4rem; border-radius: 4px; }
|
||||
.error { color: #c00; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>quicnprotochat</h1>
|
||||
<p>
|
||||
<button id="whoami">Whoami</button>
|
||||
<button id="health">Health</button>
|
||||
</p>
|
||||
<label>State path: <input id="statePath" type="text" value="quicnprotochat-state.bin" size="32" /></label>
|
||||
<br />
|
||||
<label>Server: <input id="server" type="text" value="127.0.0.1:7000" size="24" /></label>
|
||||
<div id="output">Click Whoami or Health. Results appear here.</div>
|
||||
|
||||
<script>
|
||||
const output = document.getElementById('output');
|
||||
const statePath = document.getElementById('statePath');
|
||||
const server = document.getElementById('server');
|
||||
|
||||
function show(result, isError = false) {
|
||||
output.textContent = result;
|
||||
output.className = isError ? 'error' : '';
|
||||
}
|
||||
|
||||
const invoke = window.__TAURI__?.core?.invoke;
|
||||
if (!invoke) {
|
||||
show('Tauri API not available (not running inside Tauri?).', true);
|
||||
} else {
|
||||
document.getElementById('whoami').addEventListener('click', function () {
|
||||
show('Running whoami…');
|
||||
invoke('whoami', { statePath: statePath.value.trim(), password: null })
|
||||
.then(function (s) { show(s); })
|
||||
.catch(function (e) { show(String(e), true); });
|
||||
});
|
||||
document.getElementById('health').addEventListener('click', function () {
|
||||
show('Running health…');
|
||||
invoke('health', { server: server.value.trim() })
|
||||
.then(function (s) { show(s); })
|
||||
.catch(function (e) { show(String(e), true); });
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user