@moontra/moonui-pro 2.32.32 → 2.32.34

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,39 +100,27 @@ var init_cli_token_reader = __esm({
100
100
  return this.instance;
101
101
  }
102
102
  /**
103
- * Generate device fingerprint compatible with CLI format
104
- * Format: platform-hostname-username_hash (8 chars)
103
+ * Generate secure device fingerprint using hybrid approach
104
+ * Format: platform-hostname-username_hash-browser_machine_id
105
+ *
106
+ * SECURITY: Even if .env.local is copied, browser machine ID will be different
105
107
  */
106
108
  async getDeviceFingerprint() {
107
109
  try {
108
- let platform2 = "unknown";
109
- if (typeof window !== "undefined") {
110
- const userAgent = navigator.userAgent.toLowerCase();
111
- const navigatorPlatform = navigator.platform.toLowerCase();
112
- if (navigatorPlatform.includes("mac") || userAgent.includes("mac")) {
113
- platform2 = "darwin";
114
- } else if (navigatorPlatform.includes("win") || userAgent.includes("windows")) {
115
- platform2 = "win32";
116
- } else if (navigatorPlatform.includes("linux") || userAgent.includes("linux")) {
117
- platform2 = "linux";
118
- }
119
- }
120
- let hostname = process.env.NEXT_PUBLIC_MOONUI_HOSTNAME || "localhost";
121
- if (typeof window !== "undefined" && !process.env.NEXT_PUBLIC_MOONUI_HOSTNAME) {
122
- if (window.location.hostname !== "localhost" && window.location.hostname !== "127.0.0.1") {
123
- hostname = window.location.hostname;
124
- }
125
- }
110
+ const platform2 = this.detectBrowserPlatform();
111
+ const hostname = process.env.NEXT_PUBLIC_MOONUI_HOSTNAME || "localhost";
126
112
  const username = process.env.NEXT_PUBLIC_MOONUI_USERNAME || "dev-user";
127
113
  const usernameHash = await this.sha256Hash(username);
128
- const fingerprint = `${platform2}-${hostname}-${usernameHash}`;
129
- console.log("[MoonUI Pro] Browser device fingerprint generated:", {
114
+ const browserMachineId = await this.generateBrowserMachineId();
115
+ const fingerprint = `${platform2}-${hostname}-${usernameHash}-${browserMachineId}`;
116
+ console.log("[MoonUI Pro] Secure browser device fingerprint generated:", {
130
117
  platform: platform2,
131
118
  hostname,
132
119
  username: username.substring(0, 3) + "***",
133
- // Partial logging for privacy
134
120
  usernameHash,
135
- fingerprint
121
+ browserMachineId: browserMachineId.substring(0, 4) + "***",
122
+ fingerprint: fingerprint.substring(0, 25) + "***",
123
+ security: "browser-machine-locked"
136
124
  });
137
125
  return fingerprint;
138
126
  } catch (error) {
@@ -140,6 +128,155 @@ var init_cli_token_reader = __esm({
140
128
  return "browser-fallback-device";
141
129
  }
142
130
  }
131
+ /**
132
+ * Detect platform in browser environment (CLI compatible)
133
+ */
134
+ detectBrowserPlatform() {
135
+ if (typeof window === "undefined")
136
+ return "unknown";
137
+ const userAgent = navigator.userAgent.toLowerCase();
138
+ if (userAgent.includes("mac") || userAgent.includes("darwin")) {
139
+ return "darwin";
140
+ } else if (userAgent.includes("win") || userAgent.includes("windows")) {
141
+ return "win32";
142
+ } else if (userAgent.includes("linux") || userAgent.includes("x11")) {
143
+ return "linux";
144
+ }
145
+ return "unknown";
146
+ }
147
+ /**
148
+ * Generate browser-specific machine ID using multiple browser characteristics
149
+ * This prevents token sharing between different browsers/machines
150
+ */
151
+ async generateBrowserMachineId() {
152
+ if (typeof window === "undefined") {
153
+ return "ssr-fallback";
154
+ }
155
+ try {
156
+ const characteristics = [];
157
+ characteristics.push(`${screen.width}x${screen.height}`);
158
+ characteristics.push(`${screen.colorDepth}`);
159
+ characteristics.push(`${window.devicePixelRatio || 1}`);
160
+ characteristics.push(navigator.userAgent);
161
+ characteristics.push(navigator.language);
162
+ characteristics.push(`${navigator.hardwareConcurrency || 0}`);
163
+ characteristics.push(`${navigator.maxTouchPoints || 0}`);
164
+ characteristics.push(Intl.DateTimeFormat().resolvedOptions().timeZone);
165
+ const canvasFingerprint = await this.generateCanvasFingerprint();
166
+ characteristics.push(canvasFingerprint);
167
+ const webglFingerprint = this.generateWebGLFingerprint();
168
+ characteristics.push(webglFingerprint);
169
+ const audioFingerprint = await this.generateAudioFingerprint();
170
+ characteristics.push(audioFingerprint);
171
+ const combined = characteristics.join("|");
172
+ const machineHash = await this.sha256Hash(combined);
173
+ return machineHash.substring(0, 6);
174
+ } catch (error) {
175
+ console.warn("[MoonUI Pro] Machine ID generation fallback:", error);
176
+ const fallback = `${screen.width}-${navigator.userAgent.length}-${navigator.language}`;
177
+ const fallbackHash = await this.sha256Hash(fallback);
178
+ return fallbackHash.substring(0, 6);
179
+ }
180
+ }
181
+ /**
182
+ * Generate canvas fingerprint
183
+ */
184
+ async generateCanvasFingerprint() {
185
+ try {
186
+ const canvas = document.createElement("canvas");
187
+ const ctx = canvas.getContext("2d");
188
+ if (!ctx)
189
+ return "no-canvas";
190
+ ctx.textBaseline = "top";
191
+ ctx.font = "14px Arial";
192
+ ctx.fillStyle = "#f60";
193
+ ctx.fillRect(125, 1, 62, 20);
194
+ ctx.fillStyle = "#069";
195
+ ctx.fillText("MoonUI Browser Fingerprint \u{1F510}", 2, 15);
196
+ ctx.fillStyle = "rgba(102, 204, 0, 0.7)";
197
+ ctx.fillRect(45, 25, 80, 15);
198
+ const dataURL = canvas.toDataURL();
199
+ const hash = await this.sha256Hash(dataURL);
200
+ return hash.substring(0, 8);
201
+ } catch (error) {
202
+ return "canvas-error";
203
+ }
204
+ }
205
+ /**
206
+ * Generate WebGL fingerprint
207
+ */
208
+ generateWebGLFingerprint() {
209
+ try {
210
+ const canvas = document.createElement("canvas");
211
+ const gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");
212
+ if (!gl)
213
+ return "no-webgl";
214
+ const debugInfo = gl.getExtension("WEBGL_debug_renderer_info");
215
+ const vendor = debugInfo ? gl.getParameter(debugInfo.UNMASKED_VENDOR_WEBGL) : "unknown";
216
+ const renderer = debugInfo ? gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL) : "unknown";
217
+ return `${vendor}-${renderer}`.replace(/\s+/g, "-").substring(0, 16);
218
+ } catch (error) {
219
+ return "webgl-error";
220
+ }
221
+ }
222
+ /**
223
+ * Generate audio context fingerprint
224
+ */
225
+ async generateAudioFingerprint() {
226
+ try {
227
+ const AudioContext = window.AudioContext || window.webkitAudioContext;
228
+ if (!AudioContext)
229
+ return "no-audio";
230
+ const context = new AudioContext();
231
+ const oscillator = context.createOscillator();
232
+ const gain = context.createGain();
233
+ oscillator.type = "triangle";
234
+ oscillator.frequency.setValueAtTime(1e3, context.currentTime);
235
+ gain.gain.setValueAtTime(0.01, context.currentTime);
236
+ oscillator.connect(gain);
237
+ gain.connect(context.destination);
238
+ const audioFingerprint = [
239
+ context.sampleRate.toString(),
240
+ context.destination.maxChannelCount.toString(),
241
+ context.destination.channelCount.toString(),
242
+ context.baseLatency ? context.baseLatency.toString() : "0",
243
+ context.outputLatency ? context.outputLatency.toString() : "0"
244
+ ].join("-");
245
+ try {
246
+ context.close();
247
+ } catch {
248
+ }
249
+ return audioFingerprint.substring(0, 8);
250
+ } catch (error) {
251
+ return "audio-error";
252
+ }
253
+ }
254
+ /**
255
+ * Validate device compatibility (CLI vs Browser)
256
+ * CLI: platform-hostname-userHash-macHash
257
+ * Browser: platform-hostname-userHash-browserHash
258
+ * Compatible if first 3 parts match
259
+ */
260
+ validateDeviceCompatibility(tokenDeviceId, currentDeviceId) {
261
+ const tokenParts = tokenDeviceId.split("-");
262
+ const currentParts = currentDeviceId.split("-");
263
+ if (tokenParts.length < 3 || currentParts.length < 3) {
264
+ return { compatible: false, reason: "Invalid device ID format" };
265
+ }
266
+ const platformMatch = tokenParts[0] === currentParts[0];
267
+ const hostnameMatch = tokenParts[1] === currentParts[1];
268
+ const userHashMatch = tokenParts[2] === currentParts[2];
269
+ if (!platformMatch) {
270
+ return { compatible: false, reason: "Platform mismatch (different OS)" };
271
+ }
272
+ if (!hostnameMatch) {
273
+ return { compatible: false, reason: "Hostname mismatch (different machine)" };
274
+ }
275
+ if (!userHashMatch) {
276
+ return { compatible: false, reason: "User account mismatch" };
277
+ }
278
+ return { compatible: true };
279
+ }
143
280
  /**
144
281
  * SHA256 hash function for consistency with CLI
145
282
  * Returns first 8 characters of SHA256 hex digest
@@ -232,21 +369,27 @@ var init_cli_token_reader = __esm({
232
369
  }
233
370
  const currentDeviceId = await this.getDeviceFingerprint();
234
371
  const tokenDeviceId = tokenData.deviceId;
235
- console.log("[MoonUI Pro] Device validation check:", {
236
- currentDevice: currentDeviceId,
237
- tokenDevice: tokenDeviceId,
238
- matches: currentDeviceId === tokenDeviceId
372
+ console.log("[MoonUI Pro] Hybrid device compatibility check:", {
373
+ currentDevice: currentDeviceId.substring(0, 25) + "***",
374
+ tokenDevice: tokenDeviceId.substring(0, 25) + "***"
239
375
  });
240
- if (tokenDeviceId && currentDeviceId !== tokenDeviceId) {
241
- console.error("[MoonUI Pro] Device mismatch detected!");
242
- console.error("[MoonUI Pro] This token was created for a different device");
243
- console.log("[MoonUI Pro] Token device:", tokenDeviceId);
244
- console.log("[MoonUI Pro] Current device:", currentDeviceId);
245
- console.log("[MoonUI Pro] Solutions:");
246
- console.log(' \u2022 Run "moonui login" on this device to create a new session');
247
- console.log(" \u2022 Use the correct device where this token was generated");
248
- console.log(" \u2022 Contact support for multi-device licensing options");
249
- return null;
376
+ if (tokenDeviceId) {
377
+ const compatibility = this.validateDeviceCompatibility(tokenDeviceId, currentDeviceId);
378
+ if (!compatibility.compatible) {
379
+ console.error("[MoonUI Pro] Device compatibility check failed!");
380
+ console.error("[MoonUI Pro] Reason:", compatibility.reason);
381
+ console.error("[MoonUI Pro] This indicates:");
382
+ console.log(" \u2022 Token was created on a different machine or user account");
383
+ console.log(" \u2022 .env.local file may have been copied from another device");
384
+ console.log(" \u2022 Different hostname or user profile detected");
385
+ console.log("[MoonUI Pro] Solutions:");
386
+ console.log(' \u2022 Run "moonui login" on this device to create a new session');
387
+ console.log(" \u2022 Ensure you are using the correct user account");
388
+ console.log(" \u2022 Verify hostname matches the original login device");
389
+ console.log(" \u2022 Contact support for multi-device licensing options");
390
+ return null;
391
+ }
392
+ console.log("[MoonUI Pro] Device compatibility validated successfully");
250
393
  }
251
394
  const isValid2 = await this.validateWithAPI(tokenData.token, tokenDeviceId || currentDeviceId);
252
395
  if (!isValid2) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moontra/moonui-pro",
3
- "version": "2.32.32",
3
+ "version": "2.32.34",
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",