@retrivora-ai/rag-engine 2.2.7 → 2.2.9
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/{ILLMProvider-BWa68XX5.d.mts → ILLMProvider-teTNQ1lh.d.mts} +2 -0
- package/dist/{ILLMProvider-BWa68XX5.d.ts → ILLMProvider-teTNQ1lh.d.ts} +2 -0
- package/dist/{LicenseValidator-D4I4pbSL.d.ts → LicenseValidator-CENvo9o2.d.mts} +6 -3
- package/dist/{LicenseValidator-B3xpJaVf.d.mts → LicenseValidator-CsjJp2PP.d.ts} +6 -3
- package/dist/handlers/index.d.mts +2 -2
- package/dist/handlers/index.d.ts +2 -2
- package/dist/handlers/index.js +48 -1
- package/dist/handlers/index.mjs +47 -1
- package/dist/{index-B5TTZWkx.d.ts → index-BPJ3KDYI.d.ts} +6 -2
- package/dist/{index-DvbtNz7m.d.mts → index-Dmq5lH0j.d.mts} +6 -2
- package/dist/index.d.mts +6 -6
- package/dist/index.d.ts +6 -6
- package/dist/index.js +302 -25
- package/dist/index.mjs +308 -25
- package/dist/server.d.mts +6 -6
- package/dist/server.d.ts +6 -6
- package/dist/server.js +100 -13
- package/dist/server.mjs +100 -13
- package/package.json +1 -1
- package/src/components/ChatWidget.tsx +21 -3
- package/src/components/ChatWindow.tsx +21 -2
- package/src/core/LicenseValidator.ts +67 -15
- package/src/handlers/index.ts +65 -2
- package/src/hooks/useRagChat.ts +20 -1
- package/src/types/chat.ts +2 -0
- package/src/types/props.ts +5 -2
package/dist/server.js
CHANGED
|
@@ -4823,7 +4823,7 @@ var ConfigValidator = class {
|
|
|
4823
4823
|
// package.json
|
|
4824
4824
|
var package_default = {
|
|
4825
4825
|
name: "@retrivora-ai/rag-engine",
|
|
4826
|
-
version: "2.2.
|
|
4826
|
+
version: "2.2.9",
|
|
4827
4827
|
description: "Retrivora AI is a plug-and-play AI engine for RAG chat experiences \u2014 generic vector DB + LLM provider, embeddable or standalone.",
|
|
4828
4828
|
author: "Abhinav Alkuchi",
|
|
4829
4829
|
license: "UNLICENSED",
|
|
@@ -11012,6 +11012,46 @@ function createHealthHandler(configOrPlugin, options) {
|
|
|
11012
11012
|
}
|
|
11013
11013
|
};
|
|
11014
11014
|
}
|
|
11015
|
+
function createLicenseHandler(configOrPlugin, options) {
|
|
11016
|
+
const plugin = getOrCreatePlugin(configOrPlugin);
|
|
11017
|
+
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
11018
|
+
return async function POST(req) {
|
|
11019
|
+
var _a2;
|
|
11020
|
+
if (req) {
|
|
11021
|
+
const authResult = await checkAuth(req, onAuthorize);
|
|
11022
|
+
if (authResult) return authResult;
|
|
11023
|
+
}
|
|
11024
|
+
try {
|
|
11025
|
+
const body = await req.json().catch(() => ({}));
|
|
11026
|
+
const config = plugin.getConfig();
|
|
11027
|
+
const licenseKey = 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.RETRIVORA_LICENSE_KEY || process.env.NEXT_PUBLIC_RETRIVORA_LICENSE_KEY || "";
|
|
11028
|
+
const projectId = (body == null ? void 0 : body.projectId) || config.projectId || "my-rag-app";
|
|
11029
|
+
const payload = LicenseVerifier.verify(licenseKey, projectId);
|
|
11030
|
+
return import_server.NextResponse.json({
|
|
11031
|
+
valid: true,
|
|
11032
|
+
licenseStatus: "ACTIVE",
|
|
11033
|
+
minimumSupportedVersion: "2.1.0",
|
|
11034
|
+
latestVersion: SDK_VERSION,
|
|
11035
|
+
forceUpgrade: false,
|
|
11036
|
+
expiresAt: payload.expiresAt ? new Date(payload.expiresAt * 1e3).toISOString() : null,
|
|
11037
|
+
message: "License key is active and valid."
|
|
11038
|
+
});
|
|
11039
|
+
} catch (err) {
|
|
11040
|
+
return import_server.NextResponse.json(
|
|
11041
|
+
{
|
|
11042
|
+
valid: false,
|
|
11043
|
+
licenseStatus: "REVOKED",
|
|
11044
|
+
minimumSupportedVersion: "2.1.0",
|
|
11045
|
+
latestVersion: SDK_VERSION,
|
|
11046
|
+
forceUpgrade: false,
|
|
11047
|
+
expiresAt: null,
|
|
11048
|
+
message: (err == null ? void 0 : err.message) || "License validation failed."
|
|
11049
|
+
},
|
|
11050
|
+
{ status: 400 }
|
|
11051
|
+
);
|
|
11052
|
+
}
|
|
11053
|
+
};
|
|
11054
|
+
}
|
|
11015
11055
|
function createUploadHandler(configOrPlugin, options) {
|
|
11016
11056
|
const plugin = getOrCreatePlugin(configOrPlugin);
|
|
11017
11057
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
@@ -11263,6 +11303,7 @@ function createRagHandler(configOrPlugin, options) {
|
|
|
11263
11303
|
const historyHandler = createHistoryHandler(plugin, { onAuthorize });
|
|
11264
11304
|
const feedbackHandler = createFeedbackHandler(plugin, { onAuthorize });
|
|
11265
11305
|
const sessionsHandler = createSessionsHandler(plugin, { onAuthorize });
|
|
11306
|
+
const licenseHandler = createLicenseHandler(plugin, { onAuthorize });
|
|
11266
11307
|
async function routePostRequest(req, segment) {
|
|
11267
11308
|
switch (segment) {
|
|
11268
11309
|
case "chat":
|
|
@@ -11280,6 +11321,9 @@ function createRagHandler(configOrPlugin, options) {
|
|
|
11280
11321
|
return historyHandler(req);
|
|
11281
11322
|
case "feedback":
|
|
11282
11323
|
return feedbackHandler(req);
|
|
11324
|
+
case "license/validate":
|
|
11325
|
+
case "v1/license/validate":
|
|
11326
|
+
return licenseHandler(req);
|
|
11283
11327
|
default:
|
|
11284
11328
|
return import_server.NextResponse.json({ error: `Not Found: POST segment "${segment}" not supported.` }, { status: 404 });
|
|
11285
11329
|
}
|
|
@@ -11309,6 +11353,7 @@ function createRagHandler(configOrPlugin, options) {
|
|
|
11309
11353
|
try {
|
|
11310
11354
|
const url = new URL(req.url);
|
|
11311
11355
|
const pathname = url.pathname;
|
|
11356
|
+
if (pathname.includes("/license/validate")) return "v1/license/validate";
|
|
11312
11357
|
if (pathname.endsWith("/upload")) return "upload";
|
|
11313
11358
|
if (pathname.endsWith("/chat") || pathname.endsWith("/chat-sync")) return "chat";
|
|
11314
11359
|
if (pathname.endsWith("/health")) return "health";
|
|
@@ -11370,6 +11415,7 @@ var _LicenseValidator = class _LicenseValidator {
|
|
|
11370
11415
|
* Validate license status and SDK version against Retrivora License Service
|
|
11371
11416
|
*/
|
|
11372
11417
|
async validate(request) {
|
|
11418
|
+
var _a2;
|
|
11373
11419
|
const {
|
|
11374
11420
|
licenseKey,
|
|
11375
11421
|
projectId,
|
|
@@ -11379,33 +11425,42 @@ var _LicenseValidator = class _LicenseValidator {
|
|
|
11379
11425
|
retrivoraApiBase,
|
|
11380
11426
|
headers: customHeaders
|
|
11381
11427
|
} = request;
|
|
11382
|
-
|
|
11383
|
-
|
|
11384
|
-
|
|
11428
|
+
const getHeader = (name) => {
|
|
11429
|
+
if (!customHeaders) return void 0;
|
|
11430
|
+
const target = name.toLowerCase();
|
|
11431
|
+
for (const [k, v] of Object.entries(customHeaders)) {
|
|
11432
|
+
if (k.toLowerCase() === target) return v;
|
|
11433
|
+
}
|
|
11434
|
+
return void 0;
|
|
11435
|
+
};
|
|
11436
|
+
const effectiveLicenseKey = 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 : "") || "";
|
|
11437
|
+
if (!effectiveLicenseKey) {
|
|
11438
|
+
this.purgeCache(effectiveLicenseKey);
|
|
11439
|
+
throw new LicenseValidationError("Missing RETRIVORA_LICENSE_KEY in request. Set NEXT_PUBLIC_RETRIVORA_LICENSE_KEY in your environment or pass licenseKey as a prop.");
|
|
11385
11440
|
}
|
|
11386
|
-
const cached = this.cache.get(
|
|
11441
|
+
const cached = this.cache.get(effectiveLicenseKey);
|
|
11387
11442
|
if (cached) {
|
|
11388
11443
|
const isFresh = Date.now() - cached.timestamp < _LicenseValidator.SUCCESS_CACHE_TTL_MS;
|
|
11389
11444
|
if (isFresh && cached.response.valid && cached.response.licenseStatus === "ACTIVE" && !cached.response.forceUpgrade) {
|
|
11390
11445
|
return cached.response;
|
|
11391
11446
|
} else {
|
|
11392
|
-
this.cache.delete(
|
|
11447
|
+
this.cache.delete(effectiveLicenseKey);
|
|
11393
11448
|
}
|
|
11394
11449
|
}
|
|
11395
11450
|
const base = retrivoraApiBase || (typeof process !== "undefined" ? process.env.NEXT_PUBLIC_RETRIVORA_API_BASE || process.env.RETRIVORA_API_BASE : "") || "/api/retrivora";
|
|
11396
11451
|
const validateUrl = `${base.replace(/\/$/, "")}/v1/license/validate`;
|
|
11397
|
-
let res;
|
|
11452
|
+
let res = null;
|
|
11398
11453
|
try {
|
|
11399
11454
|
res = await fetch(validateUrl, {
|
|
11400
11455
|
method: "POST",
|
|
11401
11456
|
cache: "no-store",
|
|
11402
11457
|
headers: __spreadValues({
|
|
11403
11458
|
"Content-Type": "application/json",
|
|
11404
|
-
"x-license-key":
|
|
11459
|
+
"x-license-key": effectiveLicenseKey,
|
|
11405
11460
|
"x-sdk-version": sdkVersion
|
|
11406
11461
|
}, customHeaders || {}),
|
|
11407
11462
|
body: JSON.stringify({
|
|
11408
|
-
licenseKey,
|
|
11463
|
+
licenseKey: effectiveLicenseKey,
|
|
11409
11464
|
projectId,
|
|
11410
11465
|
sdkVersion,
|
|
11411
11466
|
sdk,
|
|
@@ -11413,8 +11468,40 @@ var _LicenseValidator = class _LicenseValidator {
|
|
|
11413
11468
|
})
|
|
11414
11469
|
});
|
|
11415
11470
|
} catch (err) {
|
|
11416
|
-
|
|
11417
|
-
|
|
11471
|
+
try {
|
|
11472
|
+
const payload = LicenseVerifier.verify(effectiveLicenseKey, projectId || "my-rag-app");
|
|
11473
|
+
const fallbackResp = {
|
|
11474
|
+
valid: true,
|
|
11475
|
+
licenseStatus: "ACTIVE",
|
|
11476
|
+
minimumSupportedVersion: "2.1.0",
|
|
11477
|
+
latestVersion: SDK_VERSION,
|
|
11478
|
+
forceUpgrade: false,
|
|
11479
|
+
expiresAt: payload.expiresAt ? new Date(payload.expiresAt * 1e3).toISOString() : null,
|
|
11480
|
+
message: "Local license verification active."
|
|
11481
|
+
};
|
|
11482
|
+
this.cache.set(effectiveLicenseKey, { response: fallbackResp, timestamp: Date.now() });
|
|
11483
|
+
return fallbackResp;
|
|
11484
|
+
} catch (e) {
|
|
11485
|
+
this.purgeCache(effectiveLicenseKey);
|
|
11486
|
+
throw new LicenseValidationError(`License validation request failed: ${(err == null ? void 0 : err.message) || "Network error"}`);
|
|
11487
|
+
}
|
|
11488
|
+
}
|
|
11489
|
+
if (res && !res.ok) {
|
|
11490
|
+
try {
|
|
11491
|
+
const payload = LicenseVerifier.verify(effectiveLicenseKey, projectId || "my-rag-app");
|
|
11492
|
+
const fallbackResp = {
|
|
11493
|
+
valid: true,
|
|
11494
|
+
licenseStatus: "ACTIVE",
|
|
11495
|
+
minimumSupportedVersion: "2.1.0",
|
|
11496
|
+
latestVersion: SDK_VERSION,
|
|
11497
|
+
forceUpgrade: false,
|
|
11498
|
+
expiresAt: payload.expiresAt ? new Date(payload.expiresAt * 1e3).toISOString() : null,
|
|
11499
|
+
message: "Local license verification active."
|
|
11500
|
+
};
|
|
11501
|
+
this.cache.set(effectiveLicenseKey, { response: fallbackResp, timestamp: Date.now() });
|
|
11502
|
+
return fallbackResp;
|
|
11503
|
+
} catch (e) {
|
|
11504
|
+
}
|
|
11418
11505
|
}
|
|
11419
11506
|
const data = await res.json().catch(() => ({
|
|
11420
11507
|
valid: false,
|
|
@@ -11426,7 +11513,7 @@ var _LicenseValidator = class _LicenseValidator {
|
|
|
11426
11513
|
message: "Failed to parse license validation response."
|
|
11427
11514
|
}));
|
|
11428
11515
|
if (!res.ok || !data.valid || data.licenseStatus !== "ACTIVE" || data.forceUpgrade) {
|
|
11429
|
-
this.purgeCache(
|
|
11516
|
+
this.purgeCache(effectiveLicenseKey);
|
|
11430
11517
|
if (data.forceUpgrade || res.status === 426) {
|
|
11431
11518
|
throw new SDKVersionUnsupportedError(
|
|
11432
11519
|
data.message || `This SDK version (${sdkVersion}) is no longer supported. Upgrade to version ${data.latestVersion || "2.2.6"} or later.`,
|
|
@@ -11436,7 +11523,7 @@ var _LicenseValidator = class _LicenseValidator {
|
|
|
11436
11523
|
const errMsg = data.message || `License validation failed with status: ${data.licenseStatus}. Access denied.`;
|
|
11437
11524
|
throw new LicenseValidationError(errMsg, data);
|
|
11438
11525
|
}
|
|
11439
|
-
this.cache.set(
|
|
11526
|
+
this.cache.set(effectiveLicenseKey, {
|
|
11440
11527
|
response: data,
|
|
11441
11528
|
timestamp: Date.now()
|
|
11442
11529
|
});
|
package/dist/server.mjs
CHANGED
|
@@ -4723,7 +4723,7 @@ var ConfigValidator = class {
|
|
|
4723
4723
|
// package.json
|
|
4724
4724
|
var package_default = {
|
|
4725
4725
|
name: "@retrivora-ai/rag-engine",
|
|
4726
|
-
version: "2.2.
|
|
4726
|
+
version: "2.2.9",
|
|
4727
4727
|
description: "Retrivora AI is a plug-and-play AI engine for RAG chat experiences \u2014 generic vector DB + LLM provider, embeddable or standalone.",
|
|
4728
4728
|
author: "Abhinav Alkuchi",
|
|
4729
4729
|
license: "UNLICENSED",
|
|
@@ -10912,6 +10912,46 @@ function createHealthHandler(configOrPlugin, options) {
|
|
|
10912
10912
|
}
|
|
10913
10913
|
};
|
|
10914
10914
|
}
|
|
10915
|
+
function createLicenseHandler(configOrPlugin, options) {
|
|
10916
|
+
const plugin = getOrCreatePlugin(configOrPlugin);
|
|
10917
|
+
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
10918
|
+
return async function POST(req) {
|
|
10919
|
+
var _a2;
|
|
10920
|
+
if (req) {
|
|
10921
|
+
const authResult = await checkAuth(req, onAuthorize);
|
|
10922
|
+
if (authResult) return authResult;
|
|
10923
|
+
}
|
|
10924
|
+
try {
|
|
10925
|
+
const body = await req.json().catch(() => ({}));
|
|
10926
|
+
const config = plugin.getConfig();
|
|
10927
|
+
const licenseKey = 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.RETRIVORA_LICENSE_KEY || process.env.NEXT_PUBLIC_RETRIVORA_LICENSE_KEY || "";
|
|
10928
|
+
const projectId = (body == null ? void 0 : body.projectId) || config.projectId || "my-rag-app";
|
|
10929
|
+
const payload = LicenseVerifier.verify(licenseKey, projectId);
|
|
10930
|
+
return NextResponse.json({
|
|
10931
|
+
valid: true,
|
|
10932
|
+
licenseStatus: "ACTIVE",
|
|
10933
|
+
minimumSupportedVersion: "2.1.0",
|
|
10934
|
+
latestVersion: SDK_VERSION,
|
|
10935
|
+
forceUpgrade: false,
|
|
10936
|
+
expiresAt: payload.expiresAt ? new Date(payload.expiresAt * 1e3).toISOString() : null,
|
|
10937
|
+
message: "License key is active and valid."
|
|
10938
|
+
});
|
|
10939
|
+
} catch (err) {
|
|
10940
|
+
return NextResponse.json(
|
|
10941
|
+
{
|
|
10942
|
+
valid: false,
|
|
10943
|
+
licenseStatus: "REVOKED",
|
|
10944
|
+
minimumSupportedVersion: "2.1.0",
|
|
10945
|
+
latestVersion: SDK_VERSION,
|
|
10946
|
+
forceUpgrade: false,
|
|
10947
|
+
expiresAt: null,
|
|
10948
|
+
message: (err == null ? void 0 : err.message) || "License validation failed."
|
|
10949
|
+
},
|
|
10950
|
+
{ status: 400 }
|
|
10951
|
+
);
|
|
10952
|
+
}
|
|
10953
|
+
};
|
|
10954
|
+
}
|
|
10915
10955
|
function createUploadHandler(configOrPlugin, options) {
|
|
10916
10956
|
const plugin = getOrCreatePlugin(configOrPlugin);
|
|
10917
10957
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
@@ -11163,6 +11203,7 @@ function createRagHandler(configOrPlugin, options) {
|
|
|
11163
11203
|
const historyHandler = createHistoryHandler(plugin, { onAuthorize });
|
|
11164
11204
|
const feedbackHandler = createFeedbackHandler(plugin, { onAuthorize });
|
|
11165
11205
|
const sessionsHandler = createSessionsHandler(plugin, { onAuthorize });
|
|
11206
|
+
const licenseHandler = createLicenseHandler(plugin, { onAuthorize });
|
|
11166
11207
|
async function routePostRequest(req, segment) {
|
|
11167
11208
|
switch (segment) {
|
|
11168
11209
|
case "chat":
|
|
@@ -11180,6 +11221,9 @@ function createRagHandler(configOrPlugin, options) {
|
|
|
11180
11221
|
return historyHandler(req);
|
|
11181
11222
|
case "feedback":
|
|
11182
11223
|
return feedbackHandler(req);
|
|
11224
|
+
case "license/validate":
|
|
11225
|
+
case "v1/license/validate":
|
|
11226
|
+
return licenseHandler(req);
|
|
11183
11227
|
default:
|
|
11184
11228
|
return NextResponse.json({ error: `Not Found: POST segment "${segment}" not supported.` }, { status: 404 });
|
|
11185
11229
|
}
|
|
@@ -11209,6 +11253,7 @@ function createRagHandler(configOrPlugin, options) {
|
|
|
11209
11253
|
try {
|
|
11210
11254
|
const url = new URL(req.url);
|
|
11211
11255
|
const pathname = url.pathname;
|
|
11256
|
+
if (pathname.includes("/license/validate")) return "v1/license/validate";
|
|
11212
11257
|
if (pathname.endsWith("/upload")) return "upload";
|
|
11213
11258
|
if (pathname.endsWith("/chat") || pathname.endsWith("/chat-sync")) return "chat";
|
|
11214
11259
|
if (pathname.endsWith("/health")) return "health";
|
|
@@ -11270,6 +11315,7 @@ var _LicenseValidator = class _LicenseValidator {
|
|
|
11270
11315
|
* Validate license status and SDK version against Retrivora License Service
|
|
11271
11316
|
*/
|
|
11272
11317
|
async validate(request) {
|
|
11318
|
+
var _a2;
|
|
11273
11319
|
const {
|
|
11274
11320
|
licenseKey,
|
|
11275
11321
|
projectId,
|
|
@@ -11279,33 +11325,42 @@ var _LicenseValidator = class _LicenseValidator {
|
|
|
11279
11325
|
retrivoraApiBase,
|
|
11280
11326
|
headers: customHeaders
|
|
11281
11327
|
} = request;
|
|
11282
|
-
|
|
11283
|
-
|
|
11284
|
-
|
|
11328
|
+
const getHeader = (name) => {
|
|
11329
|
+
if (!customHeaders) return void 0;
|
|
11330
|
+
const target = name.toLowerCase();
|
|
11331
|
+
for (const [k, v] of Object.entries(customHeaders)) {
|
|
11332
|
+
if (k.toLowerCase() === target) return v;
|
|
11333
|
+
}
|
|
11334
|
+
return void 0;
|
|
11335
|
+
};
|
|
11336
|
+
const effectiveLicenseKey = 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 : "") || "";
|
|
11337
|
+
if (!effectiveLicenseKey) {
|
|
11338
|
+
this.purgeCache(effectiveLicenseKey);
|
|
11339
|
+
throw new LicenseValidationError("Missing RETRIVORA_LICENSE_KEY in request. Set NEXT_PUBLIC_RETRIVORA_LICENSE_KEY in your environment or pass licenseKey as a prop.");
|
|
11285
11340
|
}
|
|
11286
|
-
const cached = this.cache.get(
|
|
11341
|
+
const cached = this.cache.get(effectiveLicenseKey);
|
|
11287
11342
|
if (cached) {
|
|
11288
11343
|
const isFresh = Date.now() - cached.timestamp < _LicenseValidator.SUCCESS_CACHE_TTL_MS;
|
|
11289
11344
|
if (isFresh && cached.response.valid && cached.response.licenseStatus === "ACTIVE" && !cached.response.forceUpgrade) {
|
|
11290
11345
|
return cached.response;
|
|
11291
11346
|
} else {
|
|
11292
|
-
this.cache.delete(
|
|
11347
|
+
this.cache.delete(effectiveLicenseKey);
|
|
11293
11348
|
}
|
|
11294
11349
|
}
|
|
11295
11350
|
const base = retrivoraApiBase || (typeof process !== "undefined" ? process.env.NEXT_PUBLIC_RETRIVORA_API_BASE || process.env.RETRIVORA_API_BASE : "") || "/api/retrivora";
|
|
11296
11351
|
const validateUrl = `${base.replace(/\/$/, "")}/v1/license/validate`;
|
|
11297
|
-
let res;
|
|
11352
|
+
let res = null;
|
|
11298
11353
|
try {
|
|
11299
11354
|
res = await fetch(validateUrl, {
|
|
11300
11355
|
method: "POST",
|
|
11301
11356
|
cache: "no-store",
|
|
11302
11357
|
headers: __spreadValues({
|
|
11303
11358
|
"Content-Type": "application/json",
|
|
11304
|
-
"x-license-key":
|
|
11359
|
+
"x-license-key": effectiveLicenseKey,
|
|
11305
11360
|
"x-sdk-version": sdkVersion
|
|
11306
11361
|
}, customHeaders || {}),
|
|
11307
11362
|
body: JSON.stringify({
|
|
11308
|
-
licenseKey,
|
|
11363
|
+
licenseKey: effectiveLicenseKey,
|
|
11309
11364
|
projectId,
|
|
11310
11365
|
sdkVersion,
|
|
11311
11366
|
sdk,
|
|
@@ -11313,8 +11368,40 @@ var _LicenseValidator = class _LicenseValidator {
|
|
|
11313
11368
|
})
|
|
11314
11369
|
});
|
|
11315
11370
|
} catch (err) {
|
|
11316
|
-
|
|
11317
|
-
|
|
11371
|
+
try {
|
|
11372
|
+
const payload = LicenseVerifier.verify(effectiveLicenseKey, projectId || "my-rag-app");
|
|
11373
|
+
const fallbackResp = {
|
|
11374
|
+
valid: true,
|
|
11375
|
+
licenseStatus: "ACTIVE",
|
|
11376
|
+
minimumSupportedVersion: "2.1.0",
|
|
11377
|
+
latestVersion: SDK_VERSION,
|
|
11378
|
+
forceUpgrade: false,
|
|
11379
|
+
expiresAt: payload.expiresAt ? new Date(payload.expiresAt * 1e3).toISOString() : null,
|
|
11380
|
+
message: "Local license verification active."
|
|
11381
|
+
};
|
|
11382
|
+
this.cache.set(effectiveLicenseKey, { response: fallbackResp, timestamp: Date.now() });
|
|
11383
|
+
return fallbackResp;
|
|
11384
|
+
} catch (e) {
|
|
11385
|
+
this.purgeCache(effectiveLicenseKey);
|
|
11386
|
+
throw new LicenseValidationError(`License validation request failed: ${(err == null ? void 0 : err.message) || "Network error"}`);
|
|
11387
|
+
}
|
|
11388
|
+
}
|
|
11389
|
+
if (res && !res.ok) {
|
|
11390
|
+
try {
|
|
11391
|
+
const payload = LicenseVerifier.verify(effectiveLicenseKey, projectId || "my-rag-app");
|
|
11392
|
+
const fallbackResp = {
|
|
11393
|
+
valid: true,
|
|
11394
|
+
licenseStatus: "ACTIVE",
|
|
11395
|
+
minimumSupportedVersion: "2.1.0",
|
|
11396
|
+
latestVersion: SDK_VERSION,
|
|
11397
|
+
forceUpgrade: false,
|
|
11398
|
+
expiresAt: payload.expiresAt ? new Date(payload.expiresAt * 1e3).toISOString() : null,
|
|
11399
|
+
message: "Local license verification active."
|
|
11400
|
+
};
|
|
11401
|
+
this.cache.set(effectiveLicenseKey, { response: fallbackResp, timestamp: Date.now() });
|
|
11402
|
+
return fallbackResp;
|
|
11403
|
+
} catch (e) {
|
|
11404
|
+
}
|
|
11318
11405
|
}
|
|
11319
11406
|
const data = await res.json().catch(() => ({
|
|
11320
11407
|
valid: false,
|
|
@@ -11326,7 +11413,7 @@ var _LicenseValidator = class _LicenseValidator {
|
|
|
11326
11413
|
message: "Failed to parse license validation response."
|
|
11327
11414
|
}));
|
|
11328
11415
|
if (!res.ok || !data.valid || data.licenseStatus !== "ACTIVE" || data.forceUpgrade) {
|
|
11329
|
-
this.purgeCache(
|
|
11416
|
+
this.purgeCache(effectiveLicenseKey);
|
|
11330
11417
|
if (data.forceUpgrade || res.status === 426) {
|
|
11331
11418
|
throw new SDKVersionUnsupportedError(
|
|
11332
11419
|
data.message || `This SDK version (${sdkVersion}) is no longer supported. Upgrade to version ${data.latestVersion || "2.2.6"} or later.`,
|
|
@@ -11336,7 +11423,7 @@ var _LicenseValidator = class _LicenseValidator {
|
|
|
11336
11423
|
const errMsg = data.message || `License validation failed with status: ${data.licenseStatus}. Access denied.`;
|
|
11337
11424
|
throw new LicenseValidationError(errMsg, data);
|
|
11338
11425
|
}
|
|
11339
|
-
this.cache.set(
|
|
11426
|
+
this.cache.set(effectiveLicenseKey, {
|
|
11340
11427
|
response: data,
|
|
11341
11428
|
timestamp: Date.now()
|
|
11342
11429
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@retrivora-ai/rag-engine",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.9",
|
|
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",
|
|
@@ -46,7 +46,7 @@ const GEMINI_STYLES = `
|
|
|
46
46
|
}
|
|
47
47
|
`;
|
|
48
48
|
|
|
49
|
-
export function ChatWidget({ position = 'bottom-right', onAddToCart, apiUrl, retrivoraApiBase, headers }: ChatWidgetProps) {
|
|
49
|
+
export function ChatWidget({ position = 'bottom-right', onAddToCart, apiUrl, retrivoraApiBase, licenseKey: licenseKeyProp, headers }: ChatWidgetProps) {
|
|
50
50
|
const { ui, projectId } = useConfig();
|
|
51
51
|
const [isOpen, setIsOpen] = useState(false);
|
|
52
52
|
const [hasUnread, setHasUnread] = useState(false);
|
|
@@ -72,9 +72,26 @@ export function ChatWidget({ position = 'bottom-right', onAddToCart, apiUrl, ret
|
|
|
72
72
|
const handleOpen = async () => {
|
|
73
73
|
setIsValidating(true);
|
|
74
74
|
try {
|
|
75
|
-
const
|
|
75
|
+
const getHeader = (name: string) => {
|
|
76
|
+
if (!headers) return undefined;
|
|
77
|
+
const target = name.toLowerCase();
|
|
78
|
+
for (const [k, v] of Object.entries(headers)) {
|
|
79
|
+
if (k.toLowerCase() === target) return v;
|
|
80
|
+
}
|
|
81
|
+
return undefined;
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
const resolvedLicenseKey =
|
|
85
|
+
licenseKeyProp ||
|
|
86
|
+
getHeader('x-license-key') ||
|
|
87
|
+
getHeader('authorization')?.replace(/^Bearer\s+/i, '') ||
|
|
88
|
+
(typeof process !== 'undefined'
|
|
89
|
+
? (process.env.NEXT_PUBLIC_RETRIVORA_LICENSE_KEY || process.env.RETRIVORA_LICENSE_KEY)
|
|
90
|
+
: '') ||
|
|
91
|
+
'';
|
|
92
|
+
|
|
76
93
|
await LicenseValidator.getInstance().validate({
|
|
77
|
-
licenseKey,
|
|
94
|
+
licenseKey: resolvedLicenseKey,
|
|
78
95
|
projectId,
|
|
79
96
|
retrivoraApiBase,
|
|
80
97
|
headers,
|
|
@@ -167,6 +184,7 @@ export function ChatWidget({ position = 'bottom-right', onAddToCart, apiUrl, ret
|
|
|
167
184
|
onAddToCart={onAddToCart}
|
|
168
185
|
apiUrl={apiUrl}
|
|
169
186
|
retrivoraApiBase={retrivoraApiBase}
|
|
187
|
+
licenseKey={licenseKeyProp}
|
|
170
188
|
headers={headers}
|
|
171
189
|
/>
|
|
172
190
|
{/* Pointer (Tail) */}
|
|
@@ -68,6 +68,7 @@ export function ChatWindow({
|
|
|
68
68
|
onAddToCart,
|
|
69
69
|
apiUrl,
|
|
70
70
|
retrivoraApiBase,
|
|
71
|
+
licenseKey: licenseKeyProp,
|
|
71
72
|
headers
|
|
72
73
|
}: ChatWindowProps) {
|
|
73
74
|
const { ui, projectId } = useConfig();
|
|
@@ -81,6 +82,7 @@ export function ChatWindow({
|
|
|
81
82
|
namespace: projectId,
|
|
82
83
|
apiUrl,
|
|
83
84
|
retrivoraApiBase,
|
|
85
|
+
licenseKey: licenseKeyProp,
|
|
84
86
|
headers,
|
|
85
87
|
});
|
|
86
88
|
|
|
@@ -98,9 +100,26 @@ export function ChatWindow({
|
|
|
98
100
|
let isMounted = true;
|
|
99
101
|
async function validateSessionLicense() {
|
|
100
102
|
try {
|
|
101
|
-
const
|
|
103
|
+
const getHeader = (name: string) => {
|
|
104
|
+
if (!headers) return undefined;
|
|
105
|
+
const target = name.toLowerCase();
|
|
106
|
+
for (const [k, v] of Object.entries(headers)) {
|
|
107
|
+
if (k.toLowerCase() === target) return v;
|
|
108
|
+
}
|
|
109
|
+
return undefined;
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
const resolvedLicenseKey =
|
|
113
|
+
licenseKeyProp ||
|
|
114
|
+
getHeader('x-license-key') ||
|
|
115
|
+
getHeader('authorization')?.replace(/^Bearer\s+/i, '') ||
|
|
116
|
+
(typeof process !== 'undefined'
|
|
117
|
+
? (process.env.NEXT_PUBLIC_RETRIVORA_LICENSE_KEY || process.env.RETRIVORA_LICENSE_KEY)
|
|
118
|
+
: '') ||
|
|
119
|
+
'';
|
|
120
|
+
|
|
102
121
|
await LicenseValidator.getInstance().validate({
|
|
103
|
-
licenseKey,
|
|
122
|
+
licenseKey: resolvedLicenseKey,
|
|
104
123
|
projectId,
|
|
105
124
|
retrivoraApiBase,
|
|
106
125
|
headers,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { SDK_VERSION } from '../version';
|
|
2
2
|
import { SDKVersionUnsupportedError, LicenseValidationError } from '../exceptions';
|
|
3
|
+
import { LicenseVerifier } from './LicenseVerifier';
|
|
3
4
|
|
|
4
5
|
export interface LicenseValidationRequest {
|
|
5
6
|
licenseKey: string;
|
|
@@ -65,39 +66,57 @@ export class LicenseValidator {
|
|
|
65
66
|
headers: customHeaders,
|
|
66
67
|
} = request;
|
|
67
68
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
69
|
+
const getHeader = (name: string): string | undefined => {
|
|
70
|
+
if (!customHeaders) return undefined;
|
|
71
|
+
const target = name.toLowerCase();
|
|
72
|
+
for (const [k, v] of Object.entries(customHeaders)) {
|
|
73
|
+
if (k.toLowerCase() === target) return v;
|
|
74
|
+
}
|
|
75
|
+
return undefined;
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
const effectiveLicenseKey =
|
|
79
|
+
licenseKey ||
|
|
80
|
+
getHeader('x-license-key') ||
|
|
81
|
+
getHeader('authorization')?.replace(/^Bearer\s+/i, '') ||
|
|
82
|
+
(typeof process !== 'undefined'
|
|
83
|
+
? (process.env.NEXT_PUBLIC_RETRIVORA_LICENSE_KEY || process.env.RETRIVORA_LICENSE_KEY)
|
|
84
|
+
: '') ||
|
|
85
|
+
'';
|
|
86
|
+
|
|
87
|
+
if (!effectiveLicenseKey) {
|
|
88
|
+
this.purgeCache(effectiveLicenseKey);
|
|
89
|
+
throw new LicenseValidationError('Missing RETRIVORA_LICENSE_KEY in request. Set NEXT_PUBLIC_RETRIVORA_LICENSE_KEY in your environment or pass licenseKey as a prop.');
|
|
71
90
|
}
|
|
72
91
|
|
|
73
92
|
// 1. Check successful 5-minute cache
|
|
74
|
-
const cached = this.cache.get(
|
|
93
|
+
const cached = this.cache.get(effectiveLicenseKey);
|
|
75
94
|
if (cached) {
|
|
76
95
|
const isFresh = Date.now() - cached.timestamp < LicenseValidator.SUCCESS_CACHE_TTL_MS;
|
|
77
96
|
if (isFresh && cached.response.valid && cached.response.licenseStatus === 'ACTIVE' && !cached.response.forceUpgrade) {
|
|
78
97
|
return cached.response;
|
|
79
98
|
} else {
|
|
80
|
-
this.cache.delete(
|
|
99
|
+
this.cache.delete(effectiveLicenseKey);
|
|
81
100
|
}
|
|
82
101
|
}
|
|
83
102
|
|
|
84
|
-
// 2. Fetch live validation from Retrivora backend API
|
|
103
|
+
// 2. Fetch live validation from Retrivora backend API / local catch-all route
|
|
85
104
|
const base = retrivoraApiBase || (typeof process !== 'undefined' ? process.env.NEXT_PUBLIC_RETRIVORA_API_BASE || process.env.RETRIVORA_API_BASE : '') || '/api/retrivora';
|
|
86
105
|
const validateUrl = `${base.replace(/\/$/, '')}/v1/license/validate`;
|
|
87
106
|
|
|
88
|
-
let res: Response;
|
|
107
|
+
let res: Response | null = null;
|
|
89
108
|
try {
|
|
90
109
|
res = await fetch(validateUrl, {
|
|
91
110
|
method: 'POST',
|
|
92
111
|
cache: 'no-store',
|
|
93
112
|
headers: {
|
|
94
113
|
'Content-Type': 'application/json',
|
|
95
|
-
'x-license-key':
|
|
114
|
+
'x-license-key': effectiveLicenseKey,
|
|
96
115
|
'x-sdk-version': sdkVersion,
|
|
97
116
|
...(customHeaders || {}),
|
|
98
117
|
},
|
|
99
118
|
body: JSON.stringify({
|
|
100
|
-
licenseKey,
|
|
119
|
+
licenseKey: effectiveLicenseKey,
|
|
101
120
|
projectId,
|
|
102
121
|
sdkVersion,
|
|
103
122
|
sdk,
|
|
@@ -105,12 +124,45 @@ export class LicenseValidator {
|
|
|
105
124
|
}),
|
|
106
125
|
});
|
|
107
126
|
} catch (err: any) {
|
|
108
|
-
// Fallback: If network error occurs,
|
|
109
|
-
|
|
110
|
-
|
|
127
|
+
// Fallback: If network error occurs, verify locally via RSA LicenseVerifier
|
|
128
|
+
try {
|
|
129
|
+
const payload = LicenseVerifier.verify(effectiveLicenseKey, projectId || 'my-rag-app');
|
|
130
|
+
const fallbackResp: LicenseValidationResponse = {
|
|
131
|
+
valid: true,
|
|
132
|
+
licenseStatus: 'ACTIVE',
|
|
133
|
+
minimumSupportedVersion: '2.1.0',
|
|
134
|
+
latestVersion: SDK_VERSION,
|
|
135
|
+
forceUpgrade: false,
|
|
136
|
+
expiresAt: payload.expiresAt ? new Date(payload.expiresAt * 1000).toISOString() : null,
|
|
137
|
+
message: 'Local license verification active.',
|
|
138
|
+
};
|
|
139
|
+
this.cache.set(effectiveLicenseKey, { response: fallbackResp, timestamp: Date.now() });
|
|
140
|
+
return fallbackResp;
|
|
141
|
+
} catch {
|
|
142
|
+
this.purgeCache(effectiveLicenseKey);
|
|
143
|
+
throw new LicenseValidationError(`License validation request failed: ${err?.message || 'Network error'}`);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
if (res && !res.ok) {
|
|
148
|
+
// Attempt local verification fallback if API route returned 404 or non-OK response
|
|
149
|
+
try {
|
|
150
|
+
const payload = LicenseVerifier.verify(effectiveLicenseKey, projectId || 'my-rag-app');
|
|
151
|
+
const fallbackResp: LicenseValidationResponse = {
|
|
152
|
+
valid: true,
|
|
153
|
+
licenseStatus: 'ACTIVE',
|
|
154
|
+
minimumSupportedVersion: '2.1.0',
|
|
155
|
+
latestVersion: SDK_VERSION,
|
|
156
|
+
forceUpgrade: false,
|
|
157
|
+
expiresAt: payload.expiresAt ? new Date(payload.expiresAt * 1000).toISOString() : null,
|
|
158
|
+
message: 'Local license verification active.',
|
|
159
|
+
};
|
|
160
|
+
this.cache.set(effectiveLicenseKey, { response: fallbackResp, timestamp: Date.now() });
|
|
161
|
+
return fallbackResp;
|
|
162
|
+
} catch { /* proceed to parse error response */ }
|
|
111
163
|
}
|
|
112
164
|
|
|
113
|
-
const data: LicenseValidationResponse = await res
|
|
165
|
+
const data: LicenseValidationResponse = await res!.json().catch(() => ({
|
|
114
166
|
valid: false,
|
|
115
167
|
licenseStatus: 'REVOKED' as const,
|
|
116
168
|
minimumSupportedVersion: '2.1.0',
|
|
@@ -122,7 +174,7 @@ export class LicenseValidator {
|
|
|
122
174
|
|
|
123
175
|
// 3. Negative validation responses immediately purge any existing cache
|
|
124
176
|
if (!res.ok || !data.valid || data.licenseStatus !== 'ACTIVE' || data.forceUpgrade) {
|
|
125
|
-
this.purgeCache(
|
|
177
|
+
this.purgeCache(effectiveLicenseKey);
|
|
126
178
|
|
|
127
179
|
if (data.forceUpgrade || res.status === 426) {
|
|
128
180
|
throw new SDKVersionUnsupportedError(
|
|
@@ -136,7 +188,7 @@ export class LicenseValidator {
|
|
|
136
188
|
}
|
|
137
189
|
|
|
138
190
|
// 4. Cache SUCCESSFUL validation only (TTL = 5 minutes)
|
|
139
|
-
this.cache.set(
|
|
191
|
+
this.cache.set(effectiveLicenseKey, {
|
|
140
192
|
response: data,
|
|
141
193
|
timestamp: Date.now(),
|
|
142
194
|
});
|