react-native-my-survey-sdk 2.2.25 → 2.2.26

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-my-survey-sdk",
3
- "version": "2.2.25",
3
+ "version": "2.2.26",
4
4
  "description": "Xebo survey collection SDK for React Native",
5
5
  "main": "src/index.ts",
6
6
  "types": "src/index.ts",
@@ -39,6 +39,57 @@ export function buildFeedbackBaseURL(resolvedZone: string, environment: XeboEnvi
39
39
  : `https://${resolvedZone}-feedback-api.xebo.ai`;
40
40
  }
41
41
 
42
+ export function buildVerifyURL(environment: XeboEnvironment): string {
43
+ return environment === 'uat'
44
+ ? 'https://uat-api.xebo.ai/api/v1/api-key/verify'
45
+ : 'https://api.xebo.ai/api/v1/api-key/verify';
46
+ }
47
+
48
+ // ─── Step 0: API key verification → bearer token ─────────────────────────────
49
+
50
+ export async function verifyApiKey(
51
+ verifyURL: string,
52
+ zone: string,
53
+ apiKey: string,
54
+ ): Promise<string> {
55
+ console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
56
+ console.log('[Xebo Step 0] Verifying API key');
57
+ console.log('URL:', verifyURL);
58
+
59
+ const res = await fetch(verifyURL, {
60
+ method: 'POST',
61
+ headers: { 'Content-Type': 'application/json' },
62
+ body: JSON.stringify({ zone, apiKey }),
63
+ });
64
+
65
+ const json = await res.json();
66
+ console.log('[Xebo] Verify response status:', res.status);
67
+ console.log('[Xebo] Verify response:', JSON.stringify(json));
68
+
69
+ if (!res.ok) {
70
+ throw new Error(
71
+ `[Xebo] verifyApiKey failed — HTTP ${res.status}: ${JSON.stringify(json)}`
72
+ );
73
+ }
74
+
75
+ const token: string | undefined =
76
+ json?.token ??
77
+ json?.data?.token ??
78
+ json?.access_token ??
79
+ json?.bearerToken ??
80
+ json?.data?.access_token;
81
+
82
+ if (!token) {
83
+ throw new Error(
84
+ `[Xebo] verifyApiKey — bearer token not found in response: ${JSON.stringify(json)}`
85
+ );
86
+ }
87
+
88
+ console.log('[Xebo] Bearer token obtained successfully');
89
+ console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
90
+ return token;
91
+ }
92
+
42
93
  // ─── HTML stripping ───────────────────────────────────────────────────────────
43
94
 
44
95
  export function stripHTML(raw: string | undefined): string {
@@ -261,7 +312,7 @@ export interface CollectorInfo {
261
312
  export async function fetchCollector(
262
313
  baseURL: string,
263
314
  collectorId: string,
264
- apiKey: string
315
+ bearerToken: string,
265
316
  ): Promise<CollectorInfo> {
266
317
  const url = `${baseURL}/v3/collectors/collect/${collectorId}`;
267
318
  console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
@@ -269,7 +320,7 @@ export async function fetchCollector(
269
320
  console.log('URL:', url);
270
321
  console.log('Collector ID:', collectorId);
271
322
 
272
- const res = await fetch(url, { headers: { 'x-api-key': apiKey } });
323
+ const res = await fetch(url, { headers: { 'Authorization': `Bearer ${bearerToken}` } });
273
324
  const json: APICollectorResponse = await res.json();
274
325
 
275
326
  // The API may return the collector object directly at the root OR wrapped in a `data` key
@@ -299,14 +350,14 @@ export async function fetchCollector(
299
350
  export async function fetchSurvey(
300
351
  baseURL: string,
301
352
  surveyId: string,
302
- apiKey: string
353
+ bearerToken: string,
303
354
  ): Promise<XeboSurvey> {
304
355
  const url = `${baseURL}/v3/survey-management/surveys/${surveyId}`;
305
356
  console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
306
357
  console.log('[Xebo Step 2] Fetching survey');
307
358
  console.log('URL:', url);
308
359
 
309
- const res = await fetch(url, { headers: { 'x-api-key': apiKey } });
360
+ const res = await fetch(url, { headers: { 'Authorization': `Bearer ${bearerToken}` } });
310
361
  const json: APISurveyResponse = await res.json();
311
362
 
312
363
  console.log('[Xebo] Survey HTTP status:', res.status);
@@ -346,7 +397,7 @@ export async function submitResponse(
346
397
  feedbackBaseURL: string,
347
398
  surveyId: string,
348
399
  collectorUUID: string,
349
- apiKey: string,
400
+ bearerToken: string,
350
401
  answers: XeboAnswer[],
351
402
  meta?: SubmitMeta,
352
403
  ): Promise<SubmitResult> {
@@ -411,7 +462,7 @@ export async function submitResponse(
411
462
  const res = await fetch(url, {
412
463
  method: 'POST',
413
464
  headers: {
414
- 'x-api-key': apiKey,
465
+ 'Authorization': `Bearer ${bearerToken}`,
415
466
  'Content-Type': 'application/json',
416
467
  'User-Agent': userAgent,
417
468
  },
@@ -47,6 +47,8 @@ import {
47
47
  resolveZoneAndEnv,
48
48
  buildBaseURL,
49
49
  buildFeedbackBaseURL,
50
+ buildVerifyURL,
51
+ verifyApiKey,
50
52
  fetchCollector,
51
53
  fetchSurvey,
52
54
  submitResponse,
@@ -73,6 +75,8 @@ class XeboSurveyManagerClass extends SimpleEventEmitter {
73
75
  private environment: XeboEnvironment = 'production';
74
76
  private baseURL = '';
75
77
  private feedbackBaseURL = '';
78
+ private verifyURL = '';
79
+ private bearerToken = '';
76
80
 
77
81
  // User / eData
78
82
  private userData: XeboUserData | null = null;
@@ -108,6 +112,7 @@ class XeboSurveyManagerClass extends SimpleEventEmitter {
108
112
  this.environment = environment;
109
113
  this.baseURL = buildBaseURL(this.resolvedZone, this.environment);
110
114
  this.feedbackBaseURL = buildFeedbackBaseURL(this.resolvedZone, this.environment);
115
+ this.verifyURL = buildVerifyURL(this.environment);
111
116
 
112
117
  // Capture device info once at configure time
113
118
  this.deviceModel = `${DeviceInfo.getModel()} (${DeviceInfo.getSystemName()})`;
@@ -151,15 +156,22 @@ class XeboSurveyManagerClass extends SimpleEventEmitter {
151
156
  });
152
157
  }
153
158
 
159
+ // ─── Step 0: Verify API key → bearer token ────────────────────────────────
160
+
161
+ private async _verifyAndGetToken(): Promise<void> {
162
+ this.bearerToken = await verifyApiKey(this.verifyURL, this.resolvedZone, this.apiKey);
163
+ }
164
+
154
165
  // ─── Background pre-fetch ──────────────────────────────────────────────────
155
166
 
156
167
  private async _prefetchSurvey(): Promise<void> {
157
168
  try {
158
169
  console.log('[Xebo] Pre-fetching survey in background...');
159
- const collector = await fetchCollector(this.baseURL, this.collectorId, this.apiKey);
170
+ await this._verifyAndGetToken();
171
+ const collector = await fetchCollector(this.baseURL, this.collectorId, this.bearerToken);
160
172
  this.resolvedCollectorUUID = collector.uuid;
161
173
  this.resolvedCollectorMongoId = collector.mongoId;
162
- const survey = await fetchSurvey(this.baseURL, collector.surveyId, this.apiKey);
174
+ const survey = await fetchSurvey(this.baseURL, collector.surveyId, this.bearerToken);
163
175
  this.survey = survey;
164
176
  this.emit(XEBO_EVENTS.SURVEY_LOADED, survey);
165
177
  console.log('[Xebo] Pre-fetch done —', survey.questions.length, 'questions ready');
@@ -187,14 +199,17 @@ class XeboSurveyManagerClass extends SimpleEventEmitter {
187
199
  return;
188
200
  }
189
201
 
190
- // Not cached yet — fetch now
202
+ // Not cached yet — verify + fetch now
203
+ console.log('[Xebo] Step 0: verifyApiKey');
204
+ await this._verifyAndGetToken();
205
+
191
206
  console.log('[Xebo] Step 1: fetchCollector');
192
- const collector = await fetchCollector(this.baseURL, this.collectorId, this.apiKey);
207
+ const collector = await fetchCollector(this.baseURL, this.collectorId, this.bearerToken);
193
208
  this.resolvedCollectorUUID = collector.uuid;
194
209
  this.resolvedCollectorMongoId = collector.mongoId;
195
210
 
196
211
  console.log('[Xebo] Step 2: fetchSurvey');
197
- const survey = await fetchSurvey(this.baseURL, collector.surveyId, this.apiKey);
212
+ const survey = await fetchSurvey(this.baseURL, collector.surveyId, this.bearerToken);
198
213
  this.survey = survey;
199
214
  this.currentAnswers = [];
200
215
  this.currentQuestionIndex = 0;
@@ -299,7 +314,7 @@ class XeboSurveyManagerClass extends SimpleEventEmitter {
299
314
  this.feedbackBaseURL,
300
315
  this.survey.id,
301
316
  this.resolvedCollectorUUID,
302
- this.apiKey,
317
+ this.bearerToken,
303
318
  this.currentAnswers,
304
319
  {
305
320
  userData: this.userData ?? undefined,
@@ -370,7 +385,7 @@ class XeboSurveyManagerClass extends SimpleEventEmitter {
370
385
  this.feedbackBaseURL,
371
386
  queued.surveyId,
372
387
  queued.collectorUUID,
373
- this.apiKey,
388
+ this.bearerToken,
374
389
  queued.answers,
375
390
  {
376
391
  userData: queued.userData,