@buoy-gg/license 7.0.22 → 7.0.24

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 (68) hide show
  1. package/LICENSE +46 -0
  2. package/lib/commonjs/DeviceRegistrationModal.js +1 -189
  3. package/lib/commonjs/LicenseManager.js +14 -610
  4. package/lib/commonjs/api.js +1 -172
  5. package/lib/commonjs/cacheSignature.js +15 -0
  6. package/lib/commonjs/config.js +16 -28
  7. package/lib/commonjs/device-info.js +1 -93
  8. package/lib/commonjs/device-info.web.js +1 -227
  9. package/lib/commonjs/fingerprint.js +1 -30
  10. package/lib/commonjs/fingerprint.web.js +1 -30
  11. package/lib/commonjs/hooks.js +13 -120
  12. package/lib/commonjs/index.js +17 -106
  13. package/lib/commonjs/index.web.js +17 -98
  14. package/lib/commonjs/tier.js +16 -0
  15. package/lib/commonjs/types.js +1 -1
  16. package/lib/commonjs/weekendPro.js +15 -41
  17. package/lib/module/DeviceRegistrationModal.js +1 -185
  18. package/lib/module/LicenseManager.js +14 -607
  19. package/lib/module/api.js +1 -165
  20. package/lib/module/cacheSignature.js +15 -0
  21. package/lib/module/config.js +16 -24
  22. package/lib/module/device-info.js +1 -87
  23. package/lib/module/device-info.web.js +1 -220
  24. package/lib/module/fingerprint.js +1 -10
  25. package/lib/module/fingerprint.web.js +1 -10
  26. package/lib/module/hooks.js +13 -114
  27. package/lib/module/index.js +15 -54
  28. package/lib/module/index.web.js +15 -52
  29. package/lib/module/tier.js +16 -0
  30. package/lib/module/types.js +1 -1
  31. package/lib/module/weekendPro.js +15 -37
  32. package/lib/typescript/commonjs/LicenseManager.d.ts +31 -6
  33. package/lib/typescript/commonjs/LicenseManager.d.ts.map +1 -1
  34. package/lib/typescript/commonjs/cacheSignature.d.ts +42 -0
  35. package/lib/typescript/commonjs/cacheSignature.d.ts.map +1 -0
  36. package/lib/typescript/commonjs/config.d.ts +62 -1
  37. package/lib/typescript/commonjs/config.d.ts.map +1 -1
  38. package/lib/typescript/commonjs/hooks.d.ts +27 -5
  39. package/lib/typescript/commonjs/hooks.d.ts.map +1 -1
  40. package/lib/typescript/commonjs/index.d.ts +20 -2
  41. package/lib/typescript/commonjs/index.d.ts.map +1 -1
  42. package/lib/typescript/commonjs/index.web.d.ts +20 -2
  43. package/lib/typescript/commonjs/index.web.d.ts.map +1 -1
  44. package/lib/typescript/commonjs/tier.d.ts +55 -0
  45. package/lib/typescript/commonjs/tier.d.ts.map +1 -0
  46. package/lib/typescript/commonjs/types.d.ts +44 -0
  47. package/lib/typescript/commonjs/types.d.ts.map +1 -1
  48. package/lib/typescript/commonjs/weekendPro.d.ts +30 -7
  49. package/lib/typescript/commonjs/weekendPro.d.ts.map +1 -1
  50. package/lib/typescript/module/LicenseManager.d.ts +31 -6
  51. package/lib/typescript/module/LicenseManager.d.ts.map +1 -1
  52. package/lib/typescript/module/cacheSignature.d.ts +42 -0
  53. package/lib/typescript/module/cacheSignature.d.ts.map +1 -0
  54. package/lib/typescript/module/config.d.ts +62 -1
  55. package/lib/typescript/module/config.d.ts.map +1 -1
  56. package/lib/typescript/module/hooks.d.ts +27 -5
  57. package/lib/typescript/module/hooks.d.ts.map +1 -1
  58. package/lib/typescript/module/index.d.ts +20 -2
  59. package/lib/typescript/module/index.d.ts.map +1 -1
  60. package/lib/typescript/module/index.web.d.ts +20 -2
  61. package/lib/typescript/module/index.web.d.ts.map +1 -1
  62. package/lib/typescript/module/tier.d.ts +55 -0
  63. package/lib/typescript/module/tier.d.ts.map +1 -0
  64. package/lib/typescript/module/types.d.ts +44 -0
  65. package/lib/typescript/module/types.d.ts.map +1 -1
  66. package/lib/typescript/module/weekendPro.d.ts +30 -7
  67. package/lib/typescript/module/weekendPro.d.ts.map +1 -1
  68. package/package.json +7 -4
package/lib/module/api.js CHANGED
@@ -1,165 +1 @@
1
- "use strict";
2
-
3
- /**
4
- * Keygen REST API client for React Buoy
5
- *
6
- * License validation + device registration for visibility.
7
- * No limits enforced - we trust our customers.
8
- */
9
-
10
- import { KEYGEN_CONFIG } from "./config.js";
11
- const {
12
- accountId,
13
- productToken,
14
- apiUrl
15
- } = KEYGEN_CONFIG;
16
-
17
- /**
18
- * Base headers for Keygen API requests
19
- */
20
- function getBaseHeaders() {
21
- return {
22
- "Content-Type": "application/vnd.api+json",
23
- Accept: "application/vnd.api+json"
24
- };
25
- }
26
-
27
- /**
28
- * Headers for license-authenticated API requests
29
- */
30
- function getLicenseAuthHeaders(licenseKey) {
31
- return {
32
- ...getBaseHeaders(),
33
- Authorization: `License ${licenseKey}`
34
- };
35
- }
36
-
37
- /**
38
- * Headers for product token authenticated API requests
39
- */
40
- function getProductTokenHeaders() {
41
- return {
42
- ...getBaseHeaders(),
43
- Authorization: `Bearer ${productToken}`
44
- };
45
- }
46
-
47
- /**
48
- * Validate a license key with Keygen
49
- */
50
- export async function validateLicense(licenseKey) {
51
- const url = `${apiUrl}/${accountId}/licenses/actions/validate-key`;
52
- const body = {
53
- meta: {
54
- key: licenseKey
55
- }
56
- };
57
-
58
- // Note: validate-key endpoint doesn't need Authorization header
59
- // The license key in the body is the authentication
60
- const response = await fetch(url, {
61
- method: "POST",
62
- headers: getBaseHeaders(),
63
- body: JSON.stringify(body)
64
- });
65
- if (!response.ok) {
66
- const errorData = await response.json();
67
- const errorMessage = errorData.errors?.[0]?.detail || `HTTP ${response.status}`;
68
- throw new Error(errorMessage);
69
- }
70
- return await response.json();
71
- }
72
-
73
- /**
74
- * Activate a machine for a license (for visibility, not enforcement)
75
- */
76
- export async function activateMachine(licenseId, licenseKey, fingerprint, name, metadata) {
77
- const url = `${apiUrl}/${accountId}/machines`;
78
- const body = {
79
- data: {
80
- type: "machines",
81
- attributes: {
82
- fingerprint,
83
- name,
84
- metadata: metadata || {}
85
- },
86
- relationships: {
87
- license: {
88
- data: {
89
- type: "licenses",
90
- id: licenseId
91
- }
92
- }
93
- }
94
- }
95
- };
96
-
97
- // Try license key auth first
98
- let response = await fetch(url, {
99
- method: "POST",
100
- headers: getLicenseAuthHeaders(licenseKey),
101
- body: JSON.stringify(body)
102
- });
103
-
104
- // If license key auth not allowed, retry with product token
105
- if (!response.ok) {
106
- const errorData = await response.json();
107
- const errorMessage = errorData.errors?.[0]?.detail || "";
108
- const errorCode = errorData.errors?.[0]?.code;
109
- if (errorMessage.toLowerCase().includes("authentication is not allowed by policy")) {
110
- response = await fetch(url, {
111
- method: "POST",
112
- headers: getProductTokenHeaders(),
113
- body: JSON.stringify(body)
114
- });
115
- } else if (errorCode === "FINGERPRINT_TAKEN") {
116
- // Device already registered - this is fine, not an error
117
- throw new Error("FINGERPRINT_TAKEN");
118
- } else if (errorCode === "MACHINE_LIMIT_EXCEEDED") {
119
- // Don't block, just log - we trust our customers
120
- //console.log("[Buoy] Machine limit reached but not enforcing - trust mode");
121
- throw new Error("MACHINE_LIMIT_EXCEEDED");
122
- } else {
123
- throw new Error(errorMessage);
124
- }
125
- }
126
- if (!response.ok) {
127
- const errorData = await response.json();
128
- const errorCode = errorData.errors?.[0]?.code;
129
- if (errorCode === "FINGERPRINT_TAKEN") {
130
- throw new Error("FINGERPRINT_TAKEN");
131
- }
132
- if (errorCode === "MACHINE_LIMIT_EXCEEDED") {
133
- // console.log("[Buoy] Machine limit reached but not enforcing - trust mode");
134
- throw new Error("MACHINE_LIMIT_EXCEEDED");
135
- }
136
- const errorMessage = errorData.errors?.[0]?.detail || `HTTP ${response.status}`;
137
- throw new Error(errorMessage);
138
- }
139
- return response.json();
140
- }
141
-
142
- /**
143
- * Parse validation response into a simpler result
144
- * Note: response.data can be null when license is invalid (e.g., NOT_FOUND)
145
- */
146
- export function parseValidationResult(response) {
147
- const {
148
- meta,
149
- data
150
- } = response;
151
- return {
152
- valid: meta.valid,
153
- code: meta.code,
154
- detail: meta.detail,
155
- // data can be null for invalid licenses
156
- metadata: data?.attributes?.metadata
157
- };
158
- }
159
-
160
- /**
161
- * Check if a validation code indicates a fatal error (license invalid)
162
- */
163
- export function isFatalLicenseError(code) {
164
- return ["NOT_FOUND", "SUSPENDED", "EXPIRED", "BANNED", "PRODUCT_SCOPE_MISMATCH"].includes(code);
165
- }
1
+ "use strict";import{KEYGEN_CONFIG as T}from"./config.js";const{accountId:l,productToken:h,apiUrl:N}=T;function E(){return{"Content-Type":"application/vnd.api+json",Accept:"application/vnd.api+json"}}function I(e){return{...E(),Authorization:`License ${e}`}}function w(){return{...E(),Authorization:`Bearer ${h}`}}export async function validateLicense(e){const t=`${N}/${l}/licenses/actions/validate-key`;const a={meta:{key:e}};const o=await fetch(t,{method:"POST",headers:E(),body:JSON.stringify(a)});if(!o.ok){const d=await o.json();const i=d.errors?.[0]?.detail||`HTTP ${o.status}`;throw new Error(i)}return await o.json()}export async function activateMachine(e,t,a,o,d){const i=`${N}/${l}/machines`;const u={data:{type:"machines",attributes:{fingerprint:a,name:o,metadata:d||{}},relationships:{license:{data:{type:"licenses",id:e}}}}};let r=await fetch(i,{method:"POST",headers:I(t),body:JSON.stringify(u)});if(!r.ok){const n=await r.json();const s=n.errors?.[0]?.detail||"";const c=n.errors?.[0]?.code;if(s.toLowerCase().includes("authentication is not allowed by policy")){r=await fetch(i,{method:"POST",headers:w(),body:JSON.stringify(u)})}else if(c==="FINGERPRINT_TAKEN"){throw new Error("FINGERPRINT_TAKEN")}else if(c==="MACHINE_LIMIT_EXCEEDED"){throw new Error("MACHINE_LIMIT_EXCEEDED")}else{throw new Error(s)}}if(!r.ok){const n=await r.json();const s=n.errors?.[0]?.code;if(s==="FINGERPRINT_TAKEN"){throw new Error("FINGERPRINT_TAKEN")}if(s==="MACHINE_LIMIT_EXCEEDED"){throw new Error("MACHINE_LIMIT_EXCEEDED")}const c=n.errors?.[0]?.detail||`HTTP ${r.status}`;throw new Error(c)}return r.json()}export function parseValidationResult(e){const{meta:t,data:a}=e;return{valid:t.valid,code:t.code,detail:t.detail,metadata:a?.attributes?.metadata}}export function isFatalLicenseError(e){return["NOT_FOUND","SUSPENDED","EXPIRED","BANNED","PRODUCT_SCOPE_MISMATCH"].includes(e)}
@@ -0,0 +1,15 @@
1
+ "use strict";/*!
2
+ * PROPRIETARY — Buoy Pro license enforcement. NOT open source.
3
+ *
4
+ * Copyright (c) Buoy. All rights reserved. Licensed under the Buoy EULA
5
+ * (https://buoy.gg/terms), not an OSS license.
6
+ *
7
+ * This file is part of the technological measure that controls access to paid
8
+ * Buoy Pro features. Modifying, patching, aliasing, stubbing, or otherwise
9
+ * altering it so that Pro features unlock without a valid license is a breach
10
+ * of the EULA and, in the United States, circumvention of an access control
11
+ * under 17 U.S.C. § 1201 — which applies whether or not any code is copied.
12
+ *
13
+ * Pro is $9/mo, and is free for everyone every weekend. Buy a key at
14
+ * https://buoy.gg or use it free on Saturday and Sunday.
15
+ */const u="v2";const g=["v1"];const f="buoy.gg/pro:9f3c1d7a4b2e:license-cache";const S="\0";function s(t,i){let n=i>>>0;for(let r=0;r<t.length;r++){n^=t.charCodeAt(r);n=Math.imul(n,16777619)>>>0}return n>>>0}function l(t,i){const n=[i,t.licenseKey,t.licenseId,t.isPro?"1":"0",t.expiresAt??"",String(t.cachedAt)];if(i!=="v1"){n.push(t.tier??"")}n.push(f);return n.join(S)}function e(t,i){const n=l(t,i);const r=s(n,2166136261);const o=s(n,2135587861);return`${i}.${r.toString(16)}${o.toString(16)}`}export function cacheSignature(t){return e(t,u)}export function signCache(t){return{...t,sig:cacheSignature(t)}}export function verifyCacheSignature(t){if(!t||typeof t.sig!=="string"||t.sig.length===0){return false}if(t.sig===cacheSignature(t))return true;return g.some(i=>t.sig.startsWith(`${i}.`)&&t.sig===e(t,i))}
@@ -1,24 +1,16 @@
1
- "use strict";
2
-
3
- /**
4
- * Keygen configuration for React Buoy
5
- */
6
-
7
- export const KEYGEN_CONFIG = {
8
- accountId: "b0eba0e8-e904-4906-b644-38f9aab57bed",
9
- productId: "1037431d-b2fe-48db-aca9-10c5e9c4d944",
10
- // Product token - read-only, safe to embed in SDK
11
- productToken: "prod-4467c14b75b715e91884945cd3e69705846ccbce7dd5e380236a1ab3bc03139fv3",
12
- apiUrl: "https://api.keygen.sh/v1/accounts"
13
- };
14
-
15
- // Cache duration: 30 days in milliseconds
16
- export const LICENSE_CACHE_DURATION = 30 * 24 * 60 * 60 * 1000;
17
-
18
- // How often to revalidate when app is active (24 hours)
19
- // We trust our customers - this is just for usage analytics
20
- export const LICENSE_REVALIDATION_INTERVAL = 24 * 60 * 60 * 1000;
21
-
22
- // Storage key for cached license
23
- // IMPORTANT: Use only file-safe characters (no / or special chars)
24
- export const LICENSE_STORAGE_KEY = "buoy-gg-license";
1
+ "use strict";/*!
2
+ * PROPRIETARY — Buoy Pro license enforcement. NOT open source.
3
+ *
4
+ * Copyright (c) Buoy. All rights reserved. Licensed under the Buoy EULA
5
+ * (https://buoy.gg/terms), not an OSS license.
6
+ *
7
+ * This file configures the technological measure that controls access to paid
8
+ * Buoy Pro features. Modifying, patching, aliasing, stubbing, or otherwise
9
+ * altering it — including repointing `apiUrl` at a stand-in license server — so
10
+ * that Pro features unlock without a valid license is a breach of the EULA and,
11
+ * in the United States, circumvention of an access control under 17 U.S.C.
12
+ * § 1201, which applies whether or not any code is copied.
13
+ *
14
+ * Pro is $9/mo, and is free for everyone every weekend. Buy a key at
15
+ * https://buoy.gg or use it free on Saturday and Sunday.
16
+ */export const KEYGEN_CONFIG={accountId:"b0eba0e8-e904-4906-b644-38f9aab57bed",productId:"bf67cb43-eeef-40ca-b308-e6e1b22c0eaa",productToken:"prod-4467c14b75b715e91884945cd3e69705846ccbce7dd5e380236a1ab3bc03139fv3",apiUrl:"https://api.keygen.sh/v1/accounts"};export const KEYGEN_POLICIES={free:"394e3351-1249-4f73-807a-703408604c0e",solo:"fa5d3c8f-5379-40f1-b63e-ab8a974b2f28",business:"690c2212-8e54-426f-b4b4-002ee1c0ae2b"};export const LICENSE_CACHE_DURATION=30*24*60*60*1e3;export const LICENSE_REVALIDATION_INTERVAL=24*60*60*1e3;export const LICENSE_STORAGE_KEY="buoy-gg-license";export const ANONYMOUS_TIER_ENABLED=false;
@@ -1,87 +1 @@
1
- "use strict";
2
-
3
- /**
4
- * Pure JS device info utilities
5
- *
6
- * No native module dependencies - uses only React Native core APIs.
7
- * Device fingerprint is a generated UUID stored alongside license data.
8
- */
9
-
10
- import { Platform } from "react-native";
11
-
12
- /**
13
- * Generate a UUID v4
14
- */
15
- export function generateUUID() {
16
- return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, c => {
17
- const r = Math.random() * 16 | 0;
18
- const v = c === "x" ? r : r & 0x3 | 0x8;
19
- return v.toString(16);
20
- });
21
- }
22
-
23
- /**
24
- * Check if running on a simulator/emulator using Platform constants
25
- */
26
- export function isSimulator() {
27
- if (Platform.OS === "ios") {
28
- // On iOS simulator, we can check various indicators
29
- const constants = Platform.constants;
30
-
31
- // Check for simulator interface idiom
32
- if (constants?.interfaceIdiom === "simulator") {
33
- return true;
34
- }
35
-
36
- // Check if running in a testing environment
37
- if ("isTesting" in Platform && Platform.isTesting) {
38
- return true;
39
- }
40
- return false;
41
- }
42
- if (Platform.OS === "android") {
43
- const constants = Platform.constants;
44
- const brand = String(constants?.Brand || "").toLowerCase();
45
- const model = String(constants?.Model || "").toLowerCase();
46
- const fingerprint = String(constants?.Fingerprint || "").toLowerCase();
47
- const isEmulator = brand.includes("generic") || model.includes("sdk") || model.includes("emulator") || model.includes("android sdk") || fingerprint.includes("generic");
48
- return isEmulator;
49
- }
50
- return false;
51
- }
52
-
53
- /**
54
- * Get basic device metadata from Platform APIs
55
- */
56
- export function getDeviceMetadata() {
57
- const metadata = {
58
- platform: Platform.OS,
59
- osVersion: String(Platform.Version),
60
- isSimulator: String(isSimulator())
61
- };
62
-
63
- // Add Android-specific constants if available
64
- if (Platform.OS === "android") {
65
- const constants = Platform.constants;
66
- if (constants?.Brand) metadata.brand = String(constants.Brand);
67
- if (constants?.Model) metadata.model = String(constants.Model);
68
- if (constants?.Manufacturer) metadata.manufacturer = String(constants.Manufacturer);
69
- }
70
-
71
- // Add iOS-specific constants if available
72
- if (Platform.OS === "ios") {
73
- const constants = Platform.constants;
74
- if (constants?.systemName) metadata.systemName = String(constants.systemName);
75
- if (constants?.interfaceIdiom) metadata.interfaceIdiom = String(constants.interfaceIdiom);
76
- }
77
- return metadata;
78
- }
79
-
80
- /**
81
- * Get a default device name suggestion based on platform
82
- */
83
- export function getDefaultDeviceName() {
84
- const platformName = Platform.OS === "ios" ? "iOS" : Platform.OS === "android" ? "Android" : Platform.OS;
85
- const sim = isSimulator() ? " Simulator" : "";
86
- return `My ${platformName} Device${sim}`;
87
- }
1
+ "use strict";import{Platform as r}from"react-native";export function generateUUID(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,n=>{const t=Math.random()*16|0;const e=n==="x"?t:t&3|8;return e.toString(16)})}export function isSimulator(){if(r.OS==="ios"){const n=r.constants;if(n?.interfaceIdiom==="simulator"){return true}if("isTesting"in r&&r.isTesting){return true}return false}if(r.OS==="android"){const n=r.constants;const t=String(n?.Brand||"").toLowerCase();const e=String(n?.Model||"").toLowerCase();const i=String(n?.Fingerprint||"").toLowerCase();const o=t.includes("generic")||e.includes("sdk")||e.includes("emulator")||e.includes("android sdk")||i.includes("generic");return o}return false}export function getDeviceMetadata(){const n={platform:r.OS,osVersion:String(r.Version),isSimulator:String(isSimulator())};if(r.OS==="android"){const t=r.constants;if(t?.Brand)n.brand=String(t.Brand);if(t?.Model)n.model=String(t.Model);if(t?.Manufacturer)n.manufacturer=String(t.Manufacturer)}if(r.OS==="ios"){const t=r.constants;if(t?.systemName)n.systemName=String(t.systemName);if(t?.interfaceIdiom)n.interfaceIdiom=String(t.interfaceIdiom)}return n}export function getDefaultDeviceName(){const n=r.OS==="ios"?"iOS":r.OS==="android"?"Android":r.OS;const t=isSimulator()?" Simulator":"";return`My ${n} Device${t}`}
@@ -1,220 +1 @@
1
- "use strict";
2
-
3
- /**
4
- * Web/Electron device info utilities
5
- *
6
- * Platform-specific implementation for web browsers and Electron apps.
7
- * Uses browser APIs instead of React Native Platform.
8
- */
9
-
10
- /**
11
- * Generate a UUID v4
12
- */
13
- export function generateUUID() {
14
- // Use crypto.randomUUID if available (modern browsers/Node)
15
- if (typeof crypto !== "undefined" && crypto.randomUUID) {
16
- return crypto.randomUUID();
17
- }
18
-
19
- // Fallback to manual generation
20
- return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, c => {
21
- const r = Math.random() * 16 | 0;
22
- const v = c === "x" ? r : r & 0x3 | 0x8;
23
- return v.toString(16);
24
- });
25
- }
26
-
27
- /**
28
- * Check if running on a simulator/emulator
29
- * Always returns false for web/Electron
30
- */
31
- export function isSimulator() {
32
- return false;
33
- }
34
-
35
- /**
36
- * Detect the platform from userAgent
37
- */
38
- function detectPlatform() {
39
- if (typeof navigator === "undefined") {
40
- return "unknown";
41
- }
42
- const ua = navigator.userAgent.toLowerCase();
43
- const platform = navigator.platform?.toLowerCase() || "";
44
-
45
- // Check for Electron first
46
- if (ua.includes("electron")) {
47
- if (platform.includes("mac") || ua.includes("mac")) {
48
- return "electron-macos";
49
- }
50
- if (platform.includes("win") || ua.includes("win")) {
51
- return "electron-windows";
52
- }
53
- if (platform.includes("linux") || ua.includes("linux")) {
54
- return "electron-linux";
55
- }
56
- return "electron";
57
- }
58
-
59
- // Regular browser detection
60
- if (platform.includes("mac") || ua.includes("mac")) {
61
- return "macos";
62
- }
63
- if (platform.includes("win") || ua.includes("win")) {
64
- return "windows";
65
- }
66
- if (platform.includes("linux") || ua.includes("linux")) {
67
- return "linux";
68
- }
69
- if (/iphone|ipad|ipod/.test(ua)) {
70
- return "ios-web";
71
- }
72
- if (ua.includes("android")) {
73
- return "android-web";
74
- }
75
- return "web";
76
- }
77
-
78
- /**
79
- * Get OS version from userAgent
80
- */
81
- function getOSVersion() {
82
- if (typeof navigator === "undefined") {
83
- return "unknown";
84
- }
85
- const ua = navigator.userAgent;
86
-
87
- // macOS version
88
- const macMatch = ua.match(/Mac OS X ([\d_.]+)/);
89
- if (macMatch) {
90
- return macMatch[1].replace(/_/g, ".");
91
- }
92
-
93
- // Windows version
94
- const winMatch = ua.match(/Windows NT ([\d.]+)/);
95
- if (winMatch) {
96
- const versions = {
97
- "10.0": "10/11",
98
- "6.3": "8.1",
99
- "6.2": "8",
100
- "6.1": "7"
101
- };
102
- return versions[winMatch[1]] || winMatch[1];
103
- }
104
-
105
- // Linux (usually doesn't have version in UA)
106
- if (ua.includes("Linux")) {
107
- return "Linux";
108
- }
109
- return "unknown";
110
- }
111
-
112
- /**
113
- * Get browser name and version
114
- */
115
- function getBrowserInfo() {
116
- if (typeof navigator === "undefined") {
117
- return {
118
- name: "unknown",
119
- version: "unknown"
120
- };
121
- }
122
- const ua = navigator.userAgent;
123
-
124
- // Electron
125
- const electronMatch = ua.match(/Electron\/([\d.]+)/);
126
- if (electronMatch) {
127
- return {
128
- name: "Electron",
129
- version: electronMatch[1]
130
- };
131
- }
132
-
133
- // Chrome
134
- const chromeMatch = ua.match(/Chrome\/([\d.]+)/);
135
- if (chromeMatch && !ua.includes("Edg")) {
136
- return {
137
- name: "Chrome",
138
- version: chromeMatch[1]
139
- };
140
- }
141
-
142
- // Edge
143
- const edgeMatch = ua.match(/Edg\/([\d.]+)/);
144
- if (edgeMatch) {
145
- return {
146
- name: "Edge",
147
- version: edgeMatch[1]
148
- };
149
- }
150
-
151
- // Firefox
152
- const firefoxMatch = ua.match(/Firefox\/([\d.]+)/);
153
- if (firefoxMatch) {
154
- return {
155
- name: "Firefox",
156
- version: firefoxMatch[1]
157
- };
158
- }
159
-
160
- // Safari
161
- const safariMatch = ua.match(/Version\/([\d.]+).*Safari/);
162
- if (safariMatch) {
163
- return {
164
- name: "Safari",
165
- version: safariMatch[1]
166
- };
167
- }
168
- return {
169
- name: "unknown",
170
- version: "unknown"
171
- };
172
- }
173
-
174
- /**
175
- * Get basic device metadata for web/Electron
176
- */
177
- export function getDeviceMetadata() {
178
- const metadata = {
179
- platform: detectPlatform(),
180
- osVersion: getOSVersion(),
181
- isSimulator: "false"
182
- };
183
- const browserInfo = getBrowserInfo();
184
- metadata.browser = browserInfo.name;
185
- metadata.browserVersion = browserInfo.version;
186
-
187
- // Add screen info if available
188
- if (typeof window !== "undefined" && window.screen) {
189
- metadata.screenResolution = `${window.screen.width}x${window.screen.height}`;
190
- }
191
-
192
- // Add language
193
- if (typeof navigator !== "undefined" && navigator.language) {
194
- metadata.language = navigator.language;
195
- }
196
-
197
- // Add timezone
198
- try {
199
- metadata.timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
200
- } catch {
201
- // Ignore timezone detection errors
202
- }
203
- return metadata;
204
- }
205
-
206
- /**
207
- * Get a default device name suggestion based on platform
208
- */
209
- export function getDefaultDeviceName() {
210
- const platform = detectPlatform();
211
- const browserInfo = getBrowserInfo();
212
- if (platform.startsWith("electron")) {
213
- const os = platform.replace("electron-", "").replace("electron", "Desktop");
214
- return `${os.charAt(0).toUpperCase() + os.slice(1)} App`;
215
- }
216
- if (browserInfo.name !== "unknown") {
217
- return `${browserInfo.name} Browser`;
218
- }
219
- return "Web Browser";
220
- }
1
+ "use strict";export function generateUUID(){if(typeof crypto!=="undefined"&&crypto.randomUUID){return crypto.randomUUID()}return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,n=>{const e=Math.random()*16|0;const r=n==="x"?e:e&3|8;return r.toString(16)})}export function isSimulator(){return false}function a(){if(typeof navigator==="undefined"){return"unknown"}const n=navigator.userAgent.toLowerCase();const e=navigator.platform?.toLowerCase()||"";if(n.includes("electron")){if(e.includes("mac")||n.includes("mac")){return"electron-macos"}if(e.includes("win")||n.includes("win")){return"electron-windows"}if(e.includes("linux")||n.includes("linux")){return"electron-linux"}return"electron"}if(e.includes("mac")||n.includes("mac")){return"macos"}if(e.includes("win")||n.includes("win")){return"windows"}if(e.includes("linux")||n.includes("linux")){return"linux"}if(/iphone|ipad|ipod/.test(n)){return"ios-web"}if(n.includes("android")){return"android-web"}return"web"}function u(){if(typeof navigator==="undefined"){return"unknown"}const n=navigator.userAgent;const e=n.match(/Mac OS X ([\d_.]+)/);if(e){return e[1].replace(/_/g,".")}const r=n.match(/Windows NT ([\d.]+)/);if(r){const t={"10.0":"10/11","6.3":"8.1","6.2":"8","6.1":"7"};return t[r[1]]||r[1]}if(n.includes("Linux")){return"Linux"}return"unknown"}function c(){if(typeof navigator==="undefined"){return{name:"unknown",version:"unknown"}}const n=navigator.userAgent;const e=n.match(/Electron\/([\d.]+)/);if(e){return{name:"Electron",version:e[1]}}const r=n.match(/Chrome\/([\d.]+)/);if(r&&!n.includes("Edg")){return{name:"Chrome",version:r[1]}}const t=n.match(/Edg\/([\d.]+)/);if(t){return{name:"Edge",version:t[1]}}const o=n.match(/Firefox\/([\d.]+)/);if(o){return{name:"Firefox",version:o[1]}}const i=n.match(/Version\/([\d.]+).*Safari/);if(i){return{name:"Safari",version:i[1]}}return{name:"unknown",version:"unknown"}}export function getDeviceMetadata(){const n={platform:a(),osVersion:u(),isSimulator:"false"};const e=c();n.browser=e.name;n.browserVersion=e.version;if(typeof window!=="undefined"&&window.screen){n.screenResolution=`${window.screen.width}x${window.screen.height}`}if(typeof navigator!=="undefined"&&navigator.language){n.language=navigator.language}try{n.timezone=Intl.DateTimeFormat().resolvedOptions().timeZone}catch{}return n}export function getDefaultDeviceName(){const n=a();const e=c();if(n.startsWith("electron")){const r=n.replace("electron-","").replace("electron","Desktop");return`${r.charAt(0).toUpperCase()+r.slice(1)} App`}if(e.name!=="unknown"){return`${e.name} Browser`}return"Web Browser"}
@@ -1,10 +1 @@
1
- "use strict";
2
-
3
- /**
4
- * Device fingerprint utilities for license activation
5
- *
6
- * The fingerprint is a generated UUID that is stored alongside the license.
7
- * It's created when the user registers their device and persists with the license data.
8
- */
9
-
10
- export { generateUUID, isSimulator, getDeviceMetadata, getDefaultDeviceName } from "./device-info";
1
+ "use strict";export{generateUUID,isSimulator,getDeviceMetadata,getDefaultDeviceName}from"./device-info";
@@ -1,10 +1 @@
1
- "use strict";
2
-
3
- /**
4
- * Device fingerprint utilities for license activation (Web/Electron)
5
- *
6
- * The fingerprint is a generated UUID that is stored alongside the license.
7
- * It's created when the user registers their device and persists with the license data.
8
- */
9
-
10
- export { generateUUID, isSimulator, getDeviceMetadata, getDefaultDeviceName } from "./device-info.web.js";
1
+ "use strict";export{generateUUID,isSimulator,getDeviceMetadata,getDefaultDeviceName}from"./device-info.web.js";