@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.
@@ -5,6 +5,8 @@ import { ChatMessage, ChatResponse } from '../types';
5
5
  import { DocumentParser } from '../utils/DocumentParser';
6
6
  import { UITransformer } from '../utils/UITransformer';
7
7
  import { DatabaseStorage, HistoryMessage } from '../core/DatabaseStorage';
8
+ import { LicenseVerifier } from '../core/LicenseVerifier';
9
+ import { SDK_VERSION } from '../version';
8
10
 
9
11
  export interface HandlerOptions {
10
12
  onAuthorize?: (req: NextRequest) => boolean | Promise<boolean> | Response | Promise<Response>;
@@ -147,8 +149,6 @@ function getOrCreatePlugin(configOrPlugin: Partial<RagConfig> | VectorPlugin | u
147
149
 
148
150
  // ─── Telemetry Reporter Helper ───────────────────────────────────────────────
149
151
 
150
- import { SDK_VERSION } from '../version';
151
-
152
152
  /**
153
153
  * Asynchronously sends telemetry payload to telemetryUrl when telemetry is enabled
154
154
  * or when a licenseKey is set. Non-blocking.
@@ -596,6 +596,64 @@ export function createHealthHandler(
596
596
  };
597
597
  }
598
598
 
599
+ /**
600
+ * createLicenseHandler — factory for the license validation endpoint (/v1/license/validate).
601
+ */
602
+ export function createLicenseHandler(
603
+ configOrPlugin?: Partial<RagConfig> | VectorPlugin,
604
+ options?: HandlerOptions
605
+ ) {
606
+ const plugin = getOrCreatePlugin(configOrPlugin);
607
+ const onAuthorize = options?.onAuthorize;
608
+
609
+ return async function POST(req: NextRequest) {
610
+ if (req) {
611
+ const authResult = await checkAuth(req, onAuthorize);
612
+ if (authResult) return authResult as any;
613
+ }
614
+
615
+ try {
616
+ const body = await req.json().catch(() => ({}));
617
+ const config = plugin.getConfig();
618
+ const licenseKey =
619
+ req.headers.get('x-license-key') ||
620
+ body?.licenseKey ||
621
+ req.headers.get('authorization')?.replace(/^Bearer\s+/i, '') ||
622
+ config.licenseKey ||
623
+ process.env.RETRIVORA_LICENSE_KEY ||
624
+ process.env.NEXT_PUBLIC_RETRIVORA_LICENSE_KEY ||
625
+ '';
626
+
627
+ const projectId = body?.projectId || config.projectId || 'my-rag-app';
628
+
629
+ const payload = LicenseVerifier.verify(licenseKey, projectId);
630
+
631
+ return NextResponse.json({
632
+ valid: true,
633
+ licenseStatus: 'ACTIVE',
634
+ minimumSupportedVersion: '2.1.0',
635
+ latestVersion: SDK_VERSION,
636
+ forceUpgrade: false,
637
+ expiresAt: payload.expiresAt ? new Date(payload.expiresAt * 1000).toISOString() : null,
638
+ message: 'License key is active and valid.',
639
+ });
640
+ } catch (err: any) {
641
+ return NextResponse.json(
642
+ {
643
+ valid: false,
644
+ licenseStatus: 'REVOKED',
645
+ minimumSupportedVersion: '2.1.0',
646
+ latestVersion: SDK_VERSION,
647
+ forceUpgrade: false,
648
+ expiresAt: null,
649
+ message: err?.message || 'License validation failed.',
650
+ },
651
+ { status: 400 }
652
+ );
653
+ }
654
+ };
655
+ }
656
+
599
657
  /**
600
658
  * createUploadHandler — factory for the file upload ingestion endpoint.
601
659
  */
@@ -932,6 +990,7 @@ export function createRagHandler(
932
990
  const historyHandler = createHistoryHandler(plugin, { onAuthorize });
933
991
  const feedbackHandler = createFeedbackHandler(plugin, { onAuthorize });
934
992
  const sessionsHandler = createSessionsHandler(plugin, { onAuthorize });
993
+ const licenseHandler = createLicenseHandler(plugin, { onAuthorize });
935
994
 
936
995
  async function routePostRequest(req: any, segment: string) {
937
996
  switch (segment) {
@@ -950,6 +1009,9 @@ export function createRagHandler(
950
1009
  return historyHandler(req);
951
1010
  case 'feedback':
952
1011
  return feedbackHandler(req);
1012
+ case 'license/validate':
1013
+ case 'v1/license/validate':
1014
+ return licenseHandler(req);
953
1015
  default:
954
1016
  return NextResponse.json({ error: `Not Found: POST segment "${segment}" not supported.` }, { status: 404 });
955
1017
  }
@@ -983,6 +1045,7 @@ export function createRagHandler(
983
1045
  try {
984
1046
  const url = new URL(req.url);
985
1047
  const pathname = url.pathname;
1048
+ if (pathname.includes('/license/validate')) return 'v1/license/validate';
986
1049
  if (pathname.endsWith('/upload')) return 'upload';
987
1050
  if (pathname.endsWith('/chat') || pathname.endsWith('/chat-sync')) return 'chat';
988
1051
  if (pathname.endsWith('/health')) return 'health';
@@ -129,8 +129,27 @@ export function useRagChat(
129
129
  userMessageId: userMsgId,
130
130
  });
131
131
 
132
- const fetchHeaders = {
132
+ const getHeader = (headersObj: Record<string, string> | undefined, name: string) => {
133
+ if (!headersObj) return undefined;
134
+ const target = name.toLowerCase();
135
+ for (const [k, v] of Object.entries(headersObj)) {
136
+ if (k.toLowerCase() === target) return v;
137
+ }
138
+ return undefined;
139
+ };
140
+
141
+ const resolvedLicenseKey =
142
+ options.licenseKey ||
143
+ getHeader(options.headers, 'x-license-key') ||
144
+ getHeader(options.headers, 'authorization')?.replace(/^Bearer\s+/i, '') ||
145
+ (typeof process !== 'undefined'
146
+ ? (process.env.NEXT_PUBLIC_RETRIVORA_LICENSE_KEY || process.env.RETRIVORA_LICENSE_KEY)
147
+ : '') ||
148
+ '';
149
+
150
+ const fetchHeaders: Record<string, string> = {
133
151
  'Content-Type': 'application/json',
152
+ ...(resolvedLicenseKey ? { 'x-license-key': resolvedLicenseKey } : {}),
134
153
  ...(options.headers || {})
135
154
  };
136
155
 
package/src/types/chat.ts CHANGED
@@ -57,6 +57,8 @@ export interface UseRagChatOptions {
57
57
  onError?: (error: string) => void;
58
58
  /** Optional custom headers to send with the chat request */
59
59
  headers?: Record<string, string>;
60
+ /** Optional Retrivora license key override */
61
+ licenseKey?: string;
60
62
  /** Session ID for history and feedback tracking (default: 'default') */
61
63
  sessionId?: string;
62
64
  }
@@ -57,11 +57,12 @@ export interface ChatWindowProps {
57
57
  onAddToCart?: (product: Product) => void;
58
58
  /** Optional custom API URL to send chat messages to */
59
59
  apiUrl?: string;
60
- /**
61
- * Base URL for Retrivora SDK history/feedback/sessions endpoints.
60
+ /** Base URL for Retrivora SDK history/feedback/sessions endpoints.
62
61
  * Defaults to '/api/retrivora'. Set this to match your catch-all route location.
63
62
  */
64
63
  retrivoraApiBase?: string;
64
+ /** Optional Retrivora license key override */
65
+ licenseKey?: string;
65
66
  /** Optional custom headers to send with the chat request */
66
67
  headers?: Record<string, string>;
67
68
  }
@@ -78,6 +79,8 @@ export interface ChatWidgetProps {
78
79
  * Defaults to '/api/retrivora'.
79
80
  */
80
81
  retrivoraApiBase?: string;
82
+ /** Optional Retrivora license key override */
83
+ licenseKey?: string;
81
84
  /** Optional custom headers to send with the chat request */
82
85
  headers?: Record<string, string>;
83
86
  }