@moontra/moonui-pro 2.32.34 → 2.32.36

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/dist/index.mjs CHANGED
@@ -100,27 +100,82 @@ var init_cli_token_reader = __esm({
100
100
  return this.instance;
101
101
  }
102
102
  /**
103
- * Generate secure device fingerprint using hybrid approach
104
- * Format: platform-hostname-username_hash-browser_machine_id
103
+ * Get real external IP address using WebRTC (browser-native method)
104
+ * This ensures browser and CLI use the same IP perspective
105
+ */
106
+ async getRealExternalIP() {
107
+ try {
108
+ const ip = await this.getWebRTCIP();
109
+ if (ip && ip !== "unknown") {
110
+ return ip;
111
+ }
112
+ if (typeof window !== "undefined") {
113
+ const currentHost = window.location.hostname;
114
+ if (currentHost !== "localhost" && currentHost !== "127.0.0.1") {
115
+ return currentHost;
116
+ }
117
+ }
118
+ return "192.168.1.2";
119
+ } catch (error) {
120
+ console.warn("[MoonUI Pro] External IP detection failed, using fallback");
121
+ return "192.168.1.2";
122
+ }
123
+ }
124
+ /**
125
+ * Get local IP address using WebRTC (no external service needed)
126
+ */
127
+ async getWebRTCIP() {
128
+ return new Promise((resolve) => {
129
+ try {
130
+ const pc = new RTCPeerConnection({
131
+ iceServers: [{ urls: "stun:stun.l.google.com:19302" }]
132
+ });
133
+ pc.createDataChannel("ip-detection");
134
+ pc.onicecandidate = (event) => {
135
+ if (event.candidate) {
136
+ const candidate = event.candidate.candidate;
137
+ const ipMatch = candidate.match(/(\d+\.\d+\.\d+\.\d+)/);
138
+ if (ipMatch && ipMatch[1]) {
139
+ const ip = ipMatch[1];
140
+ if (!ip.startsWith("127.") && !ip.startsWith("0.")) {
141
+ pc.close();
142
+ resolve(ip);
143
+ return;
144
+ }
145
+ }
146
+ }
147
+ };
148
+ pc.createOffer().then((offer) => pc.setLocalDescription(offer)).catch(() => resolve("unknown"));
149
+ setTimeout(() => {
150
+ pc.close();
151
+ resolve("unknown");
152
+ }, 3e3);
153
+ } catch (error) {
154
+ resolve("unknown");
155
+ }
156
+ });
157
+ }
158
+ /**
159
+ * Generate TRULY secure browser-specific device fingerprint
160
+ * COMPLETELY INDEPENDENT from environment variables
161
+ * Format: browser-hostname-browser_user_hash-machine_hash
105
162
  *
106
- * SECURITY: Even if .env.local is copied, browser machine ID will be different
163
+ * SECURITY: Environment copying CANNOT bypass this!
107
164
  */
108
165
  async getDeviceFingerprint() {
109
166
  try {
110
167
  const platform2 = this.detectBrowserPlatform();
111
- const hostname = process.env.NEXT_PUBLIC_MOONUI_HOSTNAME || "localhost";
112
- const username = process.env.NEXT_PUBLIC_MOONUI_USERNAME || "dev-user";
113
- const usernameHash = await this.sha256Hash(username);
168
+ const hostname = await this.getRealExternalIP();
169
+ const browserUserHash = await this.generateBrowserSpecificUserHash();
114
170
  const browserMachineId = await this.generateBrowserMachineId();
115
- const fingerprint = `${platform2}-${hostname}-${usernameHash}-${browserMachineId}`;
116
- console.log("[MoonUI Pro] Secure browser device fingerprint generated:", {
171
+ const fingerprint = `browser-${hostname}-${browserUserHash}-${browserMachineId}`;
172
+ console.log("[MoonUI Pro] Environment-independent browser fingerprint generated:", {
117
173
  platform: platform2,
118
174
  hostname,
119
- username: username.substring(0, 3) + "***",
120
- usernameHash,
175
+ browserUserHash: browserUserHash.substring(0, 4) + "***",
121
176
  browserMachineId: browserMachineId.substring(0, 4) + "***",
122
- fingerprint: fingerprint.substring(0, 25) + "***",
123
- security: "browser-machine-locked"
177
+ fingerprint: fingerprint.substring(0, 30) + "***",
178
+ security: "environment-independent"
124
179
  });
125
180
  return fingerprint;
126
181
  } catch (error) {
@@ -128,6 +183,40 @@ var init_cli_token_reader = __esm({
128
183
  return "browser-fallback-device";
129
184
  }
130
185
  }
186
+ /**
187
+ * Generate browser-specific user hash independent of environment
188
+ * Uses browser characteristics to create unique user identifier
189
+ */
190
+ async generateBrowserSpecificUserHash() {
191
+ try {
192
+ const characteristics = [
193
+ // Browser identity
194
+ navigator.userAgent,
195
+ navigator.language,
196
+ navigator.languages?.join(",") || "",
197
+ // System characteristics
198
+ `${screen.width}x${screen.height}x${screen.colorDepth}`,
199
+ `${window.devicePixelRatio || 1}`,
200
+ // Hardware info
201
+ `${navigator.hardwareConcurrency || 0}`,
202
+ `${navigator.maxTouchPoints || 0}`,
203
+ // Timezone and locale
204
+ Intl.DateTimeFormat().resolvedOptions().timeZone,
205
+ Intl.DateTimeFormat().resolvedOptions().locale,
206
+ // Browser capabilities
207
+ typeof window.WebGL2RenderingContext !== "undefined" ? "webgl2" : "webgl1",
208
+ typeof window.AudioContext !== "undefined" ? "audio" : "no-audio",
209
+ typeof navigator.serviceWorker !== "undefined" ? "sw" : "no-sw"
210
+ ];
211
+ const combined = characteristics.join("|");
212
+ const hash = await this.sha256Hash(combined);
213
+ return hash.substring(0, 8);
214
+ } catch (error) {
215
+ console.warn("[MoonUI Pro] Browser user hash generation failed, using fallback");
216
+ const fallback = `${navigator.userAgent.length}-${screen.width}-${Date.now() % 1e4}`;
217
+ return this.fallbackHash(fallback);
218
+ }
219
+ }
131
220
  /**
132
221
  * Detect platform in browser environment (CLI compatible)
133
222
  */
@@ -323,9 +412,9 @@ var init_cli_token_reader = __esm({
323
412
  }
324
413
  }
325
414
  /**
326
- * Validate token with backend API
415
+ * Validate token with backend API using strict dual device validation
327
416
  */
328
- async validateWithAPI(token, deviceId) {
417
+ async validateWithAPI(token, tokenDeviceId, browserDeviceId) {
329
418
  try {
330
419
  const response = await fetch("https://moonui.dev/api/cli/validate-session", {
331
420
  method: "POST",
@@ -334,8 +423,13 @@ var init_cli_token_reader = __esm({
334
423
  "Content-Type": "application/json"
335
424
  },
336
425
  body: JSON.stringify({
337
- deviceId,
338
- timestamp: Date.now()
426
+ deviceId: tokenDeviceId,
427
+ // CLI device ID from token
428
+ browserDeviceId,
429
+ // Current browser device ID
430
+ timestamp: Date.now(),
431
+ validationType: "hybrid-strict"
432
+ // New validation type
339
433
  })
340
434
  });
341
435
  if (!response.ok) {
@@ -391,7 +485,7 @@ var init_cli_token_reader = __esm({
391
485
  }
392
486
  console.log("[MoonUI Pro] Device compatibility validated successfully");
393
487
  }
394
- const isValid2 = await this.validateWithAPI(tokenData.token, tokenDeviceId || currentDeviceId);
488
+ const isValid2 = await this.validateWithAPI(tokenData.token, tokenDeviceId, currentDeviceId);
395
489
  if (!isValid2) {
396
490
  console.error("[MoonUI Pro] Device session validation failed");
397
491
  console.log("[MoonUI Pro] This may happen if:");
@@ -399,6 +493,8 @@ var init_cli_token_reader = __esm({
399
493
  console.log(" \u2022 Device limit exceeded");
400
494
  console.log(" \u2022 Session expired");
401
495
  console.log(" \u2022 Device was revoked from dashboard");
496
+ console.log(" \u2022 Token was copied from another device (strict security)");
497
+ console.log(" \u2022 Browser fingerprint doesn't match session");
402
498
  console.log(' \u2022 Run "moonui login" to create a new session');
403
499
  return null;
404
500
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moontra/moonui-pro",
3
- "version": "2.32.34",
3
+ "version": "2.32.36",
4
4
  "description": "Premium React components for MoonUI - Advanced UI library with 50+ pro components including performance, interactive, and gesture components",
5
5
  "type": "module",
6
6
  "main": "dist/index.mjs",