botschat 0.1.7 → 0.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/packages/api/src/do/connection-do.ts +7 -3
- package/packages/api/src/routes/upload.ts +2 -1
- package/packages/api/src/utils/uuid.ts +17 -0
- package/packages/plugin/dist/src/channel.d.ts.map +1 -1
- package/packages/plugin/dist/src/channel.js +40 -9
- package/packages/plugin/dist/src/channel.js.map +1 -1
- package/packages/plugin/dist/src/e2e-crypto.d.ts +47 -0
- package/packages/plugin/dist/src/e2e-crypto.d.ts.map +1 -0
- package/packages/plugin/dist/src/e2e-crypto.js +210 -0
- package/packages/plugin/dist/src/e2e-crypto.js.map +1 -0
- package/packages/plugin/dist/src/ws-client.d.ts.map +1 -1
- package/packages/plugin/dist/src/ws-client.js +8 -4
- package/packages/plugin/dist/src/ws-client.js.map +1 -1
- package/packages/plugin/package.json +2 -3
- package/packages/web/dist/assets/__vite-browser-external-BIHI7g3E.js +1 -0
- package/packages/web/dist/assets/{index-ewBIratI.css → index-B1sFqYiM.css} +1 -1
- package/packages/web/dist/assets/index-BcHAQzqW.js +1497 -0
- package/packages/web/dist/index.html +2 -2
- package/packages/web/src/App.tsx +12 -5
- package/packages/web/src/components/ChatWindow.tsx +5 -5
- package/packages/web/src/components/E2ESettings.tsx +35 -11
- package/packages/web/src/components/LoginPage.tsx +3 -0
- package/packages/web/src/components/MobileLayout.tsx +29 -2
- package/packages/web/src/components/OnboardingPage.tsx +73 -26
- package/packages/web/src/components/Sidebar.tsx +14 -1
- package/packages/web/src/components/ThreadPanel.tsx +2 -1
- package/packages/web/src/e2e.ts +22 -9
- package/packages/web/src/utils/uuid.ts +21 -0
- package/packages/web/src/ws.ts +5 -2
- package/scripts/test-e2e-chat.ts +97 -0
- package/packages/web/dist/assets/index-BoNQoJjQ.js +0 -1497
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import WebSocket from "ws";
|
|
2
|
+
import { deriveKey, encryptText, decryptText, toBase64, fromBase64 } from "../packages/e2e-crypto/e2e-crypto.js";
|
|
3
|
+
|
|
4
|
+
const E2E_PWD = "botschat123";
|
|
5
|
+
|
|
6
|
+
async function main() {
|
|
7
|
+
// Login
|
|
8
|
+
const res = await fetch("http://localhost:8787/api/auth/login", {
|
|
9
|
+
method: "POST",
|
|
10
|
+
headers: { "Content-Type": "application/json" },
|
|
11
|
+
body: JSON.stringify({ email: "tong@mini.local", password: "botschat123" }),
|
|
12
|
+
});
|
|
13
|
+
if (!res.ok) { console.log("Login failed:", res.status); process.exit(1); }
|
|
14
|
+
const login = await res.json() as { id: string; token: string };
|
|
15
|
+
const { token, id: userId } = login;
|
|
16
|
+
console.log("1. Logged in:", userId);
|
|
17
|
+
|
|
18
|
+
// Channels — create if none
|
|
19
|
+
const chRes = await fetch("http://localhost:8787/api/channels", { headers: { Authorization: `Bearer ${token}` } });
|
|
20
|
+
let { channels } = await chRes.json() as { channels: Array<{ id: string }> };
|
|
21
|
+
if (!channels.length) {
|
|
22
|
+
const cr = await fetch("http://localhost:8787/api/channels", {
|
|
23
|
+
method: "POST",
|
|
24
|
+
headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json" },
|
|
25
|
+
body: JSON.stringify({ name: "Test Channel", description: "E2E test" }),
|
|
26
|
+
});
|
|
27
|
+
const ch = await cr.json() as { id: string };
|
|
28
|
+
channels = [ch];
|
|
29
|
+
console.log(" Created channel:", ch.id);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Sessions — create a fresh one
|
|
33
|
+
const sesRes = await fetch(`http://localhost:8787/api/channels/${channels[0].id}/sessions`, {
|
|
34
|
+
method: "POST",
|
|
35
|
+
headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json" },
|
|
36
|
+
body: JSON.stringify({ name: "E2E Chat Test" }),
|
|
37
|
+
});
|
|
38
|
+
const session = await sesRes.json() as { sessionKey: string };
|
|
39
|
+
console.log("2. Session:", session.sessionKey);
|
|
40
|
+
|
|
41
|
+
// Derive key
|
|
42
|
+
const key = await deriveKey(E2E_PWD, userId);
|
|
43
|
+
console.log("3. E2E key derived");
|
|
44
|
+
|
|
45
|
+
// WS connect
|
|
46
|
+
const ws = new WebSocket(`ws://localhost:8787/api/ws/${userId}/chat-test`);
|
|
47
|
+
|
|
48
|
+
await new Promise<void>((resolve, reject) => {
|
|
49
|
+
const timeout = setTimeout(() => { reject(new Error("Timeout 45s")); ws.close(); }, 45000);
|
|
50
|
+
|
|
51
|
+
ws.on("open", () => ws.send(JSON.stringify({ type: "auth", token })));
|
|
52
|
+
|
|
53
|
+
ws.on("message", async (data) => {
|
|
54
|
+
const msg = JSON.parse(data.toString()) as Record<string, unknown>;
|
|
55
|
+
|
|
56
|
+
if (msg.type === "auth.ok") {
|
|
57
|
+
console.log("4. WS auth OK");
|
|
58
|
+
const messageId = `chat-test-${Date.now()}`;
|
|
59
|
+
const ct = await encryptText(key, "hello from API test", messageId);
|
|
60
|
+
ws.send(JSON.stringify({
|
|
61
|
+
type: "user.message",
|
|
62
|
+
sessionKey: session.sessionKey,
|
|
63
|
+
text: toBase64(ct),
|
|
64
|
+
messageId,
|
|
65
|
+
encrypted: true,
|
|
66
|
+
}));
|
|
67
|
+
console.log("5. Sent encrypted 'hello from API test'");
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (msg.type === "agent.text") {
|
|
71
|
+
console.log(`6. Got agent.text (encrypted=${msg.encrypted}, messageId=${msg.messageId})`);
|
|
72
|
+
if (msg.encrypted && msg.messageId) {
|
|
73
|
+
try {
|
|
74
|
+
const plain = await decryptText(key, fromBase64(msg.text as string), msg.messageId as string);
|
|
75
|
+
console.log(" DECRYPTED:", plain.slice(0, 200));
|
|
76
|
+
} catch (e: any) {
|
|
77
|
+
console.log(" Decrypt FAILED:", e.message);
|
|
78
|
+
console.log(" Raw:", (msg.text as string || "").slice(0, 80));
|
|
79
|
+
}
|
|
80
|
+
} else {
|
|
81
|
+
console.log(" PLAINTEXT:", ((msg.text as string) || "").slice(0, 200));
|
|
82
|
+
}
|
|
83
|
+
clearTimeout(timeout);
|
|
84
|
+
resolve();
|
|
85
|
+
ws.close();
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (msg.type === "error") console.log("ERROR:", msg.message);
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
ws.on("error", (e) => console.log("WS error:", e.message));
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
console.log("\nTEST COMPLETE");
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
main().catch((e) => { console.error("FAIL:", e.message); process.exit(1); });
|