botschat 0.1.10 → 0.1.13

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.
Files changed (56) hide show
  1. package/README.md +11 -15
  2. package/migrations/0012_push_tokens.sql +11 -0
  3. package/package.json +20 -1
  4. package/packages/api/src/do/connection-do.ts +142 -24
  5. package/packages/api/src/env.ts +6 -0
  6. package/packages/api/src/index.ts +7 -0
  7. package/packages/api/src/routes/auth.ts +85 -9
  8. package/packages/api/src/routes/channels.ts +3 -2
  9. package/packages/api/src/routes/dev-auth.ts +45 -0
  10. package/packages/api/src/routes/push.ts +52 -0
  11. package/packages/api/src/routes/upload.ts +73 -38
  12. package/packages/api/src/utils/fcm.ts +167 -0
  13. package/packages/api/src/utils/firebase.ts +218 -0
  14. package/packages/plugin/dist/src/channel.d.ts +6 -0
  15. package/packages/plugin/dist/src/channel.d.ts.map +1 -1
  16. package/packages/plugin/dist/src/channel.js +71 -15
  17. package/packages/plugin/dist/src/channel.js.map +1 -1
  18. package/packages/plugin/package.json +1 -1
  19. package/packages/web/dist/assets/index-B9qN5gs6.js +1 -0
  20. package/packages/web/dist/assets/index-BQNMGVyU.js +2 -0
  21. package/packages/web/dist/assets/{index-Ev5M8VmV.css → index-Bd_RDcgO.css} +1 -1
  22. package/packages/web/dist/assets/index-Civeg2lm.js +1 -0
  23. package/packages/web/dist/assets/index-Dk33VSnY.js +2 -0
  24. package/packages/web/dist/assets/index-Kr85Nj_-.js +1516 -0
  25. package/packages/web/dist/assets/index-lVB82JKU.js +1 -0
  26. package/packages/web/dist/assets/index.esm-CtMkqqqb.js +599 -0
  27. package/packages/web/dist/assets/web-CUXjh_UA.js +1 -0
  28. package/packages/web/dist/assets/web-vKLTVUul.js +1 -0
  29. package/packages/web/dist/index.html +6 -4
  30. package/packages/web/dist/sw.js +158 -1
  31. package/packages/web/index.html +4 -2
  32. package/packages/web/package.json +4 -1
  33. package/packages/web/src/App.tsx +117 -1
  34. package/packages/web/src/api.ts +21 -1
  35. package/packages/web/src/components/AccountSettings.tsx +131 -0
  36. package/packages/web/src/components/ChatWindow.tsx +302 -70
  37. package/packages/web/src/components/CronSidebar.tsx +89 -24
  38. package/packages/web/src/components/DataConsentModal.tsx +249 -0
  39. package/packages/web/src/components/LoginPage.tsx +55 -7
  40. package/packages/web/src/components/MessageContent.tsx +71 -9
  41. package/packages/web/src/components/MobileLayout.tsx +28 -118
  42. package/packages/web/src/components/SessionTabs.tsx +41 -2
  43. package/packages/web/src/components/Sidebar.tsx +88 -66
  44. package/packages/web/src/e2e.ts +26 -5
  45. package/packages/web/src/firebase.ts +215 -3
  46. package/packages/web/src/foreground.ts +51 -0
  47. package/packages/web/src/index.css +10 -2
  48. package/packages/web/src/main.tsx +24 -2
  49. package/packages/web/src/push.ts +205 -0
  50. package/packages/web/src/ws.ts +20 -8
  51. package/scripts/dev.sh +158 -26
  52. package/scripts/mock-openclaw.mjs +382 -0
  53. package/scripts/test-e2e-chat.ts +2 -2
  54. package/scripts/test-e2e-live.ts +1 -1
  55. package/wrangler.toml +3 -0
  56. package/packages/web/dist/assets/index-DpW6VzZK.js +0 -1497
@@ -0,0 +1,131 @@
1
+ import React, { useState } from "react";
2
+ import { useAppState } from "../store";
3
+ import { setToken, setRefreshToken } from "../api";
4
+
5
+ export function AccountSettings() {
6
+ const state = useAppState();
7
+ const [showConfirm, setShowConfirm] = useState(false);
8
+ const [confirmText, setConfirmText] = useState("");
9
+ const [busy, setBusy] = useState(false);
10
+ const [error, setError] = useState<string | null>(null);
11
+
12
+ const handleLogout = () => {
13
+ setToken(null);
14
+ setRefreshToken(null);
15
+ localStorage.clear();
16
+ window.location.reload();
17
+ };
18
+
19
+ const handleDelete = async () => {
20
+ if (confirmText !== "DELETE") return;
21
+ setBusy(true);
22
+ setError(null);
23
+ try {
24
+ const token = localStorage.getItem("botschat_token");
25
+ const res = await fetch("/api/auth/account", {
26
+ method: "DELETE",
27
+ headers: { Authorization: `Bearer ${token}` },
28
+ });
29
+ if (!res.ok) {
30
+ const data = await res.json().catch(() => ({ error: res.statusText }));
31
+ throw new Error((data as { error?: string }).error ?? `HTTP ${res.status}`);
32
+ }
33
+ setToken(null);
34
+ setRefreshToken(null);
35
+ localStorage.clear();
36
+ window.location.reload();
37
+ } catch (err) {
38
+ setError(err instanceof Error ? err.message : "Failed to delete account");
39
+ setBusy(false);
40
+ }
41
+ };
42
+
43
+ return (
44
+ <div className="space-y-6">
45
+ {/* Account Info */}
46
+ <div>
47
+ <h3 className="text-h3 font-bold mb-2" style={{ color: "var(--text-primary)" }}>
48
+ Account
49
+ </h3>
50
+ <div className="space-y-1.5">
51
+ <p className="text-body" style={{ color: "var(--text-secondary)" }}>
52
+ <span style={{ color: "var(--text-muted)" }}>Email: </span>
53
+ {state.user?.email ?? "—"}
54
+ </p>
55
+ </div>
56
+ </div>
57
+
58
+ {/* Logout */}
59
+ <div>
60
+ <button
61
+ onClick={handleLogout}
62
+ className="px-4 py-2 rounded-md text-caption font-bold"
63
+ style={{ background: "var(--bg-hover)", color: "var(--text-primary)", border: "1px solid var(--border)" }}
64
+ >
65
+ Sign Out
66
+ </button>
67
+ </div>
68
+
69
+ {/* Danger Zone */}
70
+ <div
71
+ className="p-4 rounded-md border"
72
+ style={{ borderColor: "var(--accent-red, #e53e3e)", background: "rgba(255, 0, 0, 0.04)" }}
73
+ >
74
+ <h4 className="text-caption font-bold mb-2" style={{ color: "var(--accent-red, #e53e3e)" }}>
75
+ Danger Zone
76
+ </h4>
77
+ <p className="text-caption mb-3" style={{ color: "var(--text-muted)" }}>
78
+ Permanently delete your account and all associated data (messages, channels,
79
+ automations, media). This action cannot be undone.
80
+ </p>
81
+
82
+ {!showConfirm ? (
83
+ <button
84
+ onClick={() => setShowConfirm(true)}
85
+ className="px-4 py-2 rounded-md text-caption font-bold"
86
+ style={{ background: "var(--accent-red, #e53e3e)", color: "#fff" }}
87
+ >
88
+ Delete Account
89
+ </button>
90
+ ) : (
91
+ <div className="space-y-3">
92
+ <p className="text-caption font-bold" style={{ color: "var(--text-primary)" }}>
93
+ Type <code style={{ color: "var(--accent-red, #e53e3e)" }}>DELETE</code> to confirm:
94
+ </p>
95
+ <input
96
+ type="text"
97
+ value={confirmText}
98
+ onChange={(e) => setConfirmText(e.target.value)}
99
+ className="w-full px-3 py-2 rounded border text-body"
100
+ style={{ background: "var(--bg-input, var(--bg-surface))", borderColor: "var(--border)", color: "var(--text-primary)" }}
101
+ placeholder="DELETE"
102
+ autoFocus
103
+ />
104
+ {error && <p className="text-caption" style={{ color: "var(--accent-red, #e53e3e)" }}>{error}</p>}
105
+ <div className="flex gap-2">
106
+ <button
107
+ onClick={handleDelete}
108
+ disabled={confirmText !== "DELETE" || busy}
109
+ className="px-4 py-2 rounded-md text-caption font-bold"
110
+ style={{
111
+ background: "var(--accent-red, #e53e3e)",
112
+ color: "#fff",
113
+ opacity: confirmText !== "DELETE" || busy ? 0.5 : 1,
114
+ }}
115
+ >
116
+ {busy ? "Deleting..." : "Permanently Delete"}
117
+ </button>
118
+ <button
119
+ onClick={() => { setShowConfirm(false); setConfirmText(""); setError(null); }}
120
+ className="px-4 py-2 rounded-md text-caption font-bold"
121
+ style={{ background: "var(--bg-hover)", color: "var(--text-primary)", border: "1px solid var(--border)" }}
122
+ >
123
+ Cancel
124
+ </button>
125
+ </div>
126
+ </div>
127
+ )}
128
+ </div>
129
+ </div>
130
+ );
131
+ }