@retrivora-ai/rag-engine 2.2.8 → 2.3.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.
- package/README.md +2 -2
- package/dist/handlers/index.js +5 -3
- package/dist/handlers/index.mjs +5 -3
- package/dist/index.js +14 -12
- package/dist/index.mjs +14 -12
- package/dist/server.js +16 -13
- package/dist/server.mjs +16 -13
- package/package.json +1 -1
- package/src/core/LicenseValidator.ts +13 -11
- package/src/core/LicenseVerifier.ts +12 -11
- package/src/handlers/index.ts +4 -2
package/README.md
CHANGED
|
@@ -76,8 +76,8 @@ npm install @retrivora-ai/rag-engine
|
|
|
76
76
|
Create a `.env.local` file in your application root to supply your keys and provider selections:
|
|
77
77
|
```bash
|
|
78
78
|
# General Setup
|
|
79
|
-
|
|
80
|
-
|
|
79
|
+
NEXT_PUBLIC_PROJECT_ID=my-rag-application
|
|
80
|
+
NEXT_PUBLIC_RETRIVORA_LICENSE_KEY=ey... # Required for client & server deployment
|
|
81
81
|
|
|
82
82
|
# Vector Database (MongoDB Atlas Example)
|
|
83
83
|
VECTOR_DB_PROVIDER=mongodb
|
package/dist/handlers/index.js
CHANGED
|
@@ -2346,7 +2346,8 @@ var LicenseVerifier = class {
|
|
|
2346
2346
|
};
|
|
2347
2347
|
}
|
|
2348
2348
|
try {
|
|
2349
|
-
const
|
|
2349
|
+
const sanitizedKey = (licenseKey || "").trim().replace(/^["']|["']$/g, "").trim();
|
|
2350
|
+
const rawToken = sanitizedKey.replace(/^rtv_/i, "").trim();
|
|
2350
2351
|
const parts = rawToken.split(".");
|
|
2351
2352
|
if (parts.length !== 3) {
|
|
2352
2353
|
throw new Error("Malformed token structure (expected 3 parts).");
|
|
@@ -4710,7 +4711,7 @@ var ConfigValidator = class {
|
|
|
4710
4711
|
// package.json
|
|
4711
4712
|
var package_default = {
|
|
4712
4713
|
name: "@retrivora-ai/rag-engine",
|
|
4713
|
-
version: "2.
|
|
4714
|
+
version: "2.3.0",
|
|
4714
4715
|
description: "Retrivora AI is a plug-and-play AI engine for RAG chat experiences \u2014 generic vector DB + LLM provider, embeddable or standalone.",
|
|
4715
4716
|
author: "Abhinav Alkuchi",
|
|
4716
4717
|
license: "UNLICENSED",
|
|
@@ -10598,7 +10599,8 @@ function createLicenseHandler(configOrPlugin, options) {
|
|
|
10598
10599
|
try {
|
|
10599
10600
|
const body = await req.json().catch(() => ({}));
|
|
10600
10601
|
const config = plugin.getConfig();
|
|
10601
|
-
const
|
|
10602
|
+
const rawKey = req.headers.get("x-license-key") || (body == null ? void 0 : body.licenseKey) || ((_a2 = req.headers.get("authorization")) == null ? void 0 : _a2.replace(/^Bearer\s+/i, "")) || config.licenseKey || process.env.NEXT_PUBLIC_RETRIVORA_LICENSE_KEY || process.env.RETRIVORA_LICENSE_KEY || "";
|
|
10603
|
+
const licenseKey = (rawKey || "").trim().replace(/^["']|["']$/g, "").trim();
|
|
10602
10604
|
const projectId = (body == null ? void 0 : body.projectId) || config.projectId || "my-rag-app";
|
|
10603
10605
|
const payload = LicenseVerifier.verify(licenseKey, projectId);
|
|
10604
10606
|
return import_server.NextResponse.json({
|
package/dist/handlers/index.mjs
CHANGED
|
@@ -2310,7 +2310,8 @@ var LicenseVerifier = class {
|
|
|
2310
2310
|
};
|
|
2311
2311
|
}
|
|
2312
2312
|
try {
|
|
2313
|
-
const
|
|
2313
|
+
const sanitizedKey = (licenseKey || "").trim().replace(/^["']|["']$/g, "").trim();
|
|
2314
|
+
const rawToken = sanitizedKey.replace(/^rtv_/i, "").trim();
|
|
2314
2315
|
const parts = rawToken.split(".");
|
|
2315
2316
|
if (parts.length !== 3) {
|
|
2316
2317
|
throw new Error("Malformed token structure (expected 3 parts).");
|
|
@@ -4674,7 +4675,7 @@ var ConfigValidator = class {
|
|
|
4674
4675
|
// package.json
|
|
4675
4676
|
var package_default = {
|
|
4676
4677
|
name: "@retrivora-ai/rag-engine",
|
|
4677
|
-
version: "2.
|
|
4678
|
+
version: "2.3.0",
|
|
4678
4679
|
description: "Retrivora AI is a plug-and-play AI engine for RAG chat experiences \u2014 generic vector DB + LLM provider, embeddable or standalone.",
|
|
4679
4680
|
author: "Abhinav Alkuchi",
|
|
4680
4681
|
license: "UNLICENSED",
|
|
@@ -10562,7 +10563,8 @@ function createLicenseHandler(configOrPlugin, options) {
|
|
|
10562
10563
|
try {
|
|
10563
10564
|
const body = await req.json().catch(() => ({}));
|
|
10564
10565
|
const config = plugin.getConfig();
|
|
10565
|
-
const
|
|
10566
|
+
const rawKey = req.headers.get("x-license-key") || (body == null ? void 0 : body.licenseKey) || ((_a2 = req.headers.get("authorization")) == null ? void 0 : _a2.replace(/^Bearer\s+/i, "")) || config.licenseKey || process.env.NEXT_PUBLIC_RETRIVORA_LICENSE_KEY || process.env.RETRIVORA_LICENSE_KEY || "";
|
|
10567
|
+
const licenseKey = (rawKey || "").trim().replace(/^["']|["']$/g, "").trim();
|
|
10566
10568
|
const projectId = (body == null ? void 0 : body.projectId) || config.projectId || "my-rag-app";
|
|
10567
10569
|
const payload = LicenseVerifier.verify(licenseKey, projectId);
|
|
10568
10570
|
return NextResponse.json({
|
package/dist/index.js
CHANGED
|
@@ -3044,7 +3044,7 @@ function useRagChat(projectId, options = {}) {
|
|
|
3044
3044
|
// package.json
|
|
3045
3045
|
var package_default = {
|
|
3046
3046
|
name: "@retrivora-ai/rag-engine",
|
|
3047
|
-
version: "2.
|
|
3047
|
+
version: "2.3.0",
|
|
3048
3048
|
description: "Retrivora AI is a plug-and-play AI engine for RAG chat experiences \u2014 generic vector DB + LLM provider, embeddable or standalone.",
|
|
3049
3049
|
author: "Abhinav Alkuchi",
|
|
3050
3050
|
license: "UNLICENSED",
|
|
@@ -3276,7 +3276,8 @@ var LicenseVerifier = class {
|
|
|
3276
3276
|
};
|
|
3277
3277
|
}
|
|
3278
3278
|
try {
|
|
3279
|
-
const
|
|
3279
|
+
const sanitizedKey = (licenseKey || "").trim().replace(/^["']|["']$/g, "").trim();
|
|
3280
|
+
const rawToken = sanitizedKey.replace(/^rtv_/i, "").trim();
|
|
3280
3281
|
const parts = rawToken.split(".");
|
|
3281
3282
|
if (parts.length !== 3) {
|
|
3282
3283
|
throw new Error("Malformed token structure (expected 3 parts).");
|
|
@@ -3485,10 +3486,11 @@ var _LicenseValidator = class _LicenseValidator {
|
|
|
3485
3486
|
}
|
|
3486
3487
|
return void 0;
|
|
3487
3488
|
};
|
|
3488
|
-
const
|
|
3489
|
+
const rawKey = licenseKey || getHeader("x-license-key") || ((_a = getHeader("authorization")) == null ? void 0 : _a.replace(/^Bearer\s+/i, "")) || (typeof process !== "undefined" ? process.env.NEXT_PUBLIC_RETRIVORA_LICENSE_KEY || process.env.RETRIVORA_LICENSE_KEY : "") || "";
|
|
3490
|
+
const effectiveLicenseKey = (rawKey || "").trim().replace(/^["']|["']$/g, "").trim();
|
|
3489
3491
|
if (!effectiveLicenseKey) {
|
|
3490
3492
|
this.purgeCache(effectiveLicenseKey);
|
|
3491
|
-
throw new LicenseValidationError("Missing RETRIVORA_LICENSE_KEY in request.");
|
|
3493
|
+
throw new LicenseValidationError("Missing RETRIVORA_LICENSE_KEY in request. Set NEXT_PUBLIC_RETRIVORA_LICENSE_KEY in your environment or pass licenseKey as a prop.");
|
|
3492
3494
|
}
|
|
3493
3495
|
const cached = this.cache.get(effectiveLicenseKey);
|
|
3494
3496
|
if (cached) {
|
|
@@ -3512,7 +3514,7 @@ var _LicenseValidator = class _LicenseValidator {
|
|
|
3512
3514
|
"x-sdk-version": sdkVersion
|
|
3513
3515
|
}, customHeaders || {}),
|
|
3514
3516
|
body: JSON.stringify({
|
|
3515
|
-
licenseKey,
|
|
3517
|
+
licenseKey: effectiveLicenseKey,
|
|
3516
3518
|
projectId,
|
|
3517
3519
|
sdkVersion,
|
|
3518
3520
|
sdk,
|
|
@@ -3521,7 +3523,7 @@ var _LicenseValidator = class _LicenseValidator {
|
|
|
3521
3523
|
});
|
|
3522
3524
|
} catch (err) {
|
|
3523
3525
|
try {
|
|
3524
|
-
const payload = LicenseVerifier.verify(
|
|
3526
|
+
const payload = LicenseVerifier.verify(effectiveLicenseKey, projectId || "my-rag-app");
|
|
3525
3527
|
const fallbackResp = {
|
|
3526
3528
|
valid: true,
|
|
3527
3529
|
licenseStatus: "ACTIVE",
|
|
@@ -3531,16 +3533,16 @@ var _LicenseValidator = class _LicenseValidator {
|
|
|
3531
3533
|
expiresAt: payload.expiresAt ? new Date(payload.expiresAt * 1e3).toISOString() : null,
|
|
3532
3534
|
message: "Local license verification active."
|
|
3533
3535
|
};
|
|
3534
|
-
this.cache.set(
|
|
3536
|
+
this.cache.set(effectiveLicenseKey, { response: fallbackResp, timestamp: Date.now() });
|
|
3535
3537
|
return fallbackResp;
|
|
3536
3538
|
} catch (e) {
|
|
3537
|
-
this.purgeCache(
|
|
3539
|
+
this.purgeCache(effectiveLicenseKey);
|
|
3538
3540
|
throw new LicenseValidationError(`License validation request failed: ${(err == null ? void 0 : err.message) || "Network error"}`);
|
|
3539
3541
|
}
|
|
3540
3542
|
}
|
|
3541
3543
|
if (res && !res.ok) {
|
|
3542
3544
|
try {
|
|
3543
|
-
const payload = LicenseVerifier.verify(
|
|
3545
|
+
const payload = LicenseVerifier.verify(effectiveLicenseKey, projectId || "my-rag-app");
|
|
3544
3546
|
const fallbackResp = {
|
|
3545
3547
|
valid: true,
|
|
3546
3548
|
licenseStatus: "ACTIVE",
|
|
@@ -3550,7 +3552,7 @@ var _LicenseValidator = class _LicenseValidator {
|
|
|
3550
3552
|
expiresAt: payload.expiresAt ? new Date(payload.expiresAt * 1e3).toISOString() : null,
|
|
3551
3553
|
message: "Local license verification active."
|
|
3552
3554
|
};
|
|
3553
|
-
this.cache.set(
|
|
3555
|
+
this.cache.set(effectiveLicenseKey, { response: fallbackResp, timestamp: Date.now() });
|
|
3554
3556
|
return fallbackResp;
|
|
3555
3557
|
} catch (e) {
|
|
3556
3558
|
}
|
|
@@ -3565,7 +3567,7 @@ var _LicenseValidator = class _LicenseValidator {
|
|
|
3565
3567
|
message: "Failed to parse license validation response."
|
|
3566
3568
|
}));
|
|
3567
3569
|
if (!res.ok || !data.valid || data.licenseStatus !== "ACTIVE" || data.forceUpgrade) {
|
|
3568
|
-
this.purgeCache(
|
|
3570
|
+
this.purgeCache(effectiveLicenseKey);
|
|
3569
3571
|
if (data.forceUpgrade || res.status === 426) {
|
|
3570
3572
|
throw new SDKVersionUnsupportedError(
|
|
3571
3573
|
data.message || `This SDK version (${sdkVersion}) is no longer supported. Upgrade to version ${data.latestVersion || "2.2.6"} or later.`,
|
|
@@ -3575,7 +3577,7 @@ var _LicenseValidator = class _LicenseValidator {
|
|
|
3575
3577
|
const errMsg = data.message || `License validation failed with status: ${data.licenseStatus}. Access denied.`;
|
|
3576
3578
|
throw new LicenseValidationError(errMsg, data);
|
|
3577
3579
|
}
|
|
3578
|
-
this.cache.set(
|
|
3580
|
+
this.cache.set(effectiveLicenseKey, {
|
|
3579
3581
|
response: data,
|
|
3580
3582
|
timestamp: Date.now()
|
|
3581
3583
|
});
|
package/dist/index.mjs
CHANGED
|
@@ -3049,7 +3049,7 @@ function useRagChat(projectId, options = {}) {
|
|
|
3049
3049
|
// package.json
|
|
3050
3050
|
var package_default = {
|
|
3051
3051
|
name: "@retrivora-ai/rag-engine",
|
|
3052
|
-
version: "2.
|
|
3052
|
+
version: "2.3.0",
|
|
3053
3053
|
description: "Retrivora AI is a plug-and-play AI engine for RAG chat experiences \u2014 generic vector DB + LLM provider, embeddable or standalone.",
|
|
3054
3054
|
author: "Abhinav Alkuchi",
|
|
3055
3055
|
license: "UNLICENSED",
|
|
@@ -3281,7 +3281,8 @@ var LicenseVerifier = class {
|
|
|
3281
3281
|
};
|
|
3282
3282
|
}
|
|
3283
3283
|
try {
|
|
3284
|
-
const
|
|
3284
|
+
const sanitizedKey = (licenseKey || "").trim().replace(/^["']|["']$/g, "").trim();
|
|
3285
|
+
const rawToken = sanitizedKey.replace(/^rtv_/i, "").trim();
|
|
3285
3286
|
const parts = rawToken.split(".");
|
|
3286
3287
|
if (parts.length !== 3) {
|
|
3287
3288
|
throw new Error("Malformed token structure (expected 3 parts).");
|
|
@@ -3490,10 +3491,11 @@ var _LicenseValidator = class _LicenseValidator {
|
|
|
3490
3491
|
}
|
|
3491
3492
|
return void 0;
|
|
3492
3493
|
};
|
|
3493
|
-
const
|
|
3494
|
+
const rawKey = licenseKey || getHeader("x-license-key") || ((_a = getHeader("authorization")) == null ? void 0 : _a.replace(/^Bearer\s+/i, "")) || (typeof process !== "undefined" ? process.env.NEXT_PUBLIC_RETRIVORA_LICENSE_KEY || process.env.RETRIVORA_LICENSE_KEY : "") || "";
|
|
3495
|
+
const effectiveLicenseKey = (rawKey || "").trim().replace(/^["']|["']$/g, "").trim();
|
|
3494
3496
|
if (!effectiveLicenseKey) {
|
|
3495
3497
|
this.purgeCache(effectiveLicenseKey);
|
|
3496
|
-
throw new LicenseValidationError("Missing RETRIVORA_LICENSE_KEY in request.");
|
|
3498
|
+
throw new LicenseValidationError("Missing RETRIVORA_LICENSE_KEY in request. Set NEXT_PUBLIC_RETRIVORA_LICENSE_KEY in your environment or pass licenseKey as a prop.");
|
|
3497
3499
|
}
|
|
3498
3500
|
const cached = this.cache.get(effectiveLicenseKey);
|
|
3499
3501
|
if (cached) {
|
|
@@ -3517,7 +3519,7 @@ var _LicenseValidator = class _LicenseValidator {
|
|
|
3517
3519
|
"x-sdk-version": sdkVersion
|
|
3518
3520
|
}, customHeaders || {}),
|
|
3519
3521
|
body: JSON.stringify({
|
|
3520
|
-
licenseKey,
|
|
3522
|
+
licenseKey: effectiveLicenseKey,
|
|
3521
3523
|
projectId,
|
|
3522
3524
|
sdkVersion,
|
|
3523
3525
|
sdk,
|
|
@@ -3526,7 +3528,7 @@ var _LicenseValidator = class _LicenseValidator {
|
|
|
3526
3528
|
});
|
|
3527
3529
|
} catch (err) {
|
|
3528
3530
|
try {
|
|
3529
|
-
const payload = LicenseVerifier.verify(
|
|
3531
|
+
const payload = LicenseVerifier.verify(effectiveLicenseKey, projectId || "my-rag-app");
|
|
3530
3532
|
const fallbackResp = {
|
|
3531
3533
|
valid: true,
|
|
3532
3534
|
licenseStatus: "ACTIVE",
|
|
@@ -3536,16 +3538,16 @@ var _LicenseValidator = class _LicenseValidator {
|
|
|
3536
3538
|
expiresAt: payload.expiresAt ? new Date(payload.expiresAt * 1e3).toISOString() : null,
|
|
3537
3539
|
message: "Local license verification active."
|
|
3538
3540
|
};
|
|
3539
|
-
this.cache.set(
|
|
3541
|
+
this.cache.set(effectiveLicenseKey, { response: fallbackResp, timestamp: Date.now() });
|
|
3540
3542
|
return fallbackResp;
|
|
3541
3543
|
} catch (e) {
|
|
3542
|
-
this.purgeCache(
|
|
3544
|
+
this.purgeCache(effectiveLicenseKey);
|
|
3543
3545
|
throw new LicenseValidationError(`License validation request failed: ${(err == null ? void 0 : err.message) || "Network error"}`);
|
|
3544
3546
|
}
|
|
3545
3547
|
}
|
|
3546
3548
|
if (res && !res.ok) {
|
|
3547
3549
|
try {
|
|
3548
|
-
const payload = LicenseVerifier.verify(
|
|
3550
|
+
const payload = LicenseVerifier.verify(effectiveLicenseKey, projectId || "my-rag-app");
|
|
3549
3551
|
const fallbackResp = {
|
|
3550
3552
|
valid: true,
|
|
3551
3553
|
licenseStatus: "ACTIVE",
|
|
@@ -3555,7 +3557,7 @@ var _LicenseValidator = class _LicenseValidator {
|
|
|
3555
3557
|
expiresAt: payload.expiresAt ? new Date(payload.expiresAt * 1e3).toISOString() : null,
|
|
3556
3558
|
message: "Local license verification active."
|
|
3557
3559
|
};
|
|
3558
|
-
this.cache.set(
|
|
3560
|
+
this.cache.set(effectiveLicenseKey, { response: fallbackResp, timestamp: Date.now() });
|
|
3559
3561
|
return fallbackResp;
|
|
3560
3562
|
} catch (e) {
|
|
3561
3563
|
}
|
|
@@ -3570,7 +3572,7 @@ var _LicenseValidator = class _LicenseValidator {
|
|
|
3570
3572
|
message: "Failed to parse license validation response."
|
|
3571
3573
|
}));
|
|
3572
3574
|
if (!res.ok || !data.valid || data.licenseStatus !== "ACTIVE" || data.forceUpgrade) {
|
|
3573
|
-
this.purgeCache(
|
|
3575
|
+
this.purgeCache(effectiveLicenseKey);
|
|
3574
3576
|
if (data.forceUpgrade || res.status === 426) {
|
|
3575
3577
|
throw new SDKVersionUnsupportedError(
|
|
3576
3578
|
data.message || `This SDK version (${sdkVersion}) is no longer supported. Upgrade to version ${data.latestVersion || "2.2.6"} or later.`,
|
|
@@ -3580,7 +3582,7 @@ var _LicenseValidator = class _LicenseValidator {
|
|
|
3580
3582
|
const errMsg = data.message || `License validation failed with status: ${data.licenseStatus}. Access denied.`;
|
|
3581
3583
|
throw new LicenseValidationError(errMsg, data);
|
|
3582
3584
|
}
|
|
3583
|
-
this.cache.set(
|
|
3585
|
+
this.cache.set(effectiveLicenseKey, {
|
|
3584
3586
|
response: data,
|
|
3585
3587
|
timestamp: Date.now()
|
|
3586
3588
|
});
|
package/dist/server.js
CHANGED
|
@@ -2417,7 +2417,8 @@ var LicenseVerifier = class {
|
|
|
2417
2417
|
};
|
|
2418
2418
|
}
|
|
2419
2419
|
try {
|
|
2420
|
-
const
|
|
2420
|
+
const sanitizedKey = (licenseKey || "").trim().replace(/^["']|["']$/g, "").trim();
|
|
2421
|
+
const rawToken = sanitizedKey.replace(/^rtv_/i, "").trim();
|
|
2421
2422
|
const parts = rawToken.split(".");
|
|
2422
2423
|
if (parts.length !== 3) {
|
|
2423
2424
|
throw new Error("Malformed token structure (expected 3 parts).");
|
|
@@ -4823,7 +4824,7 @@ var ConfigValidator = class {
|
|
|
4823
4824
|
// package.json
|
|
4824
4825
|
var package_default = {
|
|
4825
4826
|
name: "@retrivora-ai/rag-engine",
|
|
4826
|
-
version: "2.
|
|
4827
|
+
version: "2.3.0",
|
|
4827
4828
|
description: "Retrivora AI is a plug-and-play AI engine for RAG chat experiences \u2014 generic vector DB + LLM provider, embeddable or standalone.",
|
|
4828
4829
|
author: "Abhinav Alkuchi",
|
|
4829
4830
|
license: "UNLICENSED",
|
|
@@ -11024,7 +11025,8 @@ function createLicenseHandler(configOrPlugin, options) {
|
|
|
11024
11025
|
try {
|
|
11025
11026
|
const body = await req.json().catch(() => ({}));
|
|
11026
11027
|
const config = plugin.getConfig();
|
|
11027
|
-
const
|
|
11028
|
+
const rawKey = req.headers.get("x-license-key") || (body == null ? void 0 : body.licenseKey) || ((_a2 = req.headers.get("authorization")) == null ? void 0 : _a2.replace(/^Bearer\s+/i, "")) || config.licenseKey || process.env.NEXT_PUBLIC_RETRIVORA_LICENSE_KEY || process.env.RETRIVORA_LICENSE_KEY || "";
|
|
11029
|
+
const licenseKey = (rawKey || "").trim().replace(/^["']|["']$/g, "").trim();
|
|
11028
11030
|
const projectId = (body == null ? void 0 : body.projectId) || config.projectId || "my-rag-app";
|
|
11029
11031
|
const payload = LicenseVerifier.verify(licenseKey, projectId);
|
|
11030
11032
|
return import_server.NextResponse.json({
|
|
@@ -11433,10 +11435,11 @@ var _LicenseValidator = class _LicenseValidator {
|
|
|
11433
11435
|
}
|
|
11434
11436
|
return void 0;
|
|
11435
11437
|
};
|
|
11436
|
-
const
|
|
11438
|
+
const rawKey = licenseKey || getHeader("x-license-key") || ((_a2 = getHeader("authorization")) == null ? void 0 : _a2.replace(/^Bearer\s+/i, "")) || (typeof process !== "undefined" ? process.env.NEXT_PUBLIC_RETRIVORA_LICENSE_KEY || process.env.RETRIVORA_LICENSE_KEY : "") || "";
|
|
11439
|
+
const effectiveLicenseKey = (rawKey || "").trim().replace(/^["']|["']$/g, "").trim();
|
|
11437
11440
|
if (!effectiveLicenseKey) {
|
|
11438
11441
|
this.purgeCache(effectiveLicenseKey);
|
|
11439
|
-
throw new LicenseValidationError("Missing RETRIVORA_LICENSE_KEY in request.");
|
|
11442
|
+
throw new LicenseValidationError("Missing RETRIVORA_LICENSE_KEY in request. Set NEXT_PUBLIC_RETRIVORA_LICENSE_KEY in your environment or pass licenseKey as a prop.");
|
|
11440
11443
|
}
|
|
11441
11444
|
const cached = this.cache.get(effectiveLicenseKey);
|
|
11442
11445
|
if (cached) {
|
|
@@ -11460,7 +11463,7 @@ var _LicenseValidator = class _LicenseValidator {
|
|
|
11460
11463
|
"x-sdk-version": sdkVersion
|
|
11461
11464
|
}, customHeaders || {}),
|
|
11462
11465
|
body: JSON.stringify({
|
|
11463
|
-
licenseKey,
|
|
11466
|
+
licenseKey: effectiveLicenseKey,
|
|
11464
11467
|
projectId,
|
|
11465
11468
|
sdkVersion,
|
|
11466
11469
|
sdk,
|
|
@@ -11469,7 +11472,7 @@ var _LicenseValidator = class _LicenseValidator {
|
|
|
11469
11472
|
});
|
|
11470
11473
|
} catch (err) {
|
|
11471
11474
|
try {
|
|
11472
|
-
const payload = LicenseVerifier.verify(
|
|
11475
|
+
const payload = LicenseVerifier.verify(effectiveLicenseKey, projectId || "my-rag-app");
|
|
11473
11476
|
const fallbackResp = {
|
|
11474
11477
|
valid: true,
|
|
11475
11478
|
licenseStatus: "ACTIVE",
|
|
@@ -11479,16 +11482,16 @@ var _LicenseValidator = class _LicenseValidator {
|
|
|
11479
11482
|
expiresAt: payload.expiresAt ? new Date(payload.expiresAt * 1e3).toISOString() : null,
|
|
11480
11483
|
message: "Local license verification active."
|
|
11481
11484
|
};
|
|
11482
|
-
this.cache.set(
|
|
11485
|
+
this.cache.set(effectiveLicenseKey, { response: fallbackResp, timestamp: Date.now() });
|
|
11483
11486
|
return fallbackResp;
|
|
11484
11487
|
} catch (e) {
|
|
11485
|
-
this.purgeCache(
|
|
11488
|
+
this.purgeCache(effectiveLicenseKey);
|
|
11486
11489
|
throw new LicenseValidationError(`License validation request failed: ${(err == null ? void 0 : err.message) || "Network error"}`);
|
|
11487
11490
|
}
|
|
11488
11491
|
}
|
|
11489
11492
|
if (res && !res.ok) {
|
|
11490
11493
|
try {
|
|
11491
|
-
const payload = LicenseVerifier.verify(
|
|
11494
|
+
const payload = LicenseVerifier.verify(effectiveLicenseKey, projectId || "my-rag-app");
|
|
11492
11495
|
const fallbackResp = {
|
|
11493
11496
|
valid: true,
|
|
11494
11497
|
licenseStatus: "ACTIVE",
|
|
@@ -11498,7 +11501,7 @@ var _LicenseValidator = class _LicenseValidator {
|
|
|
11498
11501
|
expiresAt: payload.expiresAt ? new Date(payload.expiresAt * 1e3).toISOString() : null,
|
|
11499
11502
|
message: "Local license verification active."
|
|
11500
11503
|
};
|
|
11501
|
-
this.cache.set(
|
|
11504
|
+
this.cache.set(effectiveLicenseKey, { response: fallbackResp, timestamp: Date.now() });
|
|
11502
11505
|
return fallbackResp;
|
|
11503
11506
|
} catch (e) {
|
|
11504
11507
|
}
|
|
@@ -11513,7 +11516,7 @@ var _LicenseValidator = class _LicenseValidator {
|
|
|
11513
11516
|
message: "Failed to parse license validation response."
|
|
11514
11517
|
}));
|
|
11515
11518
|
if (!res.ok || !data.valid || data.licenseStatus !== "ACTIVE" || data.forceUpgrade) {
|
|
11516
|
-
this.purgeCache(
|
|
11519
|
+
this.purgeCache(effectiveLicenseKey);
|
|
11517
11520
|
if (data.forceUpgrade || res.status === 426) {
|
|
11518
11521
|
throw new SDKVersionUnsupportedError(
|
|
11519
11522
|
data.message || `This SDK version (${sdkVersion}) is no longer supported. Upgrade to version ${data.latestVersion || "2.2.6"} or later.`,
|
|
@@ -11523,7 +11526,7 @@ var _LicenseValidator = class _LicenseValidator {
|
|
|
11523
11526
|
const errMsg = data.message || `License validation failed with status: ${data.licenseStatus}. Access denied.`;
|
|
11524
11527
|
throw new LicenseValidationError(errMsg, data);
|
|
11525
11528
|
}
|
|
11526
|
-
this.cache.set(
|
|
11529
|
+
this.cache.set(effectiveLicenseKey, {
|
|
11527
11530
|
response: data,
|
|
11528
11531
|
timestamp: Date.now()
|
|
11529
11532
|
});
|
package/dist/server.mjs
CHANGED
|
@@ -2317,7 +2317,8 @@ var LicenseVerifier = class {
|
|
|
2317
2317
|
};
|
|
2318
2318
|
}
|
|
2319
2319
|
try {
|
|
2320
|
-
const
|
|
2320
|
+
const sanitizedKey = (licenseKey || "").trim().replace(/^["']|["']$/g, "").trim();
|
|
2321
|
+
const rawToken = sanitizedKey.replace(/^rtv_/i, "").trim();
|
|
2321
2322
|
const parts = rawToken.split(".");
|
|
2322
2323
|
if (parts.length !== 3) {
|
|
2323
2324
|
throw new Error("Malformed token structure (expected 3 parts).");
|
|
@@ -4723,7 +4724,7 @@ var ConfigValidator = class {
|
|
|
4723
4724
|
// package.json
|
|
4724
4725
|
var package_default = {
|
|
4725
4726
|
name: "@retrivora-ai/rag-engine",
|
|
4726
|
-
version: "2.
|
|
4727
|
+
version: "2.3.0",
|
|
4727
4728
|
description: "Retrivora AI is a plug-and-play AI engine for RAG chat experiences \u2014 generic vector DB + LLM provider, embeddable or standalone.",
|
|
4728
4729
|
author: "Abhinav Alkuchi",
|
|
4729
4730
|
license: "UNLICENSED",
|
|
@@ -10924,7 +10925,8 @@ function createLicenseHandler(configOrPlugin, options) {
|
|
|
10924
10925
|
try {
|
|
10925
10926
|
const body = await req.json().catch(() => ({}));
|
|
10926
10927
|
const config = plugin.getConfig();
|
|
10927
|
-
const
|
|
10928
|
+
const rawKey = req.headers.get("x-license-key") || (body == null ? void 0 : body.licenseKey) || ((_a2 = req.headers.get("authorization")) == null ? void 0 : _a2.replace(/^Bearer\s+/i, "")) || config.licenseKey || process.env.NEXT_PUBLIC_RETRIVORA_LICENSE_KEY || process.env.RETRIVORA_LICENSE_KEY || "";
|
|
10929
|
+
const licenseKey = (rawKey || "").trim().replace(/^["']|["']$/g, "").trim();
|
|
10928
10930
|
const projectId = (body == null ? void 0 : body.projectId) || config.projectId || "my-rag-app";
|
|
10929
10931
|
const payload = LicenseVerifier.verify(licenseKey, projectId);
|
|
10930
10932
|
return NextResponse.json({
|
|
@@ -11333,10 +11335,11 @@ var _LicenseValidator = class _LicenseValidator {
|
|
|
11333
11335
|
}
|
|
11334
11336
|
return void 0;
|
|
11335
11337
|
};
|
|
11336
|
-
const
|
|
11338
|
+
const rawKey = licenseKey || getHeader("x-license-key") || ((_a2 = getHeader("authorization")) == null ? void 0 : _a2.replace(/^Bearer\s+/i, "")) || (typeof process !== "undefined" ? process.env.NEXT_PUBLIC_RETRIVORA_LICENSE_KEY || process.env.RETRIVORA_LICENSE_KEY : "") || "";
|
|
11339
|
+
const effectiveLicenseKey = (rawKey || "").trim().replace(/^["']|["']$/g, "").trim();
|
|
11337
11340
|
if (!effectiveLicenseKey) {
|
|
11338
11341
|
this.purgeCache(effectiveLicenseKey);
|
|
11339
|
-
throw new LicenseValidationError("Missing RETRIVORA_LICENSE_KEY in request.");
|
|
11342
|
+
throw new LicenseValidationError("Missing RETRIVORA_LICENSE_KEY in request. Set NEXT_PUBLIC_RETRIVORA_LICENSE_KEY in your environment or pass licenseKey as a prop.");
|
|
11340
11343
|
}
|
|
11341
11344
|
const cached = this.cache.get(effectiveLicenseKey);
|
|
11342
11345
|
if (cached) {
|
|
@@ -11360,7 +11363,7 @@ var _LicenseValidator = class _LicenseValidator {
|
|
|
11360
11363
|
"x-sdk-version": sdkVersion
|
|
11361
11364
|
}, customHeaders || {}),
|
|
11362
11365
|
body: JSON.stringify({
|
|
11363
|
-
licenseKey,
|
|
11366
|
+
licenseKey: effectiveLicenseKey,
|
|
11364
11367
|
projectId,
|
|
11365
11368
|
sdkVersion,
|
|
11366
11369
|
sdk,
|
|
@@ -11369,7 +11372,7 @@ var _LicenseValidator = class _LicenseValidator {
|
|
|
11369
11372
|
});
|
|
11370
11373
|
} catch (err) {
|
|
11371
11374
|
try {
|
|
11372
|
-
const payload = LicenseVerifier.verify(
|
|
11375
|
+
const payload = LicenseVerifier.verify(effectiveLicenseKey, projectId || "my-rag-app");
|
|
11373
11376
|
const fallbackResp = {
|
|
11374
11377
|
valid: true,
|
|
11375
11378
|
licenseStatus: "ACTIVE",
|
|
@@ -11379,16 +11382,16 @@ var _LicenseValidator = class _LicenseValidator {
|
|
|
11379
11382
|
expiresAt: payload.expiresAt ? new Date(payload.expiresAt * 1e3).toISOString() : null,
|
|
11380
11383
|
message: "Local license verification active."
|
|
11381
11384
|
};
|
|
11382
|
-
this.cache.set(
|
|
11385
|
+
this.cache.set(effectiveLicenseKey, { response: fallbackResp, timestamp: Date.now() });
|
|
11383
11386
|
return fallbackResp;
|
|
11384
11387
|
} catch (e) {
|
|
11385
|
-
this.purgeCache(
|
|
11388
|
+
this.purgeCache(effectiveLicenseKey);
|
|
11386
11389
|
throw new LicenseValidationError(`License validation request failed: ${(err == null ? void 0 : err.message) || "Network error"}`);
|
|
11387
11390
|
}
|
|
11388
11391
|
}
|
|
11389
11392
|
if (res && !res.ok) {
|
|
11390
11393
|
try {
|
|
11391
|
-
const payload = LicenseVerifier.verify(
|
|
11394
|
+
const payload = LicenseVerifier.verify(effectiveLicenseKey, projectId || "my-rag-app");
|
|
11392
11395
|
const fallbackResp = {
|
|
11393
11396
|
valid: true,
|
|
11394
11397
|
licenseStatus: "ACTIVE",
|
|
@@ -11398,7 +11401,7 @@ var _LicenseValidator = class _LicenseValidator {
|
|
|
11398
11401
|
expiresAt: payload.expiresAt ? new Date(payload.expiresAt * 1e3).toISOString() : null,
|
|
11399
11402
|
message: "Local license verification active."
|
|
11400
11403
|
};
|
|
11401
|
-
this.cache.set(
|
|
11404
|
+
this.cache.set(effectiveLicenseKey, { response: fallbackResp, timestamp: Date.now() });
|
|
11402
11405
|
return fallbackResp;
|
|
11403
11406
|
} catch (e) {
|
|
11404
11407
|
}
|
|
@@ -11413,7 +11416,7 @@ var _LicenseValidator = class _LicenseValidator {
|
|
|
11413
11416
|
message: "Failed to parse license validation response."
|
|
11414
11417
|
}));
|
|
11415
11418
|
if (!res.ok || !data.valid || data.licenseStatus !== "ACTIVE" || data.forceUpgrade) {
|
|
11416
|
-
this.purgeCache(
|
|
11419
|
+
this.purgeCache(effectiveLicenseKey);
|
|
11417
11420
|
if (data.forceUpgrade || res.status === 426) {
|
|
11418
11421
|
throw new SDKVersionUnsupportedError(
|
|
11419
11422
|
data.message || `This SDK version (${sdkVersion}) is no longer supported. Upgrade to version ${data.latestVersion || "2.2.6"} or later.`,
|
|
@@ -11423,7 +11426,7 @@ var _LicenseValidator = class _LicenseValidator {
|
|
|
11423
11426
|
const errMsg = data.message || `License validation failed with status: ${data.licenseStatus}. Access denied.`;
|
|
11424
11427
|
throw new LicenseValidationError(errMsg, data);
|
|
11425
11428
|
}
|
|
11426
|
-
this.cache.set(
|
|
11429
|
+
this.cache.set(effectiveLicenseKey, {
|
|
11427
11430
|
response: data,
|
|
11428
11431
|
timestamp: Date.now()
|
|
11429
11432
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@retrivora-ai/rag-engine",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.3.0",
|
|
4
4
|
"description": "Retrivora AI is a plug-and-play AI engine for RAG chat experiences — generic vector DB + LLM provider, embeddable or standalone.",
|
|
5
5
|
"author": "Abhinav Alkuchi",
|
|
6
6
|
"license": "UNLICENSED",
|
|
@@ -75,7 +75,7 @@ export class LicenseValidator {
|
|
|
75
75
|
return undefined;
|
|
76
76
|
};
|
|
77
77
|
|
|
78
|
-
const
|
|
78
|
+
const rawKey =
|
|
79
79
|
licenseKey ||
|
|
80
80
|
getHeader('x-license-key') ||
|
|
81
81
|
getHeader('authorization')?.replace(/^Bearer\s+/i, '') ||
|
|
@@ -84,9 +84,11 @@ export class LicenseValidator {
|
|
|
84
84
|
: '') ||
|
|
85
85
|
'';
|
|
86
86
|
|
|
87
|
+
const effectiveLicenseKey = (rawKey || '').trim().replace(/^["']|["']$/g, '').trim();
|
|
88
|
+
|
|
87
89
|
if (!effectiveLicenseKey) {
|
|
88
90
|
this.purgeCache(effectiveLicenseKey);
|
|
89
|
-
throw new LicenseValidationError('Missing RETRIVORA_LICENSE_KEY in request.');
|
|
91
|
+
throw new LicenseValidationError('Missing RETRIVORA_LICENSE_KEY in request. Set NEXT_PUBLIC_RETRIVORA_LICENSE_KEY in your environment or pass licenseKey as a prop.');
|
|
90
92
|
}
|
|
91
93
|
|
|
92
94
|
// 1. Check successful 5-minute cache
|
|
@@ -100,7 +102,7 @@ export class LicenseValidator {
|
|
|
100
102
|
}
|
|
101
103
|
}
|
|
102
104
|
|
|
103
|
-
// 2. Fetch live validation from Retrivora backend API
|
|
105
|
+
// 2. Fetch live validation from Retrivora backend API / local catch-all route
|
|
104
106
|
const base = retrivoraApiBase || (typeof process !== 'undefined' ? process.env.NEXT_PUBLIC_RETRIVORA_API_BASE || process.env.RETRIVORA_API_BASE : '') || '/api/retrivora';
|
|
105
107
|
const validateUrl = `${base.replace(/\/$/, '')}/v1/license/validate`;
|
|
106
108
|
|
|
@@ -116,7 +118,7 @@ export class LicenseValidator {
|
|
|
116
118
|
...(customHeaders || {}),
|
|
117
119
|
},
|
|
118
120
|
body: JSON.stringify({
|
|
119
|
-
licenseKey,
|
|
121
|
+
licenseKey: effectiveLicenseKey,
|
|
120
122
|
projectId,
|
|
121
123
|
sdkVersion,
|
|
122
124
|
sdk,
|
|
@@ -126,7 +128,7 @@ export class LicenseValidator {
|
|
|
126
128
|
} catch (err: any) {
|
|
127
129
|
// Fallback: If network error occurs, verify locally via RSA LicenseVerifier
|
|
128
130
|
try {
|
|
129
|
-
const payload = LicenseVerifier.verify(
|
|
131
|
+
const payload = LicenseVerifier.verify(effectiveLicenseKey, projectId || 'my-rag-app');
|
|
130
132
|
const fallbackResp: LicenseValidationResponse = {
|
|
131
133
|
valid: true,
|
|
132
134
|
licenseStatus: 'ACTIVE',
|
|
@@ -136,10 +138,10 @@ export class LicenseValidator {
|
|
|
136
138
|
expiresAt: payload.expiresAt ? new Date(payload.expiresAt * 1000).toISOString() : null,
|
|
137
139
|
message: 'Local license verification active.',
|
|
138
140
|
};
|
|
139
|
-
this.cache.set(
|
|
141
|
+
this.cache.set(effectiveLicenseKey, { response: fallbackResp, timestamp: Date.now() });
|
|
140
142
|
return fallbackResp;
|
|
141
143
|
} catch {
|
|
142
|
-
this.purgeCache(
|
|
144
|
+
this.purgeCache(effectiveLicenseKey);
|
|
143
145
|
throw new LicenseValidationError(`License validation request failed: ${err?.message || 'Network error'}`);
|
|
144
146
|
}
|
|
145
147
|
}
|
|
@@ -147,7 +149,7 @@ export class LicenseValidator {
|
|
|
147
149
|
if (res && !res.ok) {
|
|
148
150
|
// Attempt local verification fallback if API route returned 404 or non-OK response
|
|
149
151
|
try {
|
|
150
|
-
const payload = LicenseVerifier.verify(
|
|
152
|
+
const payload = LicenseVerifier.verify(effectiveLicenseKey, projectId || 'my-rag-app');
|
|
151
153
|
const fallbackResp: LicenseValidationResponse = {
|
|
152
154
|
valid: true,
|
|
153
155
|
licenseStatus: 'ACTIVE',
|
|
@@ -157,7 +159,7 @@ export class LicenseValidator {
|
|
|
157
159
|
expiresAt: payload.expiresAt ? new Date(payload.expiresAt * 1000).toISOString() : null,
|
|
158
160
|
message: 'Local license verification active.',
|
|
159
161
|
};
|
|
160
|
-
this.cache.set(
|
|
162
|
+
this.cache.set(effectiveLicenseKey, { response: fallbackResp, timestamp: Date.now() });
|
|
161
163
|
return fallbackResp;
|
|
162
164
|
} catch { /* proceed to parse error response */ }
|
|
163
165
|
}
|
|
@@ -174,7 +176,7 @@ export class LicenseValidator {
|
|
|
174
176
|
|
|
175
177
|
// 3. Negative validation responses immediately purge any existing cache
|
|
176
178
|
if (!res.ok || !data.valid || data.licenseStatus !== 'ACTIVE' || data.forceUpgrade) {
|
|
177
|
-
this.purgeCache(
|
|
179
|
+
this.purgeCache(effectiveLicenseKey);
|
|
178
180
|
|
|
179
181
|
if (data.forceUpgrade || res.status === 426) {
|
|
180
182
|
throw new SDKVersionUnsupportedError(
|
|
@@ -188,7 +190,7 @@ export class LicenseValidator {
|
|
|
188
190
|
}
|
|
189
191
|
|
|
190
192
|
// 4. Cache SUCCESSFUL validation only (TTL = 5 minutes)
|
|
191
|
-
this.cache.set(
|
|
193
|
+
this.cache.set(effectiveLicenseKey, {
|
|
192
194
|
response: data,
|
|
193
195
|
timestamp: Date.now(),
|
|
194
196
|
});
|
|
@@ -80,7 +80,8 @@ MwIDAQAB
|
|
|
80
80
|
}
|
|
81
81
|
|
|
82
82
|
try {
|
|
83
|
-
const
|
|
83
|
+
const sanitizedKey = (licenseKey || '').trim().replace(/^["']|["']$/g, '').trim();
|
|
84
|
+
const rawToken = sanitizedKey.replace(/^rtv_/i, '').trim();
|
|
84
85
|
const parts = rawToken.split('.');
|
|
85
86
|
if (parts.length !== 3) {
|
|
86
87
|
throw new Error('Malformed token structure (expected 3 parts).');
|
|
@@ -90,7 +91,7 @@ MwIDAQAB
|
|
|
90
91
|
const dataToVerify = `${headerB64}.${payloadB64}`;
|
|
91
92
|
|
|
92
93
|
const publicKey = publicKeyOverride ?? this.PUBLIC_KEY;
|
|
93
|
-
|
|
94
|
+
|
|
94
95
|
// 2. Cryptographic signature check
|
|
95
96
|
const signature = Buffer.from(signatureB64, 'base64url');
|
|
96
97
|
const data = Buffer.from(dataToVerify);
|
|
@@ -123,7 +124,7 @@ MwIDAQAB
|
|
|
123
124
|
if (!isProjectMatch) {
|
|
124
125
|
throw new Error(
|
|
125
126
|
`Project ID mismatch. License is bound to project namespace "${payload.projectId}" ` +
|
|
126
|
-
|
|
127
|
+
`but configuration has "${currentProjectId}".`
|
|
127
128
|
);
|
|
128
129
|
}
|
|
129
130
|
|
|
@@ -206,18 +207,18 @@ MwIDAQAB
|
|
|
206
207
|
if (payload.ipv4 || payload.ipv6) {
|
|
207
208
|
let currentIpv4 = '';
|
|
208
209
|
let currentIpv6 = '';
|
|
209
|
-
|
|
210
|
+
|
|
210
211
|
try {
|
|
211
212
|
const res = await fetch('https://api4.ipify.org?format=json', { signal: AbortSignal.timeout(3000) });
|
|
212
213
|
const data = await res.json();
|
|
213
214
|
currentIpv4 = data.ip;
|
|
214
|
-
} catch (e) {}
|
|
215
|
-
|
|
215
|
+
} catch (e) { }
|
|
216
|
+
|
|
216
217
|
try {
|
|
217
218
|
const res = await fetch('https://api6.ipify.org?format=json', { signal: AbortSignal.timeout(3000) });
|
|
218
219
|
const data = await res.json();
|
|
219
220
|
currentIpv6 = data.ip;
|
|
220
|
-
} catch (e) {}
|
|
221
|
+
} catch (e) { }
|
|
221
222
|
|
|
222
223
|
const localIps: string[] = [];
|
|
223
224
|
try {
|
|
@@ -230,14 +231,14 @@ MwIDAQAB
|
|
|
230
231
|
}
|
|
231
232
|
}
|
|
232
233
|
}
|
|
233
|
-
} catch (e) {}
|
|
234
|
-
|
|
234
|
+
} catch (e) { }
|
|
235
|
+
|
|
235
236
|
const isIpv4Match = payload.ipv4 && (
|
|
236
|
-
currentIpv4 === payload.ipv4 ||
|
|
237
|
+
currentIpv4 === payload.ipv4 ||
|
|
237
238
|
localIps.includes(payload.ipv4)
|
|
238
239
|
);
|
|
239
240
|
const isIpv6Match = payload.ipv6 && (
|
|
240
|
-
currentIpv6 === payload.ipv6 ||
|
|
241
|
+
currentIpv6 === payload.ipv6 ||
|
|
241
242
|
localIps.includes(payload.ipv6)
|
|
242
243
|
);
|
|
243
244
|
|
package/src/handlers/index.ts
CHANGED
|
@@ -615,15 +615,17 @@ export function createLicenseHandler(
|
|
|
615
615
|
try {
|
|
616
616
|
const body = await req.json().catch(() => ({}));
|
|
617
617
|
const config = plugin.getConfig();
|
|
618
|
-
const
|
|
618
|
+
const rawKey =
|
|
619
619
|
req.headers.get('x-license-key') ||
|
|
620
620
|
body?.licenseKey ||
|
|
621
621
|
req.headers.get('authorization')?.replace(/^Bearer\s+/i, '') ||
|
|
622
622
|
config.licenseKey ||
|
|
623
|
-
process.env.RETRIVORA_LICENSE_KEY ||
|
|
624
623
|
process.env.NEXT_PUBLIC_RETRIVORA_LICENSE_KEY ||
|
|
624
|
+
process.env.RETRIVORA_LICENSE_KEY ||
|
|
625
625
|
'';
|
|
626
626
|
|
|
627
|
+
const licenseKey = (rawKey || '').trim().replace(/^["']|["']$/g, '').trim();
|
|
628
|
+
|
|
627
629
|
const projectId = body?.projectId || config.projectId || 'my-rag-app';
|
|
628
630
|
|
|
629
631
|
const payload = LicenseVerifier.verify(licenseKey, projectId);
|