@mooncompany/uplink-chat 0.5.0

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.

Potentially problematic release.


This version of @mooncompany/uplink-chat might be problematic. Click here for more details.

Files changed (158) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +185 -0
  3. package/bin/uplink.js +279 -0
  4. package/middleware/error-handler.js +69 -0
  5. package/package.json +93 -0
  6. package/public/css/agents.36b98c0f.css +1469 -0
  7. package/public/css/agents.css +1469 -0
  8. package/public/css/app.a6a7f8f5.css +2731 -0
  9. package/public/css/app.css +2731 -0
  10. package/public/css/artifacts.css +444 -0
  11. package/public/css/commands.css +55 -0
  12. package/public/css/connection.css +131 -0
  13. package/public/css/dashboard.css +233 -0
  14. package/public/css/developer.css +328 -0
  15. package/public/css/files.css +123 -0
  16. package/public/css/markdown.css +156 -0
  17. package/public/css/message-actions.css +278 -0
  18. package/public/css/mobile.css +614 -0
  19. package/public/css/panels-unified.css +483 -0
  20. package/public/css/premium.css +415 -0
  21. package/public/css/realtime.css +189 -0
  22. package/public/css/satellites.css +401 -0
  23. package/public/css/shortcuts.css +185 -0
  24. package/public/css/split-view.4def0262.css +673 -0
  25. package/public/css/split-view.css +673 -0
  26. package/public/css/theme-generator.css +391 -0
  27. package/public/css/themes.css +387 -0
  28. package/public/css/timestamps.css +54 -0
  29. package/public/css/variables.css +78 -0
  30. package/public/dist/bundle.b55050c4.js +15757 -0
  31. package/public/favicon.svg +24 -0
  32. package/public/img/agents/ada.png +0 -0
  33. package/public/img/agents/clarice.png +0 -0
  34. package/public/img/agents/dennis-nedry.png +0 -0
  35. package/public/img/agents/elliot-alderson.png +0 -0
  36. package/public/img/agents/main.png +0 -0
  37. package/public/img/agents/scotty.png +0 -0
  38. package/public/img/agents/top-flight-security.png +0 -0
  39. package/public/index.html +1083 -0
  40. package/public/js/agents-data.js +234 -0
  41. package/public/js/agents-ui.js +72 -0
  42. package/public/js/agents.js +1525 -0
  43. package/public/js/app.js +79 -0
  44. package/public/js/appearance-settings.js +111 -0
  45. package/public/js/artifacts.js +432 -0
  46. package/public/js/audio-queue.js +168 -0
  47. package/public/js/bootstrap.js +54 -0
  48. package/public/js/chat.js +1211 -0
  49. package/public/js/commands.js +581 -0
  50. package/public/js/connection-api.js +121 -0
  51. package/public/js/connection.js +1231 -0
  52. package/public/js/context-tracker.js +271 -0
  53. package/public/js/core.js +172 -0
  54. package/public/js/dashboard.js +452 -0
  55. package/public/js/developer.js +432 -0
  56. package/public/js/encryption.js +124 -0
  57. package/public/js/errors.js +122 -0
  58. package/public/js/event-bus.js +77 -0
  59. package/public/js/fetch-utils.js +171 -0
  60. package/public/js/file-handler.js +229 -0
  61. package/public/js/files.js +352 -0
  62. package/public/js/gateway-chat.js +538 -0
  63. package/public/js/logger.js +112 -0
  64. package/public/js/markdown.js +190 -0
  65. package/public/js/message-actions.js +431 -0
  66. package/public/js/message-renderer.js +288 -0
  67. package/public/js/missed-messages.js +235 -0
  68. package/public/js/mobile-debug.js +95 -0
  69. package/public/js/notifications.js +367 -0
  70. package/public/js/offline-queue.js +178 -0
  71. package/public/js/onboarding.js +543 -0
  72. package/public/js/panels.js +156 -0
  73. package/public/js/premium.js +412 -0
  74. package/public/js/realtime-voice.js +844 -0
  75. package/public/js/satellite-sync.js +256 -0
  76. package/public/js/satellite-ui.js +175 -0
  77. package/public/js/satellites.js +1516 -0
  78. package/public/js/settings.js +1087 -0
  79. package/public/js/shortcuts.js +381 -0
  80. package/public/js/split-chat.js +1234 -0
  81. package/public/js/split-resize.js +211 -0
  82. package/public/js/splitview.js +340 -0
  83. package/public/js/storage.js +408 -0
  84. package/public/js/streaming-handler.js +324 -0
  85. package/public/js/stt-settings.js +316 -0
  86. package/public/js/theme-generator.js +661 -0
  87. package/public/js/themes.js +164 -0
  88. package/public/js/timestamps.js +198 -0
  89. package/public/js/tts-settings.js +575 -0
  90. package/public/js/ui.js +267 -0
  91. package/public/js/update-notifier.js +143 -0
  92. package/public/js/utils/constants.js +165 -0
  93. package/public/js/utils/sanitize.js +93 -0
  94. package/public/js/utils/sse-parser.js +195 -0
  95. package/public/js/voice.js +883 -0
  96. package/public/manifest.json +58 -0
  97. package/public/moon_texture.jpg +0 -0
  98. package/public/sw.js +221 -0
  99. package/public/three.min.js +6 -0
  100. package/server/channel.js +529 -0
  101. package/server/chat.js +270 -0
  102. package/server/config-store.js +362 -0
  103. package/server/config.js +159 -0
  104. package/server/context.js +131 -0
  105. package/server/gateway-commands.js +211 -0
  106. package/server/gateway-proxy.js +318 -0
  107. package/server/index.js +22 -0
  108. package/server/logger.js +89 -0
  109. package/server/middleware/auth.js +188 -0
  110. package/server/middleware.js +218 -0
  111. package/server/openclaw-discover.js +308 -0
  112. package/server/premium/index.js +156 -0
  113. package/server/premium/license.js +140 -0
  114. package/server/realtime/bridge.js +837 -0
  115. package/server/realtime/index.js +349 -0
  116. package/server/realtime/tts-stream.js +446 -0
  117. package/server/routes/agents.js +564 -0
  118. package/server/routes/artifacts.js +174 -0
  119. package/server/routes/chat.js +311 -0
  120. package/server/routes/config-settings.js +345 -0
  121. package/server/routes/config.js +603 -0
  122. package/server/routes/files.js +307 -0
  123. package/server/routes/index.js +18 -0
  124. package/server/routes/media.js +451 -0
  125. package/server/routes/missed-messages.js +107 -0
  126. package/server/routes/premium.js +75 -0
  127. package/server/routes/push.js +156 -0
  128. package/server/routes/satellite.js +406 -0
  129. package/server/routes/status.js +251 -0
  130. package/server/routes/stt.js +35 -0
  131. package/server/routes/voice.js +260 -0
  132. package/server/routes/webhooks.js +203 -0
  133. package/server/routes.js +206 -0
  134. package/server/runtime-config.js +336 -0
  135. package/server/share.js +305 -0
  136. package/server/stt/faster-whisper.js +72 -0
  137. package/server/stt/groq.js +51 -0
  138. package/server/stt/index.js +196 -0
  139. package/server/stt/openai.js +49 -0
  140. package/server/sync.js +244 -0
  141. package/server/tailscale-https.js +175 -0
  142. package/server/tts.js +646 -0
  143. package/server/update-checker.js +172 -0
  144. package/server/utils/filename.js +129 -0
  145. package/server/utils.js +147 -0
  146. package/server/watchdog.js +318 -0
  147. package/server/websocket/broadcast.js +359 -0
  148. package/server/websocket/connections.js +339 -0
  149. package/server/websocket/index.js +215 -0
  150. package/server/websocket/routing.js +277 -0
  151. package/server/websocket/sync.js +102 -0
  152. package/server.js +404 -0
  153. package/utils/detect-tool-usage.js +93 -0
  154. package/utils/errors.js +158 -0
  155. package/utils/html-escape.js +84 -0
  156. package/utils/id-sanitize.js +94 -0
  157. package/utils/response.js +130 -0
  158. package/utils/with-retry.js +105 -0
@@ -0,0 +1,140 @@
1
+ /**
2
+ * License Validation Module
3
+ *
4
+ * Validates Uplink Premium license keys using HMAC-SHA256.
5
+ *
6
+ * Key format: UPL-XXXXX-XXXXX-XXXXX-XXXXX
7
+ *
8
+ * Structure:
9
+ * - First 10 base32 chars (6 bytes): random payload
10
+ * - Last 10 base32 chars (6 bytes): truncated HMAC-SHA256 tag
11
+ *
12
+ * The HMAC secret is derived from multiple components to avoid
13
+ * a single obvious string in the source code.
14
+ */
15
+
16
+ import { createHmac } from 'crypto';
17
+
18
+ // Key derivation components — split across the file to avoid easy grep
19
+ // These combine to form the HMAC signing key
20
+ const _a = Buffer.from('7570-6c69-6e6b', 'hex'); // part 1
21
+ const _b = Buffer.from('2e70-7265-6d69-756d', 'hex'); // part 2
22
+ const _c = Buffer.from('2e6c-6963-656e-7365', 'hex'); // part 3
23
+ const _d = Buffer.from('2e76-3031', 'hex'); // part 4
24
+
25
+ function _dk() {
26
+ // Derive signing key from components + additional mixing
27
+ const base = Buffer.concat([_a, _b, _c, _d]);
28
+ return createHmac('sha256', 'uplink-key-derivation')
29
+ .update(base)
30
+ .digest();
31
+ }
32
+
33
+ // Base32 alphabet (Crockford variant — no I/L/O/U to avoid confusion)
34
+ const B32 = '0123456789ABCDEFGHJKMNPQRSTVWXYZ';
35
+
36
+ function base32Encode(buffer) {
37
+ let result = '';
38
+ let bits = 0;
39
+ let value = 0;
40
+ for (const byte of buffer) {
41
+ value = (value << 8) | byte;
42
+ bits += 8;
43
+ while (bits >= 5) {
44
+ bits -= 5;
45
+ result += B32[(value >>> bits) & 0x1f];
46
+ }
47
+ }
48
+ if (bits > 0) {
49
+ result += B32[(value << (5 - bits)) & 0x1f];
50
+ }
51
+ return result;
52
+ }
53
+
54
+ function base32Decode(str) {
55
+ const lookup = {};
56
+ for (let i = 0; i < B32.length; i++) {
57
+ lookup[B32[i]] = i;
58
+ }
59
+ // Also accept lowercase
60
+ for (let i = 0; i < B32.length; i++) {
61
+ lookup[B32[i].toLowerCase()] = i;
62
+ }
63
+
64
+ let bits = 0;
65
+ let value = 0;
66
+ const bytes = [];
67
+ for (const char of str) {
68
+ const v = lookup[char];
69
+ if (v === undefined) return null;
70
+ value = (value << 5) | v;
71
+ bits += 5;
72
+ if (bits >= 8) {
73
+ bits -= 8;
74
+ bytes.push((value >>> bits) & 0xff);
75
+ }
76
+ }
77
+ return Buffer.from(bytes);
78
+ }
79
+
80
+ /**
81
+ * Validate a license key
82
+ * @param {string} key - License key (e.g. UPL-A1B2C-D3E4F-G5H6J-K7M8N)
83
+ * @returns {{ valid: boolean, error?: string }}
84
+ */
85
+ export function validateLicense(key) {
86
+ if (!key || typeof key !== 'string') {
87
+ return { valid: false, error: 'No license key provided' };
88
+ }
89
+
90
+ // Normalize: remove prefix, dashes, whitespace, uppercase
91
+ const cleaned = key.trim().toUpperCase().replace(/^UPL-/, '').replace(/[-\s]/g, '');
92
+
93
+ // Should be exactly 20 base32 chars (10 payload + 10 tag)
94
+ if (cleaned.length !== 20) {
95
+ return { valid: false, error: 'Invalid key format' };
96
+ }
97
+
98
+ // Split into payload and tag
99
+ const payloadStr = cleaned.slice(0, 10);
100
+ const tagStr = cleaned.slice(10);
101
+
102
+ const payload = base32Decode(payloadStr);
103
+ const tag = base32Decode(tagStr);
104
+
105
+ if (!payload || !tag) {
106
+ return { valid: false, error: 'Invalid key format' };
107
+ }
108
+
109
+ // Canonicalize: re-encode decoded bytes and compare to input
110
+ // This prevents padding bit variants from being treated as different keys
111
+ if (base32Encode(payload).slice(0, 10) !== payloadStr ||
112
+ base32Encode(tag).slice(0, 10) !== tagStr) {
113
+ return { valid: false, error: 'Invalid key format' };
114
+ }
115
+
116
+ // Compute expected HMAC tag
117
+ const signingKey = _dk();
118
+ const expectedTag = createHmac('sha256', signingKey)
119
+ .update(payload)
120
+ .digest()
121
+ .slice(0, 6); // Truncate to 6 bytes (matches tag length)
122
+
123
+ // Constant-time comparison
124
+ if (expectedTag.length !== tag.length) {
125
+ return { valid: false, error: 'Invalid license key' };
126
+ }
127
+
128
+ let diff = 0;
129
+ for (let i = 0; i < expectedTag.length; i++) {
130
+ diff |= expectedTag[i] ^ tag[i];
131
+ }
132
+
133
+ if (diff !== 0) {
134
+ return { valid: false, error: 'Invalid license key' };
135
+ }
136
+
137
+ return { valid: true };
138
+ }
139
+
140
+ export default { validateLicense };