@retrivora-ai/rag-engine 2.2.7 → 2.2.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -2760,7 +2760,7 @@ function useRagChat(projectId, options = {}) {
2760
2760
  }, [messages]);
2761
2761
  const sendMessage = (0, import_react11.useCallback)(
2762
2762
  async (text, opts) => {
2763
- var _a, _b, _c, _d, _e;
2763
+ var _a, _b, _c, _d, _e, _f;
2764
2764
  const trimmed = text.trim();
2765
2765
  if (!trimmed || isLoading) return;
2766
2766
  lastInputRef.current = trimmed;
@@ -2792,9 +2792,18 @@ function useRagChat(projectId, options = {}) {
2792
2792
  messageId: assistantMessageId,
2793
2793
  userMessageId: userMsgId
2794
2794
  });
2795
- const fetchHeaders = __spreadValues({
2795
+ const getHeader = (headersObj, name) => {
2796
+ if (!headersObj) return void 0;
2797
+ const target = name.toLowerCase();
2798
+ for (const [k, v] of Object.entries(headersObj)) {
2799
+ if (k.toLowerCase() === target) return v;
2800
+ }
2801
+ return void 0;
2802
+ };
2803
+ const resolvedLicenseKey = options.licenseKey || getHeader(options.headers, "x-license-key") || ((_b = getHeader(options.headers, "authorization")) == null ? void 0 : _b.replace(/^Bearer\s+/i, "")) || (typeof process !== "undefined" ? process.env.NEXT_PUBLIC_RETRIVORA_LICENSE_KEY || process.env.RETRIVORA_LICENSE_KEY : "") || "";
2804
+ const fetchHeaders = __spreadValues(__spreadValues({
2796
2805
  "Content-Type": "application/json"
2797
- }, options.headers || {});
2806
+ }, resolvedLicenseKey ? { "x-license-key": resolvedLicenseKey } : {}), options.headers || {});
2798
2807
  let response = await fetch(primaryUrl, {
2799
2808
  method: "POST",
2800
2809
  headers: fetchHeaders,
@@ -2812,10 +2821,10 @@ function useRagChat(projectId, options = {}) {
2812
2821
  }
2813
2822
  if (!response.ok) {
2814
2823
  const errorData = await response.json().catch(() => ({}));
2815
- if (response.status === 403 || response.status === 401 || typeof errorData.error === "string" && errorData.error.toLowerCase().includes("license") || ((_b = errorData.error) == null ? void 0 : _b.type) === "license_revoked") {
2824
+ if (response.status === 403 || response.status === 401 || typeof errorData.error === "string" && errorData.error.toLowerCase().includes("license") || ((_c = errorData.error) == null ? void 0 : _c.type) === "license_revoked") {
2816
2825
  throw new Error("Your Retrivora license is no longer valid. Please contact your administrator or obtain a valid license key.");
2817
2826
  }
2818
- throw new Error(((_c = errorData.error) == null ? void 0 : _c.message) || errorData.error || `Server returned ${response.status}`);
2827
+ throw new Error(((_d = errorData.error) == null ? void 0 : _d.message) || errorData.error || `Server returned ${response.status}`);
2819
2828
  }
2820
2829
  if (!response.body) {
2821
2830
  throw new Error("No response body received from server");
@@ -2879,7 +2888,7 @@ function useRagChat(projectId, options = {}) {
2879
2888
  pendingThinkingRef.current = thinkingContent;
2880
2889
  scheduleFlush(assistantMessageId);
2881
2890
  } else if (frame.type === "metadata") {
2882
- sources = (_d = frame.sources) != null ? _d : [];
2891
+ sources = (_e = frame.sources) != null ? _e : [];
2883
2892
  thinkingMs = frame.thinkingMs;
2884
2893
  } else if (frame.type === "ui_transformation") {
2885
2894
  uiTransformation = frame.data;
@@ -2895,7 +2904,7 @@ function useRagChat(projectId, options = {}) {
2895
2904
  if (frame.type === "text" && frame.text) assistantContent += frame.text;
2896
2905
  else if (frame.type === "thinking" && frame.text) thinkingContent += frame.text;
2897
2906
  else if (frame.type === "metadata") {
2898
- sources = (_e = frame.sources) != null ? _e : [];
2907
+ sources = (_f = frame.sources) != null ? _f : [];
2899
2908
  thinkingMs = frame.thinkingMs;
2900
2909
  } else if (frame.type === "observability") trace = frame.data;
2901
2910
  }
@@ -3035,7 +3044,7 @@ function useRagChat(projectId, options = {}) {
3035
3044
  // package.json
3036
3045
  var package_default = {
3037
3046
  name: "@retrivora-ai/rag-engine",
3038
- version: "2.2.7",
3047
+ version: "2.2.8",
3039
3048
  description: "Retrivora AI is a plug-and-play AI engine for RAG chat experiences \u2014 generic vector DB + LLM provider, embeddable or standalone.",
3040
3049
  author: "Abhinav Alkuchi",
3041
3050
  license: "UNLICENSED",
@@ -3225,6 +3234,213 @@ var LicenseValidationError = class extends RetrivoraError {
3225
3234
  }
3226
3235
  };
3227
3236
 
3237
+ // src/core/LicenseVerifier.ts
3238
+ var crypto = __toESM(require("crypto"));
3239
+ var LicenseVerifier = class {
3240
+ /**
3241
+ * Decodes, verifies signature, and checks metadata of a license key.
3242
+ *
3243
+ * @param licenseKey - Base64url signed JWT license key.
3244
+ * @param currentProjectId - Project namespace ID.
3245
+ * @param publicKeyOverride - Optional override for unit/integration tests.
3246
+ */
3247
+ static verify(licenseKey, currentProjectId, provider, publicKeyOverride) {
3248
+ const isProduction = process.env.NODE_ENV === "production";
3249
+ const now = Date.now();
3250
+ if (licenseKey) {
3251
+ const cacheKey = `${licenseKey}:${currentProjectId}:${provider || ""}:${publicKeyOverride || ""}`;
3252
+ const cached = this.cache.get(cacheKey);
3253
+ if (cached && now - cached.cachedAt < this.CACHE_TTL_MS) {
3254
+ const currentTimestampSec = Math.floor(now / 1e3);
3255
+ if (cached.payload.expiresAt && currentTimestampSec > cached.payload.expiresAt) {
3256
+ this.cache.delete(cacheKey);
3257
+ } else {
3258
+ return cached.payload;
3259
+ }
3260
+ }
3261
+ }
3262
+ if (!licenseKey) {
3263
+ if (isProduction) {
3264
+ throw new ConfigurationException(
3265
+ "[Retrivora SDK] License key (licenseKey) is required in production environments."
3266
+ );
3267
+ }
3268
+ console.warn(
3269
+ `\x1B[33m[Retrivora SDK] WARNING: Running without a license key. This namespace (${currentProjectId}) is permitted for local development only.\x1B[0m`
3270
+ );
3271
+ return {
3272
+ projectId: currentProjectId,
3273
+ expiresAt: Math.floor(Date.now() / 1e3) + 86400,
3274
+ // Valid for 24h
3275
+ tier: "hobby"
3276
+ };
3277
+ }
3278
+ try {
3279
+ const rawToken = licenseKey.replace(/^rtv_/i, "").trim();
3280
+ const parts = rawToken.split(".");
3281
+ if (parts.length !== 3) {
3282
+ throw new Error("Malformed token structure (expected 3 parts).");
3283
+ }
3284
+ const [headerB64, payloadB64, signatureB64] = parts;
3285
+ const dataToVerify = `${headerB64}.${payloadB64}`;
3286
+ const publicKey = publicKeyOverride != null ? publicKeyOverride : this.PUBLIC_KEY;
3287
+ const signature = Buffer.from(signatureB64, "base64url");
3288
+ const data = Buffer.from(dataToVerify);
3289
+ const isValid = crypto.verify(
3290
+ "sha256",
3291
+ data,
3292
+ publicKey,
3293
+ signature
3294
+ );
3295
+ if (!isValid) {
3296
+ throw new Error("Signature verification failed.");
3297
+ }
3298
+ const payload = JSON.parse(
3299
+ Buffer.from(payloadB64, "base64url").toString("utf8")
3300
+ );
3301
+ if (!payload.projectId) {
3302
+ throw new Error('License payload is missing "projectId".');
3303
+ }
3304
+ const isProjectMatch = payload.projectId === currentProjectId || payload.projectId === `retrivora-${currentProjectId}` || `retrivora-${payload.projectId}` === currentProjectId;
3305
+ if (!isProjectMatch) {
3306
+ throw new Error(
3307
+ `Project ID mismatch. License is bound to project namespace "${payload.projectId}" but configuration has "${currentProjectId}".`
3308
+ );
3309
+ }
3310
+ if (!payload.expiresAt) {
3311
+ throw new Error('License payload is missing expiration ("expiresAt").');
3312
+ }
3313
+ const currentTimestampSec = Math.floor(Date.now() / 1e3);
3314
+ if (currentTimestampSec > payload.expiresAt) {
3315
+ throw new Error(
3316
+ `License key has expired. Expiration: ${new Date(
3317
+ payload.expiresAt * 1e3
3318
+ ).toDateString()}`
3319
+ );
3320
+ }
3321
+ if (isProduction && provider) {
3322
+ const tier = (payload.tier || "").toLowerCase();
3323
+ const normalizedProvider = provider.toLowerCase();
3324
+ if (tier === "hobby") {
3325
+ const allowedHobby = ["postgresql", "pgvector", "supabase"];
3326
+ if (!allowedHobby.includes(normalizedProvider)) {
3327
+ throw new Error(
3328
+ `The database provider "${provider}" is not allowed on the Hobby tier. Hobby tier is restricted to PostgreSQL and Supabase. Please upgrade to a Developer Pro or Enterprise plan.`
3329
+ );
3330
+ }
3331
+ } else if (tier === "pro" || tier === "developer_pro" || tier === "premium" || tier === "growth" || tier === "free_trial" || tier === "free_tier" || tier === "free") {
3332
+ const allowedPro = [
3333
+ "postgresql",
3334
+ "pgvector",
3335
+ "supabase",
3336
+ "pinecone",
3337
+ "qdrant",
3338
+ "mongodb",
3339
+ "milvus",
3340
+ "chroma",
3341
+ "chromadb"
3342
+ ];
3343
+ if (!allowedPro.includes(normalizedProvider)) {
3344
+ throw new Error(
3345
+ `The database provider "${provider}" is not allowed on the Developer Pro tier. Please upgrade to an Enterprise plan.`
3346
+ );
3347
+ }
3348
+ }
3349
+ }
3350
+ if (licenseKey) {
3351
+ const cacheKey = `${licenseKey}:${currentProjectId}:${provider || ""}:${publicKeyOverride || ""}`;
3352
+ this.cache.set(cacheKey, { payload, cachedAt: now });
3353
+ }
3354
+ return payload;
3355
+ } catch (err) {
3356
+ const message = err instanceof Error ? err.message : String(err);
3357
+ throw new ConfigurationException(
3358
+ `[Retrivora SDK] License key validation failed: ${message}`
3359
+ );
3360
+ }
3361
+ }
3362
+ static async verifyIP(licenseKey) {
3363
+ if (!licenseKey) return;
3364
+ try {
3365
+ const parts = licenseKey.split(".");
3366
+ if (parts.length !== 3) return;
3367
+ const [, payloadB64] = parts;
3368
+ const payload = JSON.parse(
3369
+ Buffer.from(payloadB64, "base64url").toString("utf8")
3370
+ );
3371
+ const tier = (payload.tier || "").toLowerCase();
3372
+ if (tier === "enterprise" || tier === "custom") {
3373
+ return;
3374
+ }
3375
+ if (payload.ipv4 || payload.ipv6) {
3376
+ let currentIpv4 = "";
3377
+ let currentIpv6 = "";
3378
+ try {
3379
+ const res = await fetch("https://api4.ipify.org?format=json", { signal: AbortSignal.timeout(3e3) });
3380
+ const data = await res.json();
3381
+ currentIpv4 = data.ip;
3382
+ } catch (e) {
3383
+ }
3384
+ try {
3385
+ const res = await fetch("https://api6.ipify.org?format=json", { signal: AbortSignal.timeout(3e3) });
3386
+ const data = await res.json();
3387
+ currentIpv6 = data.ip;
3388
+ } catch (e) {
3389
+ }
3390
+ const localIps = [];
3391
+ try {
3392
+ const osModule = require("os");
3393
+ const interfaces = osModule.networkInterfaces();
3394
+ for (const name of Object.keys(interfaces)) {
3395
+ for (const iface of interfaces[name] || []) {
3396
+ if (!iface.internal) {
3397
+ localIps.push(iface.address);
3398
+ }
3399
+ }
3400
+ }
3401
+ } catch (e) {
3402
+ }
3403
+ const isIpv4Match = payload.ipv4 && (currentIpv4 === payload.ipv4 || localIps.includes(payload.ipv4));
3404
+ const isIpv6Match = payload.ipv6 && (currentIpv6 === payload.ipv6 || localIps.includes(payload.ipv6));
3405
+ if (payload.ipv4 && payload.ipv6) {
3406
+ if (!isIpv4Match && !isIpv6Match) {
3407
+ throw new Error(
3408
+ `License key access restricted. This license key was created for a different system (authorized IPv4: ${payload.ipv4}, IPv6: ${payload.ipv6}) and cannot be used on this machine.`
3409
+ );
3410
+ }
3411
+ } else if (payload.ipv4 && !isIpv4Match) {
3412
+ throw new Error(
3413
+ `License key access restricted. This license key was created for a different system (authorized IPv4: ${payload.ipv4}) and cannot be used on this machine.`
3414
+ );
3415
+ } else if (payload.ipv6 && !isIpv6Match) {
3416
+ throw new Error(
3417
+ `License key access restricted. This license key was created for a different system (authorized IPv6: ${payload.ipv6}) and cannot be used on this machine.`
3418
+ );
3419
+ }
3420
+ }
3421
+ } catch (err) {
3422
+ if (err.message.includes("License key access restricted")) {
3423
+ throw new ConfigurationException(`[Retrivora SDK] ${err.message}`);
3424
+ }
3425
+ }
3426
+ }
3427
+ };
3428
+ // A simple in-memory cache to save CPU overhead of cryptographic signature checks.
3429
+ LicenseVerifier.cache = /* @__PURE__ */ new Map();
3430
+ LicenseVerifier.CACHE_TTL_MS = 60 * 1e3;
3431
+ // Cache verified license for 60 seconds
3432
+ // Retrivora's Public Key used to verify the license key signature.
3433
+ // In production, this matches the private key held by Retrivora SaaS.
3434
+ LicenseVerifier.PUBLIC_KEY = `-----BEGIN PUBLIC KEY-----
3435
+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArMieCkCBtTfByRNOserm
3436
+ XM4T0Am29JyNzB4XQPe+WJJ56CN73H1HLXx9n1ByFcxkEJ9po+SURj5DnvUXwEy+
3437
+ xstx33wDPpVmcMQe33j5CRYS0S4gICiNqIRN7XkTlJtrcXqrmh1/hdOAwfRbjO1T
3438
+ NVtORHwUwWfI/lBLyxUPGtKPed+0fQ7NtcW4o00JXxs3EjCB5BV9CbnXoTjQb/4h
3439
+ iwZof4l8rb7oaNzOsVg0RSyxsETX7Ex5sI0CjBz1p2mYp4oVhw/A/h8Ls7H0XzjC
3440
+ +Eb6BLtsytt5JHoSp0jExLlCpDmpys2L+kETcBVx+IqiXtdN1n6KbkksvEDUVzLI
3441
+ MwIDAQAB
3442
+ -----END PUBLIC KEY-----`;
3443
+
3228
3444
  // src/core/LicenseValidator.ts
3229
3445
  var _LicenseValidator = class _LicenseValidator {
3230
3446
  // 5-minute TTL for successful validation only
@@ -3251,6 +3467,7 @@ var _LicenseValidator = class _LicenseValidator {
3251
3467
  * Validate license status and SDK version against Retrivora License Service
3252
3468
  */
3253
3469
  async validate(request) {
3470
+ var _a;
3254
3471
  const {
3255
3472
  licenseKey,
3256
3473
  projectId,
@@ -3260,29 +3477,38 @@ var _LicenseValidator = class _LicenseValidator {
3260
3477
  retrivoraApiBase,
3261
3478
  headers: customHeaders
3262
3479
  } = request;
3263
- if (!licenseKey) {
3264
- this.purgeCache(licenseKey);
3480
+ const getHeader = (name) => {
3481
+ if (!customHeaders) return void 0;
3482
+ const target = name.toLowerCase();
3483
+ for (const [k, v] of Object.entries(customHeaders)) {
3484
+ if (k.toLowerCase() === target) return v;
3485
+ }
3486
+ return void 0;
3487
+ };
3488
+ const effectiveLicenseKey = 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 : "") || "";
3489
+ if (!effectiveLicenseKey) {
3490
+ this.purgeCache(effectiveLicenseKey);
3265
3491
  throw new LicenseValidationError("Missing RETRIVORA_LICENSE_KEY in request.");
3266
3492
  }
3267
- const cached = this.cache.get(licenseKey);
3493
+ const cached = this.cache.get(effectiveLicenseKey);
3268
3494
  if (cached) {
3269
3495
  const isFresh = Date.now() - cached.timestamp < _LicenseValidator.SUCCESS_CACHE_TTL_MS;
3270
3496
  if (isFresh && cached.response.valid && cached.response.licenseStatus === "ACTIVE" && !cached.response.forceUpgrade) {
3271
3497
  return cached.response;
3272
3498
  } else {
3273
- this.cache.delete(licenseKey);
3499
+ this.cache.delete(effectiveLicenseKey);
3274
3500
  }
3275
3501
  }
3276
3502
  const base = retrivoraApiBase || (typeof process !== "undefined" ? process.env.NEXT_PUBLIC_RETRIVORA_API_BASE || process.env.RETRIVORA_API_BASE : "") || "/api/retrivora";
3277
3503
  const validateUrl = `${base.replace(/\/$/, "")}/v1/license/validate`;
3278
- let res;
3504
+ let res = null;
3279
3505
  try {
3280
3506
  res = await fetch(validateUrl, {
3281
3507
  method: "POST",
3282
3508
  cache: "no-store",
3283
3509
  headers: __spreadValues({
3284
3510
  "Content-Type": "application/json",
3285
- "x-license-key": licenseKey,
3511
+ "x-license-key": effectiveLicenseKey,
3286
3512
  "x-sdk-version": sdkVersion
3287
3513
  }, customHeaders || {}),
3288
3514
  body: JSON.stringify({
@@ -3294,8 +3520,40 @@ var _LicenseValidator = class _LicenseValidator {
3294
3520
  })
3295
3521
  });
3296
3522
  } catch (err) {
3297
- this.purgeCache(licenseKey);
3298
- throw new LicenseValidationError(`License validation request failed: ${(err == null ? void 0 : err.message) || "Network error"}`);
3523
+ try {
3524
+ const payload = LicenseVerifier.verify(licenseKey, projectId || "my-rag-app");
3525
+ const fallbackResp = {
3526
+ valid: true,
3527
+ licenseStatus: "ACTIVE",
3528
+ minimumSupportedVersion: "2.1.0",
3529
+ latestVersion: SDK_VERSION,
3530
+ forceUpgrade: false,
3531
+ expiresAt: payload.expiresAt ? new Date(payload.expiresAt * 1e3).toISOString() : null,
3532
+ message: "Local license verification active."
3533
+ };
3534
+ this.cache.set(licenseKey, { response: fallbackResp, timestamp: Date.now() });
3535
+ return fallbackResp;
3536
+ } catch (e) {
3537
+ this.purgeCache(licenseKey);
3538
+ throw new LicenseValidationError(`License validation request failed: ${(err == null ? void 0 : err.message) || "Network error"}`);
3539
+ }
3540
+ }
3541
+ if (res && !res.ok) {
3542
+ try {
3543
+ const payload = LicenseVerifier.verify(licenseKey, projectId || "my-rag-app");
3544
+ const fallbackResp = {
3545
+ valid: true,
3546
+ licenseStatus: "ACTIVE",
3547
+ minimumSupportedVersion: "2.1.0",
3548
+ latestVersion: SDK_VERSION,
3549
+ forceUpgrade: false,
3550
+ expiresAt: payload.expiresAt ? new Date(payload.expiresAt * 1e3).toISOString() : null,
3551
+ message: "Local license verification active."
3552
+ };
3553
+ this.cache.set(licenseKey, { response: fallbackResp, timestamp: Date.now() });
3554
+ return fallbackResp;
3555
+ } catch (e) {
3556
+ }
3299
3557
  }
3300
3558
  const data = await res.json().catch(() => ({
3301
3559
  valid: false,
@@ -3342,6 +3600,7 @@ function ChatWindow({
3342
3600
  onAddToCart,
3343
3601
  apiUrl,
3344
3602
  retrivoraApiBase,
3603
+ licenseKey: licenseKeyProp,
3345
3604
  headers
3346
3605
  }) {
3347
3606
  var _a;
@@ -3356,6 +3615,7 @@ function ChatWindow({
3356
3615
  namespace: projectId,
3357
3616
  apiUrl,
3358
3617
  retrivoraApiBase,
3618
+ licenseKey: licenseKeyProp,
3359
3619
  headers
3360
3620
  });
3361
3621
  const [suggestions, setSuggestions] = (0, import_react12.useState)([]);
@@ -3370,9 +3630,17 @@ function ChatWindow({
3370
3630
  async function validateSessionLicense() {
3371
3631
  var _a2;
3372
3632
  try {
3373
- const licenseKey = (headers == null ? void 0 : headers["x-license-key"]) || ((_a2 = headers == null ? void 0 : headers["authorization"]) == null ? void 0 : _a2.replace(/^Bearer\s+/i, "")) || "";
3633
+ const getHeader = (name) => {
3634
+ if (!headers) return void 0;
3635
+ const target = name.toLowerCase();
3636
+ for (const [k, v] of Object.entries(headers)) {
3637
+ if (k.toLowerCase() === target) return v;
3638
+ }
3639
+ return void 0;
3640
+ };
3641
+ const resolvedLicenseKey = licenseKeyProp || 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 : "") || "";
3374
3642
  await LicenseValidator.getInstance().validate({
3375
- licenseKey,
3643
+ licenseKey: resolvedLicenseKey,
3376
3644
  projectId,
3377
3645
  retrivoraApiBase,
3378
3646
  headers
@@ -3843,7 +4111,7 @@ var GEMINI_STYLES = `
3843
4111
  --circle: shape(evenodd from 13.482% 79.505%, curve by -7.1945% -12.47% with -1.4985% -1.8575% / -6.328% -10.225%, curve by 0.0985% -33.8965% with -4.1645% -10.7945% / -4.1685% -23.0235%, curve by 6.9955% -12.101% with 1.72% -4.3825% / 4.0845% -8.458%, curve by 30.125% -17.119% with 7.339% -9.1825% / 18.4775% -15.5135%, curve by 13.4165% 0.095% with 4.432% -0.6105% / 8.9505% -0.5855%, curve by 29.364% 16.9% with 11.6215% 1.77% / 22.102% 7.9015%, curve by 7.176% 12.4145% with 3.002% 3.7195% / 5.453% 7.968%, curve by -0.0475% 33.8925% with 4.168% 10.756% / 4.2305% 22.942%, curve by -7.1135% 12.2825% with -1.74% 4.4535% / -4.1455% 8.592%, curve by -29.404% 16.9075% with -7.202% 8.954% / -18.019% 15.137%, curve by -14.19% -0.018% with -4.6635% 0.7255% / -9.4575% 0.7205%, curve by -29.226% -16.8875% with -11.573% -1.8065% / -21.9955% -7.9235%, close);
3844
4112
  }
3845
4113
  `;
3846
- function ChatWidget({ position = "bottom-right", onAddToCart, apiUrl, retrivoraApiBase, headers }) {
4114
+ function ChatWidget({ position = "bottom-right", onAddToCart, apiUrl, retrivoraApiBase, licenseKey: licenseKeyProp, headers }) {
3847
4115
  const { ui, projectId } = useConfig();
3848
4116
  const [isOpen, setIsOpen] = (0, import_react13.useState)(false);
3849
4117
  const [hasUnread, setHasUnread] = (0, import_react13.useState)(false);
@@ -3860,9 +4128,17 @@ function ChatWidget({ position = "bottom-right", onAddToCart, apiUrl, retrivoraA
3860
4128
  var _a;
3861
4129
  setIsValidating(true);
3862
4130
  try {
3863
- const licenseKey = (headers == null ? void 0 : headers["x-license-key"]) || ((_a = headers == null ? void 0 : headers["authorization"]) == null ? void 0 : _a.replace(/^Bearer\s+/i, "")) || "";
4131
+ const getHeader = (name) => {
4132
+ if (!headers) return void 0;
4133
+ const target = name.toLowerCase();
4134
+ for (const [k, v] of Object.entries(headers)) {
4135
+ if (k.toLowerCase() === target) return v;
4136
+ }
4137
+ return void 0;
4138
+ };
4139
+ const resolvedLicenseKey = licenseKeyProp || 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 : "") || "";
3864
4140
  await LicenseValidator.getInstance().validate({
3865
- licenseKey,
4141
+ licenseKey: resolvedLicenseKey,
3866
4142
  projectId,
3867
4143
  retrivoraApiBase,
3868
4144
  headers
@@ -3944,6 +4220,7 @@ function ChatWidget({ position = "bottom-right", onAddToCart, apiUrl, retrivoraA
3944
4220
  onAddToCart,
3945
4221
  apiUrl,
3946
4222
  retrivoraApiBase,
4223
+ licenseKey: licenseKeyProp,
3947
4224
  headers
3948
4225
  }
3949
4226
  ),