@moontra/moonui-pro 3.0.0 → 3.1.1
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/cdn/index.global.js +121 -121
- package/dist/cdn/index.global.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.mjs +47 -23
- package/dist/server.d.ts +26 -1
- package/dist/server.mjs +74 -5
- package/package.json +2 -1
- package/scripts/postinstall.cjs +199 -0
- package/dist/lib/build-time-validator.d.ts +0 -30
- package/dist/lib/build-time-validator.mjs +0 -117
- package/dist/lib/client-token-verifier.d.ts +0 -27
- package/dist/lib/client-token-verifier.mjs +0 -44
- package/plugin/next.js +0 -83
- package/plugin/vite.js +0 -76
package/dist/index.d.ts
CHANGED
|
@@ -376,7 +376,7 @@ declare const MoonUIAvatarFallbackPro: React$1.ForwardRefExoticComponent<Omit<Av
|
|
|
376
376
|
* Dark ve light modda uyumlu, erişilebilir ve çeşitli varyantlar sunar.
|
|
377
377
|
*/
|
|
378
378
|
declare const moonUIBadgeVariantsPro: (props?: ({
|
|
379
|
-
variant?: "
|
|
379
|
+
variant?: "primary" | "secondary" | "success" | "warning" | "ghost" | "outline" | "destructive" | "pro" | "admin" | null | undefined;
|
|
380
380
|
size?: "sm" | "md" | "lg" | null | undefined;
|
|
381
381
|
radius?: "default" | "none" | "sm" | "lg" | null | undefined;
|
|
382
382
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
@@ -4367,7 +4367,7 @@ declare const statusVariants: (props?: ({
|
|
|
4367
4367
|
declare const badgeVariants: (props?: ({
|
|
4368
4368
|
size?: "sm" | "md" | "lg" | "xl" | "2xl" | "xs" | "3xl" | null | undefined;
|
|
4369
4369
|
position?: "top-left" | "top-right" | "bottom-left" | "bottom-right" | null | undefined;
|
|
4370
|
-
variant?: "
|
|
4370
|
+
variant?: "lifetime" | "default" | "success" | "warning" | "info" | "destructive" | "pro" | null | undefined;
|
|
4371
4371
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
4372
4372
|
declare const iconBadgeMap: {
|
|
4373
4373
|
crown: React$1.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React$1.RefAttributes<SVGSVGElement>>;
|
package/dist/index.mjs
CHANGED
|
@@ -2115,33 +2115,39 @@ var AUTH_CONFIG = {
|
|
|
2115
2115
|
}
|
|
2116
2116
|
};
|
|
2117
2117
|
|
|
2118
|
-
// src/lib/
|
|
2119
|
-
function
|
|
2118
|
+
// src/lib/license-token-client.ts
|
|
2119
|
+
function readLicenseTokenClient() {
|
|
2120
2120
|
try {
|
|
2121
|
-
|
|
2122
|
-
if (!token) {
|
|
2123
|
-
console.log("[MoonUI] No build token found");
|
|
2121
|
+
if (typeof window === "undefined" || !window.localStorage) {
|
|
2124
2122
|
return null;
|
|
2125
2123
|
}
|
|
2126
|
-
const
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
};
|
|
2135
|
-
if (payload.expiresAt < Date.now()) {
|
|
2136
|
-
console.warn("[MoonUI] Build token expired, rebuild required");
|
|
2124
|
+
const storedToken = localStorage.getItem("moonui_license_token");
|
|
2125
|
+
if (!storedToken) {
|
|
2126
|
+
return null;
|
|
2127
|
+
}
|
|
2128
|
+
const token = JSON.parse(storedToken);
|
|
2129
|
+
if (token.expiresAt < Date.now()) {
|
|
2130
|
+
console.log("[MoonUI] Client license token expired");
|
|
2131
|
+
localStorage.removeItem("moonui_license_token");
|
|
2137
2132
|
return null;
|
|
2138
2133
|
}
|
|
2139
|
-
return
|
|
2134
|
+
return token;
|
|
2140
2135
|
} catch (error) {
|
|
2141
|
-
console.error("[MoonUI] Error
|
|
2136
|
+
console.error("[MoonUI] Error reading client license token:", error);
|
|
2142
2137
|
return null;
|
|
2143
2138
|
}
|
|
2144
2139
|
}
|
|
2140
|
+
function saveLicenseTokenClient(token) {
|
|
2141
|
+
try {
|
|
2142
|
+
if (typeof window === "undefined" || !window.localStorage) {
|
|
2143
|
+
return;
|
|
2144
|
+
}
|
|
2145
|
+
localStorage.setItem("moonui_license_token", JSON.stringify(token));
|
|
2146
|
+
console.log("[MoonUI] License token cached in browser");
|
|
2147
|
+
} catch (error) {
|
|
2148
|
+
console.error("[MoonUI] Error saving client license token:", error);
|
|
2149
|
+
}
|
|
2150
|
+
}
|
|
2145
2151
|
var AuthContext = createContext(void 0);
|
|
2146
2152
|
var authPromise = null;
|
|
2147
2153
|
var lastFetchTime = 0;
|
|
@@ -2187,17 +2193,17 @@ function MoonUIAuthProvider({ children }) {
|
|
|
2187
2193
|
console.log("[MoonUI Auth] Using ongoing request");
|
|
2188
2194
|
return authPromise;
|
|
2189
2195
|
}
|
|
2190
|
-
const
|
|
2191
|
-
if (
|
|
2192
|
-
console.log("[MoonUI Auth] Using
|
|
2196
|
+
const licenseToken = readLicenseTokenClient();
|
|
2197
|
+
if (licenseToken && licenseToken.hasProAccess) {
|
|
2198
|
+
console.log("[MoonUI Auth] Using embedded license token - Pro access granted");
|
|
2193
2199
|
const tokenState = {
|
|
2194
2200
|
isLoading: false,
|
|
2195
2201
|
hasProAccess: true,
|
|
2196
2202
|
isAuthenticated: true,
|
|
2197
|
-
subscriptionPlan:
|
|
2203
|
+
subscriptionPlan: licenseToken.plan === "lifetime" ? "lifetime" : "free",
|
|
2198
2204
|
subscription: {
|
|
2199
2205
|
status: "active",
|
|
2200
|
-
plan:
|
|
2206
|
+
plan: licenseToken.plan === "lifetime" ? "lifetime" : "free"
|
|
2201
2207
|
},
|
|
2202
2208
|
isAdmin: false
|
|
2203
2209
|
};
|
|
@@ -2270,6 +2276,16 @@ function MoonUIAuthProvider({ children }) {
|
|
|
2270
2276
|
if (response && response.ok) {
|
|
2271
2277
|
console.log("[MoonUI Auth] Using CLI auth server");
|
|
2272
2278
|
const data = await response.json();
|
|
2279
|
+
if (data.valid && data.hasProAccess) {
|
|
2280
|
+
saveLicenseTokenClient({
|
|
2281
|
+
valid: true,
|
|
2282
|
+
hasProAccess: data.hasProAccess,
|
|
2283
|
+
plan: data.plan || "lifetime",
|
|
2284
|
+
expiresAt: data.expiresAt || Date.now() + 30 * 24 * 60 * 60 * 1e3,
|
|
2285
|
+
domain: "localhost",
|
|
2286
|
+
timestamp: Date.now()
|
|
2287
|
+
});
|
|
2288
|
+
}
|
|
2273
2289
|
const newState = {
|
|
2274
2290
|
isLoading: false,
|
|
2275
2291
|
hasProAccess: data.hasProAccess || false,
|
|
@@ -2314,6 +2330,14 @@ function MoonUIAuthProvider({ children }) {
|
|
|
2314
2330
|
const validationData = await validationResponse.json();
|
|
2315
2331
|
if (validationData.valid && validationData.hasProAccess) {
|
|
2316
2332
|
console.log("[MoonUI Auth] License key validated successfully");
|
|
2333
|
+
saveLicenseTokenClient({
|
|
2334
|
+
valid: true,
|
|
2335
|
+
hasProAccess: validationData.hasProAccess,
|
|
2336
|
+
plan: validationData.plan || "lifetime",
|
|
2337
|
+
expiresAt: validationData.expiresAt || Date.now() + 30 * 24 * 60 * 60 * 1e3,
|
|
2338
|
+
domain: currentDomain || "production",
|
|
2339
|
+
timestamp: Date.now()
|
|
2340
|
+
});
|
|
2317
2341
|
const newState = {
|
|
2318
2342
|
isLoading: false,
|
|
2319
2343
|
hasProAccess: validationData.hasProAccess,
|
package/dist/server.d.ts
CHANGED
|
@@ -100,4 +100,29 @@ type AuthConfig = typeof AUTH_CONFIG;
|
|
|
100
100
|
type CacheConfig = typeof AUTH_CONFIG.cache;
|
|
101
101
|
type SecurityConfig = typeof AUTH_CONFIG.security;
|
|
102
102
|
|
|
103
|
-
|
|
103
|
+
/**
|
|
104
|
+
* License Token Reader
|
|
105
|
+
* Reads and decrypts the license token created by postinstall script
|
|
106
|
+
*/
|
|
107
|
+
interface LicenseToken {
|
|
108
|
+
valid: boolean;
|
|
109
|
+
hasProAccess: boolean;
|
|
110
|
+
plan: string;
|
|
111
|
+
expiresAt: number;
|
|
112
|
+
domain: string;
|
|
113
|
+
timestamp: number;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Read license token from file system (for server-side)
|
|
117
|
+
*/
|
|
118
|
+
declare function readLicenseTokenServer(): LicenseToken | null;
|
|
119
|
+
/**
|
|
120
|
+
* Read license token (server-side only)
|
|
121
|
+
*/
|
|
122
|
+
declare function readLicenseToken(): LicenseToken | null;
|
|
123
|
+
/**
|
|
124
|
+
* Check if Pro features are enabled from license token
|
|
125
|
+
*/
|
|
126
|
+
declare function hasProAccessFromToken(): boolean;
|
|
127
|
+
|
|
128
|
+
export { AUTH_CONFIG, AuthConfig, CacheConfig, SecurityConfig, clearValidationCookies, decryptData, encryptData, generateServerDeviceFingerprint, getValidationFromCookies, hasProAccessFromToken, performServerValidation, readLicenseToken, readLicenseTokenServer, setValidationInCookies, validateWithMoonUIServer };
|
package/dist/server.mjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import crypto from 'crypto';
|
|
1
|
+
import * as crypto from 'crypto';
|
|
2
|
+
import crypto__default from 'crypto';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* @moontra/moonui-pro v2.0.9
|
|
@@ -3026,14 +3027,14 @@ var AUTH_CONFIG = {
|
|
|
3026
3027
|
};
|
|
3027
3028
|
var ENCRYPTION_KEY = process.env.MOONUI_ENCRYPTION_KEY || "moonui-pro-default-key-change-in-production";
|
|
3028
3029
|
function encryptData(data) {
|
|
3029
|
-
const cipher =
|
|
3030
|
+
const cipher = crypto__default.createCipher("aes-256-cbc", ENCRYPTION_KEY);
|
|
3030
3031
|
let encrypted = cipher.update(JSON.stringify(data), "utf8", "hex");
|
|
3031
3032
|
encrypted += cipher.final("hex");
|
|
3032
3033
|
return encrypted;
|
|
3033
3034
|
}
|
|
3034
3035
|
function decryptData(encryptedData) {
|
|
3035
3036
|
try {
|
|
3036
|
-
const decipher =
|
|
3037
|
+
const decipher = crypto__default.createDecipher("aes-256-cbc", ENCRYPTION_KEY);
|
|
3037
3038
|
let decrypted = decipher.update(encryptedData, "hex", "utf8");
|
|
3038
3039
|
decrypted += decipher.final("utf8");
|
|
3039
3040
|
return JSON.parse(decrypted);
|
|
@@ -3050,7 +3051,7 @@ async function generateServerDeviceFingerprint() {
|
|
|
3050
3051
|
headersList.get("accept-encoding") || "unknown",
|
|
3051
3052
|
headersList.get("x-forwarded-for") || headersList.get("x-real-ip") || "unknown"
|
|
3052
3053
|
];
|
|
3053
|
-
const fingerprint =
|
|
3054
|
+
const fingerprint = crypto__default.createHash("sha256").update(components.join("|")).digest("hex");
|
|
3054
3055
|
return fingerprint;
|
|
3055
3056
|
}
|
|
3056
3057
|
async function validateWithMoonUIServer(token, deviceId) {
|
|
@@ -3147,6 +3148,74 @@ async function performServerValidation() {
|
|
|
3147
3148
|
}
|
|
3148
3149
|
return { ...result, cached: false };
|
|
3149
3150
|
}
|
|
3151
|
+
function decryptToken(encryptedData, key) {
|
|
3152
|
+
try {
|
|
3153
|
+
const algorithm = "aes-256-gcm";
|
|
3154
|
+
const salt = Buffer.from(encryptedData.salt, "hex");
|
|
3155
|
+
const derivedKey = crypto.pbkdf2Sync(key, salt, 1e5, 32, "sha256");
|
|
3156
|
+
const iv = Buffer.from(encryptedData.iv, "hex");
|
|
3157
|
+
const authTag = Buffer.from(encryptedData.authTag, "hex");
|
|
3158
|
+
const decipher = crypto.createDecipheriv(algorithm, derivedKey, iv);
|
|
3159
|
+
decipher.setAuthTag(authTag);
|
|
3160
|
+
let decrypted = decipher.update(encryptedData.encrypted, "hex", "utf8");
|
|
3161
|
+
decrypted += decipher.final("utf8");
|
|
3162
|
+
return JSON.parse(decrypted);
|
|
3163
|
+
} catch (error) {
|
|
3164
|
+
console.error("[MoonUI] Failed to decrypt license token:", error);
|
|
3165
|
+
return null;
|
|
3166
|
+
}
|
|
3167
|
+
}
|
|
3168
|
+
function readLicenseTokenServer() {
|
|
3169
|
+
try {
|
|
3170
|
+
if (typeof window !== "undefined") {
|
|
3171
|
+
return null;
|
|
3172
|
+
}
|
|
3173
|
+
const fs = __require("fs");
|
|
3174
|
+
const path = __require("path");
|
|
3175
|
+
const possiblePaths = [
|
|
3176
|
+
path.join(process.cwd(), ".moonui-license"),
|
|
3177
|
+
path.join(process.cwd(), "..", ".moonui-license"),
|
|
3178
|
+
path.join(process.cwd(), "..", "..", ".moonui-license"),
|
|
3179
|
+
path.join(__dirname, "..", "..", "..", "..", ".moonui-license")
|
|
3180
|
+
];
|
|
3181
|
+
let encryptedData = null;
|
|
3182
|
+
let foundPath = null;
|
|
3183
|
+
for (const filePath of possiblePaths) {
|
|
3184
|
+
if (fs.existsSync(filePath)) {
|
|
3185
|
+
foundPath = filePath;
|
|
3186
|
+
const fileContent = fs.readFileSync(filePath, "utf8");
|
|
3187
|
+
encryptedData = JSON.parse(fileContent);
|
|
3188
|
+
break;
|
|
3189
|
+
}
|
|
3190
|
+
}
|
|
3191
|
+
if (!encryptedData || !foundPath) {
|
|
3192
|
+
console.log("[MoonUI] No license file found");
|
|
3193
|
+
return null;
|
|
3194
|
+
}
|
|
3195
|
+
const decryptionKey = process.env.MOONUI_LICENSE_KEY || process.env.NEXT_PUBLIC_MOONUI_LICENSE_KEY || "default-key";
|
|
3196
|
+
const token = decryptToken(encryptedData, decryptionKey);
|
|
3197
|
+
if (!token) {
|
|
3198
|
+
console.log("[MoonUI] Failed to decrypt license token");
|
|
3199
|
+
return null;
|
|
3200
|
+
}
|
|
3201
|
+
if (token.expiresAt < Date.now()) {
|
|
3202
|
+
console.log("[MoonUI] License token expired, re-validation required");
|
|
3203
|
+
return null;
|
|
3204
|
+
}
|
|
3205
|
+
console.log("[MoonUI] License token loaded successfully from:", foundPath);
|
|
3206
|
+
return token;
|
|
3207
|
+
} catch (error) {
|
|
3208
|
+
console.error("[MoonUI] Error reading license token:", error);
|
|
3209
|
+
return null;
|
|
3210
|
+
}
|
|
3211
|
+
}
|
|
3212
|
+
function readLicenseToken() {
|
|
3213
|
+
return readLicenseTokenServer();
|
|
3214
|
+
}
|
|
3215
|
+
function hasProAccessFromToken() {
|
|
3216
|
+
const token = readLicenseToken();
|
|
3217
|
+
return token ? token.hasProAccess : false;
|
|
3218
|
+
}
|
|
3150
3219
|
|
|
3151
3220
|
// src/server.ts
|
|
3152
3221
|
if (typeof window !== "undefined") {
|
|
@@ -3155,4 +3224,4 @@ if (typeof window !== "undefined") {
|
|
|
3155
3224
|
);
|
|
3156
3225
|
}
|
|
3157
3226
|
|
|
3158
|
-
export { AUTH_CONFIG, clearValidationCookies, decryptData, encryptData, generateServerDeviceFingerprint, getValidationFromCookies, performServerValidation, setValidationInCookies, validateWithMoonUIServer };
|
|
3227
|
+
export { AUTH_CONFIG, clearValidationCookies, decryptData, encryptData, generateServerDeviceFingerprint, getValidationFromCookies, hasProAccessFromToken, performServerValidation, readLicenseToken, readLicenseTokenServer, setValidationInCookies, validateWithMoonUIServer };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@moontra/moonui-pro",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.1.1",
|
|
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",
|
|
@@ -51,6 +51,7 @@
|
|
|
51
51
|
"test:watch": "jest --watch",
|
|
52
52
|
"test:coverage": "jest --coverage",
|
|
53
53
|
"prepublishOnly": "npm run clean && npm run build",
|
|
54
|
+
"postinstall": "node scripts/postinstall.cjs",
|
|
54
55
|
"pub": "npm version patch && npm run build && npm publish",
|
|
55
56
|
"pub:minor": "npm version minor && npm run build && npm publish",
|
|
56
57
|
"pub:major": "npm version major && npm run build && npm publish"
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* MoonUI Pro PostInstall Script
|
|
5
|
+
* Automatically validates license in production environments during npm install
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const fs = require('fs');
|
|
9
|
+
const path = require('path');
|
|
10
|
+
const crypto = require('crypto');
|
|
11
|
+
const https = require('https');
|
|
12
|
+
|
|
13
|
+
// Configuration
|
|
14
|
+
const LICENSE_FILE = '.moonui-license';
|
|
15
|
+
const API_URL = 'https://moonui.dev/api/v1/license/validate';
|
|
16
|
+
const CACHE_DURATION = 30 * 24 * 60 * 60 * 1000; // 30 days in milliseconds
|
|
17
|
+
|
|
18
|
+
// Detect if we're in production environment
|
|
19
|
+
function isProduction() {
|
|
20
|
+
return (
|
|
21
|
+
process.env.NODE_ENV === 'production' ||
|
|
22
|
+
process.env.VERCEL === '1' ||
|
|
23
|
+
process.env.NETLIFY === 'true' ||
|
|
24
|
+
process.env.CI === 'true' ||
|
|
25
|
+
process.env.MOONUI_AUTH_TOKEN // Special token for CI/CD
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Encrypt token for storage
|
|
30
|
+
function encryptToken(token, key) {
|
|
31
|
+
const algorithm = 'aes-256-gcm';
|
|
32
|
+
const salt = crypto.randomBytes(16);
|
|
33
|
+
const derivedKey = crypto.pbkdf2Sync(key, salt, 100000, 32, 'sha256');
|
|
34
|
+
const iv = crypto.randomBytes(16);
|
|
35
|
+
const cipher = crypto.createCipheriv(algorithm, derivedKey, iv);
|
|
36
|
+
|
|
37
|
+
let encrypted = cipher.update(JSON.stringify(token), 'utf8', 'hex');
|
|
38
|
+
encrypted += cipher.final('hex');
|
|
39
|
+
|
|
40
|
+
const authTag = cipher.getAuthTag();
|
|
41
|
+
|
|
42
|
+
return {
|
|
43
|
+
encrypted,
|
|
44
|
+
salt: salt.toString('hex'),
|
|
45
|
+
iv: iv.toString('hex'),
|
|
46
|
+
authTag: authTag.toString('hex')
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Validate license with MoonUI API
|
|
51
|
+
async function validateLicense(licenseKey) {
|
|
52
|
+
return new Promise((resolve, reject) => {
|
|
53
|
+
const postData = JSON.stringify({
|
|
54
|
+
licenseKey,
|
|
55
|
+
domain: process.env.VERCEL_URL || process.env.DEPLOY_URL || 'unknown',
|
|
56
|
+
environment: 'production'
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
const options = {
|
|
60
|
+
hostname: 'moonui.dev',
|
|
61
|
+
port: 443,
|
|
62
|
+
path: '/api/v1/license/validate',
|
|
63
|
+
method: 'POST',
|
|
64
|
+
headers: {
|
|
65
|
+
'Content-Type': 'application/json',
|
|
66
|
+
'Content-Length': Buffer.byteLength(postData),
|
|
67
|
+
'X-PostInstall': 'true',
|
|
68
|
+
'X-Environment': process.env.VERCEL ? 'vercel' : process.env.NETLIFY ? 'netlify' : 'unknown'
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
const req = https.request(options, (res) => {
|
|
73
|
+
let data = '';
|
|
74
|
+
|
|
75
|
+
res.on('data', (chunk) => {
|
|
76
|
+
data += chunk;
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
res.on('end', () => {
|
|
80
|
+
try {
|
|
81
|
+
const result = JSON.parse(data);
|
|
82
|
+
if (res.statusCode === 200 && result.valid) {
|
|
83
|
+
resolve(result);
|
|
84
|
+
} else {
|
|
85
|
+
reject(new Error(result.error || 'License validation failed'));
|
|
86
|
+
}
|
|
87
|
+
} catch (error) {
|
|
88
|
+
reject(error);
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
req.on('error', (error) => {
|
|
94
|
+
reject(error);
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
req.write(postData);
|
|
98
|
+
req.end();
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Save license token to file
|
|
103
|
+
function saveLicenseToken(token) {
|
|
104
|
+
try {
|
|
105
|
+
// Find the project root (where package.json is)
|
|
106
|
+
let projectRoot = process.cwd();
|
|
107
|
+
let attempts = 0;
|
|
108
|
+
|
|
109
|
+
while (attempts < 10) {
|
|
110
|
+
if (fs.existsSync(path.join(projectRoot, 'package.json'))) {
|
|
111
|
+
break;
|
|
112
|
+
}
|
|
113
|
+
projectRoot = path.dirname(projectRoot);
|
|
114
|
+
attempts++;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const licenseFilePath = path.join(projectRoot, LICENSE_FILE);
|
|
118
|
+
|
|
119
|
+
// Encrypt token with a deterministic key based on environment
|
|
120
|
+
const encryptionKey = process.env.MOONUI_LICENSE_KEY || 'default-key';
|
|
121
|
+
const encryptedData = encryptToken(token, encryptionKey);
|
|
122
|
+
|
|
123
|
+
// Save to file
|
|
124
|
+
fs.writeFileSync(licenseFilePath, JSON.stringify(encryptedData, null, 2));
|
|
125
|
+
|
|
126
|
+
console.log('[MoonUI Pro] ✓ License token saved successfully');
|
|
127
|
+
return true;
|
|
128
|
+
} catch (error) {
|
|
129
|
+
console.error('[MoonUI Pro] Failed to save license token:', error.message);
|
|
130
|
+
return false;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Main postinstall logic
|
|
135
|
+
async function main() {
|
|
136
|
+
try {
|
|
137
|
+
// Only run in production environments
|
|
138
|
+
if (!isProduction()) {
|
|
139
|
+
console.log('[MoonUI Pro] Development environment detected, skipping license validation');
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
console.log('[MoonUI Pro] Production environment detected, checking license...');
|
|
144
|
+
|
|
145
|
+
// Check for license key in environment variables
|
|
146
|
+
const licenseKey = process.env.MOONUI_LICENSE_KEY ||
|
|
147
|
+
process.env.NEXT_PUBLIC_MOONUI_LICENSE_KEY ||
|
|
148
|
+
process.env.VITE_MOONUI_LICENSE_KEY ||
|
|
149
|
+
process.env.REACT_APP_MOONUI_LICENSE_KEY;
|
|
150
|
+
|
|
151
|
+
if (!licenseKey) {
|
|
152
|
+
console.log('[MoonUI Pro] No license key found in environment variables');
|
|
153
|
+
console.log('[MoonUI Pro] Set MOONUI_LICENSE_KEY to enable Pro features');
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
console.log('[MoonUI Pro] Validating license key...');
|
|
158
|
+
|
|
159
|
+
// Validate license with API
|
|
160
|
+
const validationResult = await validateLicense(licenseKey);
|
|
161
|
+
|
|
162
|
+
if (validationResult.valid && validationResult.hasProAccess) {
|
|
163
|
+
// Create token with validation result and expiry
|
|
164
|
+
const token = {
|
|
165
|
+
valid: true,
|
|
166
|
+
hasProAccess: validationResult.hasProAccess,
|
|
167
|
+
plan: validationResult.plan,
|
|
168
|
+
expiresAt: Date.now() + CACHE_DURATION,
|
|
169
|
+
domain: validationResult.domain,
|
|
170
|
+
timestamp: Date.now()
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
// Save encrypted token
|
|
174
|
+
saveLicenseToken(token);
|
|
175
|
+
|
|
176
|
+
console.log('[MoonUI Pro] ✓ License validated successfully');
|
|
177
|
+
console.log('[MoonUI Pro] ✓ Pro features enabled');
|
|
178
|
+
} else {
|
|
179
|
+
console.log('[MoonUI Pro] License validation failed');
|
|
180
|
+
console.log('[MoonUI Pro] Pro features will be disabled');
|
|
181
|
+
}
|
|
182
|
+
} catch (error) {
|
|
183
|
+
console.error('[MoonUI Pro] Error during postinstall:', error.message);
|
|
184
|
+
console.log('[MoonUI Pro] Continuing with Free plan');
|
|
185
|
+
|
|
186
|
+
// Don't fail the install process
|
|
187
|
+
process.exit(0);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// Run if called directly (not imported)
|
|
192
|
+
if (require.main === module) {
|
|
193
|
+
main().catch(error => {
|
|
194
|
+
console.error('[MoonUI Pro] Unexpected error:', error);
|
|
195
|
+
process.exit(0); // Don't fail npm install
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
module.exports = { validateLicense, saveLicenseToken, isProduction };
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Build-time license validation and token generation
|
|
3
|
-
* This runs during build process, not in browser
|
|
4
|
-
*/
|
|
5
|
-
interface TokenPayload {
|
|
6
|
-
licenseKey: string;
|
|
7
|
-
domain: string;
|
|
8
|
-
timestamp: number;
|
|
9
|
-
expiresAt: number;
|
|
10
|
-
hasProAccess: boolean;
|
|
11
|
-
plan: string;
|
|
12
|
-
}
|
|
13
|
-
/**
|
|
14
|
-
* Validate license key at build time
|
|
15
|
-
* Makes server-side request to avoid CORS
|
|
16
|
-
*/
|
|
17
|
-
declare function validateLicenseAtBuildTime(licenseKey: string | undefined, domain?: string): Promise<string | null>;
|
|
18
|
-
/**
|
|
19
|
-
* Verify and decrypt token on client-side
|
|
20
|
-
*/
|
|
21
|
-
declare function verifyAndDecryptToken(token: string): TokenPayload | null;
|
|
22
|
-
/**
|
|
23
|
-
* Generate a webpack DefinePlugin config with the token
|
|
24
|
-
*/
|
|
25
|
-
declare function generateWebpackDefineConfig(token: string | null): {
|
|
26
|
-
'process.env.MOONUI_BUILD_TOKEN': string;
|
|
27
|
-
'process.env.MOONUI_BUILD_TIME': string;
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
export { generateWebpackDefineConfig, validateLicenseAtBuildTime, verifyAndDecryptToken };
|
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
import crypto from 'crypto';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* @moontra/moonui-pro v2.0.9
|
|
5
|
-
* Premium UI components for MoonUI
|
|
6
|
-
* (c) 2025 MoonUI. All rights reserved.
|
|
7
|
-
* @license Commercial - https://moonui.dev/license
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
var ENCRYPTION_KEY = "moonui-pro-2024-encryption-key-v1";
|
|
11
|
-
var SIGNING_KEY = "moonui-pro-2024-signing-key-v1";
|
|
12
|
-
async function validateLicenseAtBuildTime(licenseKey, domain) {
|
|
13
|
-
if (!licenseKey) {
|
|
14
|
-
console.log("[MoonUI Build] No license key provided");
|
|
15
|
-
return null;
|
|
16
|
-
}
|
|
17
|
-
try {
|
|
18
|
-
console.log("[MoonUI Build] Validating license key...");
|
|
19
|
-
const validationDomain = domain || process.env.VERCEL_URL || process.env.NEXT_PUBLIC_VERCEL_URL || process.env.DEPLOY_URL || "localhost";
|
|
20
|
-
const response = await fetch("https://moonui.dev/api/v1/license/validate", {
|
|
21
|
-
method: "POST",
|
|
22
|
-
headers: {
|
|
23
|
-
"Content-Type": "application/json",
|
|
24
|
-
"X-Build-Time-Validation": "true",
|
|
25
|
-
"User-Agent": "MoonUI-Build-Validator/1.0"
|
|
26
|
-
},
|
|
27
|
-
body: JSON.stringify({
|
|
28
|
-
licenseKey,
|
|
29
|
-
domain: validationDomain
|
|
30
|
-
})
|
|
31
|
-
});
|
|
32
|
-
if (!response.ok) {
|
|
33
|
-
console.error("[MoonUI Build] License validation failed:", response.status);
|
|
34
|
-
return null;
|
|
35
|
-
}
|
|
36
|
-
const data = await response.json();
|
|
37
|
-
if (!data.valid || !data.hasProAccess) {
|
|
38
|
-
console.error("[MoonUI Build] Invalid license or no Pro access");
|
|
39
|
-
return null;
|
|
40
|
-
}
|
|
41
|
-
console.log("[MoonUI Build] License validated successfully");
|
|
42
|
-
const payload = {
|
|
43
|
-
licenseKey: licenseKey.substring(0, 8) + "...",
|
|
44
|
-
// Only store partial key
|
|
45
|
-
domain: validationDomain,
|
|
46
|
-
timestamp: Date.now(),
|
|
47
|
-
expiresAt: Date.now() + 7 * 24 * 60 * 60 * 1e3,
|
|
48
|
-
// 7 days
|
|
49
|
-
hasProAccess: data.hasProAccess,
|
|
50
|
-
plan: data.plan || "pro"
|
|
51
|
-
};
|
|
52
|
-
const token = encryptAndSignToken(payload);
|
|
53
|
-
return token;
|
|
54
|
-
} catch (error) {
|
|
55
|
-
console.error("[MoonUI Build] Error validating license:", error);
|
|
56
|
-
return null;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
function encryptAndSignToken(payload) {
|
|
60
|
-
const payloadString = JSON.stringify(payload);
|
|
61
|
-
const iv = crypto.randomBytes(16);
|
|
62
|
-
const cipher = crypto.createCipheriv(
|
|
63
|
-
"aes-256-gcm",
|
|
64
|
-
crypto.scryptSync(ENCRYPTION_KEY, "salt", 32),
|
|
65
|
-
iv
|
|
66
|
-
);
|
|
67
|
-
let encrypted = cipher.update(payloadString, "utf8", "hex");
|
|
68
|
-
encrypted += cipher.final("hex");
|
|
69
|
-
const authTag = cipher.getAuthTag();
|
|
70
|
-
const hmac = crypto.createHmac("sha256", SIGNING_KEY);
|
|
71
|
-
hmac.update(encrypted);
|
|
72
|
-
const signature = hmac.digest("hex");
|
|
73
|
-
const token = Buffer.from(JSON.stringify({
|
|
74
|
-
encrypted,
|
|
75
|
-
authTag: authTag.toString("hex"),
|
|
76
|
-
signature,
|
|
77
|
-
iv: iv.toString("hex")
|
|
78
|
-
})).toString("base64");
|
|
79
|
-
return token;
|
|
80
|
-
}
|
|
81
|
-
function verifyAndDecryptToken(token) {
|
|
82
|
-
try {
|
|
83
|
-
const decoded = JSON.parse(Buffer.from(token, "base64").toString());
|
|
84
|
-
const hmac = crypto.createHmac("sha256", SIGNING_KEY);
|
|
85
|
-
hmac.update(decoded.encrypted);
|
|
86
|
-
const expectedSignature = hmac.digest("hex");
|
|
87
|
-
if (decoded.signature !== expectedSignature) {
|
|
88
|
-
console.error("[MoonUI] Invalid token signature");
|
|
89
|
-
return null;
|
|
90
|
-
}
|
|
91
|
-
const decipher = crypto.createDecipheriv(
|
|
92
|
-
"aes-256-gcm",
|
|
93
|
-
crypto.scryptSync(ENCRYPTION_KEY, "salt", 32),
|
|
94
|
-
Buffer.from(decoded.iv, "hex")
|
|
95
|
-
);
|
|
96
|
-
decipher.setAuthTag(Buffer.from(decoded.authTag, "hex"));
|
|
97
|
-
let decrypted = decipher.update(decoded.encrypted, "hex", "utf8");
|
|
98
|
-
decrypted += decipher.final("utf8");
|
|
99
|
-
const payload = JSON.parse(decrypted);
|
|
100
|
-
if (payload.expiresAt < Date.now()) {
|
|
101
|
-
console.error("[MoonUI] Token expired");
|
|
102
|
-
return null;
|
|
103
|
-
}
|
|
104
|
-
return payload;
|
|
105
|
-
} catch (error) {
|
|
106
|
-
console.error("[MoonUI] Error verifying token:", error);
|
|
107
|
-
return null;
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
function generateWebpackDefineConfig(token) {
|
|
111
|
-
return {
|
|
112
|
-
"process.env.MOONUI_BUILD_TOKEN": JSON.stringify(token),
|
|
113
|
-
"process.env.MOONUI_BUILD_TIME": JSON.stringify(Date.now())
|
|
114
|
-
};
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
export { generateWebpackDefineConfig, validateLicenseAtBuildTime, verifyAndDecryptToken };
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Client-side token verification
|
|
3
|
-
* This runs in the browser and verifies the build-time generated token
|
|
4
|
-
*/
|
|
5
|
-
interface TokenPayload {
|
|
6
|
-
licenseKey: string;
|
|
7
|
-
domain: string;
|
|
8
|
-
timestamp: number;
|
|
9
|
-
expiresAt: number;
|
|
10
|
-
hasProAccess: boolean;
|
|
11
|
-
plan: string;
|
|
12
|
-
}
|
|
13
|
-
/**
|
|
14
|
-
* Simple client-side token verification
|
|
15
|
-
* Note: Real decryption happens server-side, this is just a basic check
|
|
16
|
-
*/
|
|
17
|
-
declare function verifyBuildToken(): TokenPayload | null;
|
|
18
|
-
/**
|
|
19
|
-
* Check if Pro features are enabled
|
|
20
|
-
*/
|
|
21
|
-
declare function hasProAccess(): boolean;
|
|
22
|
-
/**
|
|
23
|
-
* Get subscription plan from token
|
|
24
|
-
*/
|
|
25
|
-
declare function getSubscriptionPlan(): string;
|
|
26
|
-
|
|
27
|
-
export { getSubscriptionPlan, hasProAccess, verifyBuildToken };
|