@explorins/pers-sdk 1.6.15 → 1.6.17

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.
Files changed (94) hide show
  1. package/dist/analytics.cjs +4 -0
  2. package/dist/analytics.cjs.map +1 -1
  3. package/dist/analytics.js +1 -1
  4. package/dist/api-key/api/api-key-api.d.ts +37 -0
  5. package/dist/api-key/api/api-key-api.d.ts.map +1 -0
  6. package/dist/api-key/index.d.ts +7 -0
  7. package/dist/api-key/index.d.ts.map +1 -0
  8. package/dist/business.cjs +4 -0
  9. package/dist/business.cjs.map +1 -1
  10. package/dist/business.js +1 -1
  11. package/dist/campaign.cjs +4 -0
  12. package/dist/campaign.cjs.map +1 -1
  13. package/dist/campaign.js +1 -1
  14. package/dist/chunks/{pers-sdk-tfJJbxVi.cjs → pers-sdk-CCegy2bB.cjs} +294 -50
  15. package/dist/chunks/pers-sdk-CCegy2bB.cjs.map +1 -0
  16. package/dist/chunks/{pers-sdk-QAju9eRs.js → pers-sdk-FWPQvR7K.js} +293 -51
  17. package/dist/chunks/pers-sdk-FWPQvR7K.js.map +1 -0
  18. package/dist/chunks/{tenant-service-Ba7xrWED.cjs → tenant-service-DME24vr1.cjs} +6 -20
  19. package/dist/chunks/tenant-service-DME24vr1.cjs.map +1 -0
  20. package/dist/chunks/{tenant-service-DELk412y.js → tenant-service-DxtHAlaa.js} +6 -20
  21. package/dist/chunks/tenant-service-DxtHAlaa.js.map +1 -0
  22. package/dist/chunks/{web3-chain-service-Du4hH6br.js → web3-chain-service-D0IJ794i.js} +58 -4
  23. package/dist/chunks/web3-chain-service-D0IJ794i.js.map +1 -0
  24. package/dist/chunks/{web3-chain-service-BUKWdi0r.cjs → web3-chain-service-oMqWfd61.cjs} +58 -3
  25. package/dist/chunks/web3-chain-service-oMqWfd61.cjs.map +1 -0
  26. package/dist/core/auth/auth-provider.interface.d.ts +4 -6
  27. package/dist/core/auth/auth-provider.interface.d.ts.map +1 -1
  28. package/dist/core/auth/auth-status.d.ts +17 -0
  29. package/dist/core/auth/auth-status.d.ts.map +1 -0
  30. package/dist/core/auth/default-auth-provider.d.ts +2 -1
  31. package/dist/core/auth/default-auth-provider.d.ts.map +1 -1
  32. package/dist/core/auth/refresh-manager.d.ts.map +1 -1
  33. package/dist/core/auth/services/auth-service.d.ts +6 -1
  34. package/dist/core/auth/services/auth-service.d.ts.map +1 -1
  35. package/dist/core/errors/index.d.ts +13 -2
  36. package/dist/core/errors/index.d.ts.map +1 -1
  37. package/dist/core/pers-api-client.d.ts +1 -0
  38. package/dist/core/pers-api-client.d.ts.map +1 -1
  39. package/dist/core/pers-config.d.ts +0 -4
  40. package/dist/core/pers-config.d.ts.map +1 -1
  41. package/dist/core.cjs +4 -3
  42. package/dist/core.cjs.map +1 -1
  43. package/dist/core.js +3 -3
  44. package/dist/donation.cjs +4 -0
  45. package/dist/donation.cjs.map +1 -1
  46. package/dist/donation.js +1 -1
  47. package/dist/index.cjs +13 -3
  48. package/dist/index.cjs.map +1 -1
  49. package/dist/index.d.ts +2 -0
  50. package/dist/index.d.ts.map +1 -1
  51. package/dist/index.js +4 -4
  52. package/dist/managers/api-key-manager.d.ts +100 -0
  53. package/dist/managers/api-key-manager.d.ts.map +1 -0
  54. package/dist/managers/index.d.ts +1 -0
  55. package/dist/managers/index.d.ts.map +1 -1
  56. package/dist/package.json +2 -2
  57. package/dist/payment.cjs +4 -0
  58. package/dist/payment.cjs.map +1 -1
  59. package/dist/payment.js +1 -1
  60. package/dist/pers-sdk.d.ts +24 -1
  61. package/dist/pers-sdk.d.ts.map +1 -1
  62. package/dist/redemption.cjs +4 -0
  63. package/dist/redemption.cjs.map +1 -1
  64. package/dist/redemption.js +1 -1
  65. package/dist/shared/interfaces/pers-shared-lib.interfaces.d.ts +2 -0
  66. package/dist/shared/interfaces/pers-shared-lib.interfaces.d.ts.map +1 -1
  67. package/dist/tenant/api/tenant-api.d.ts +5 -15
  68. package/dist/tenant/api/tenant-api.d.ts.map +1 -1
  69. package/dist/tenant.cjs +5 -1
  70. package/dist/tenant.cjs.map +1 -1
  71. package/dist/tenant.js +2 -2
  72. package/dist/token.cjs +4 -0
  73. package/dist/token.cjs.map +1 -1
  74. package/dist/token.js +1 -1
  75. package/dist/transaction.cjs +4 -0
  76. package/dist/transaction.cjs.map +1 -1
  77. package/dist/transaction.js +1 -1
  78. package/dist/user-status.cjs +4 -0
  79. package/dist/user-status.cjs.map +1 -1
  80. package/dist/user-status.js +1 -1
  81. package/dist/user.cjs +4 -0
  82. package/dist/user.cjs.map +1 -1
  83. package/dist/user.js +1 -1
  84. package/dist/web3-chain/api/web3-chain-api.d.ts.map +1 -1
  85. package/dist/web3-chain.cjs +5 -1
  86. package/dist/web3-chain.cjs.map +1 -1
  87. package/dist/web3-chain.js +2 -2
  88. package/package.json +2 -2
  89. package/dist/chunks/pers-sdk-QAju9eRs.js.map +0 -1
  90. package/dist/chunks/pers-sdk-tfJJbxVi.cjs.map +0 -1
  91. package/dist/chunks/tenant-service-Ba7xrWED.cjs.map +0 -1
  92. package/dist/chunks/tenant-service-DELk412y.js.map +0 -1
  93. package/dist/chunks/web3-chain-service-BUKWdi0r.cjs.map +0 -1
  94. package/dist/chunks/web3-chain-service-Du4hH6br.js.map +0 -1
@@ -11,4 +11,8 @@ Object.defineProperty(exports, "AccountOwnerType", {
11
11
  enumerable: true,
12
12
  get: function () { return persShared.AccountOwnerType; }
13
13
  });
14
+ Object.defineProperty(exports, "ApiKeyType", {
15
+ enumerable: true,
16
+ get: function () { return persShared.ApiKeyType; }
17
+ });
14
18
  //# sourceMappingURL=analytics.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"analytics.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;"}
1
+ {"version":3,"file":"analytics.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;"}
package/dist/analytics.js CHANGED
@@ -1,3 +1,3 @@
1
1
  export { A as AnalyticsApi, a as AnalyticsService } from './chunks/analytics-service-CxyrOwel.js';
2
- export { AccountOwnerType } from '@explorins/pers-shared';
2
+ export { AccountOwnerType, ApiKeyType } from '@explorins/pers-shared';
3
3
  //# sourceMappingURL=analytics.js.map
@@ -0,0 +1,37 @@
1
+ import { PersApiClient } from '../../core/pers-api-client';
2
+ import { ApiKeyDTO, ApiKeyCreatedDTO, ApiKeyRequestDTO, ApiKeyVerificationDTO, IntegrationApiKeyType } from '../../shared/interfaces/pers-shared-lib.interfaces';
3
+ /**
4
+ * Platform-Agnostic API Key API Client
5
+ *
6
+ * Handles API key management operations for tenant admins.
7
+ * All operations require admin authentication and operate within tenant context.
8
+ */
9
+ export declare class ApiKeyApi {
10
+ private apiClient;
11
+ private readonly basePath;
12
+ constructor(apiClient: PersApiClient);
13
+ /**
14
+ * ADMIN: Get all tenant API keys
15
+ *
16
+ * @param type Optional filter by integration API key type (database-stored tokens that can be revoked)
17
+ * @param includeRevoked Include revoked API keys in results (default: false)
18
+ * @returns Array of API keys for the current tenant
19
+ */
20
+ getTenantApiKeys(type?: IntegrationApiKeyType, includeRevoked?: boolean): Promise<ApiKeyDTO[]>;
21
+ /**
22
+ * ADMIN: Create new API key
23
+ *
24
+ * @param type Type of API key to create
25
+ * @param name Name for the API key
26
+ * @returns Created API key with the actual key (store securely - only returned once)
27
+ */
28
+ createApiKey(req: ApiKeyRequestDTO): Promise<ApiKeyCreatedDTO>;
29
+ /**
30
+ * ADMIN: Revoke API key
31
+ *
32
+ * @param apiKeyId Unique identifier of the API key to revoke
33
+ * @returns API key verification details with revocation status
34
+ */
35
+ revokeApiKey(apiKeyId: string): Promise<ApiKeyVerificationDTO>;
36
+ }
37
+ //# sourceMappingURL=api-key-api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-key-api.d.ts","sourceRoot":"","sources":["../../../src/api-key/api/api-key-api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EACL,SAAS,EACT,gBAAgB,EAChB,gBAAgB,EAChB,qBAAqB,EACrB,qBAAqB,EACtB,MAAM,oDAAoD,CAAC;AAE5D;;;;;GAKG;AACH,qBAAa,SAAS;IAGR,OAAO,CAAC,SAAS;IAF7B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAe;gBAEpB,SAAS,EAAE,aAAa;IAE5C;;;;;;OAMG;IACG,gBAAgB,CAAC,IAAI,CAAC,EAAE,qBAAqB,EAAE,cAAc,GAAE,OAAe,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAW3G;;;;;;OAMG;IACG,YAAY,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAIpE;;;;;OAKG;IACG,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,CAAC;CAGrE"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * API Key Domain Exports
3
+ *
4
+ * Re-exports all API key related functionality for easy importing
5
+ */
6
+ export * from './api/api-key-api';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/api-key/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,cAAc,mBAAmB,CAAC"}
package/dist/business.cjs CHANGED
@@ -11,4 +11,8 @@ Object.defineProperty(exports, "AccountOwnerType", {
11
11
  enumerable: true,
12
12
  get: function () { return persShared.AccountOwnerType; }
13
13
  });
14
+ Object.defineProperty(exports, "ApiKeyType", {
15
+ enumerable: true,
16
+ get: function () { return persShared.ApiKeyType; }
17
+ });
14
18
  //# sourceMappingURL=business.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"business.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;"}
1
+ {"version":3,"file":"business.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;"}
package/dist/business.js CHANGED
@@ -1,3 +1,3 @@
1
1
  export { B as BusinessApi, a as BusinessService } from './chunks/business-service-DrC-TNGa.js';
2
- export { AccountOwnerType } from '@explorins/pers-shared';
2
+ export { AccountOwnerType, ApiKeyType } from '@explorins/pers-shared';
3
3
  //# sourceMappingURL=business.js.map
package/dist/campaign.cjs CHANGED
@@ -11,4 +11,8 @@ Object.defineProperty(exports, "AccountOwnerType", {
11
11
  enumerable: true,
12
12
  get: function () { return persShared.AccountOwnerType; }
13
13
  });
14
+ Object.defineProperty(exports, "ApiKeyType", {
15
+ enumerable: true,
16
+ get: function () { return persShared.ApiKeyType; }
17
+ });
14
18
  //# sourceMappingURL=campaign.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"campaign.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;"}
1
+ {"version":3,"file":"campaign.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;"}
package/dist/campaign.js CHANGED
@@ -1,3 +1,3 @@
1
1
  export { C as CampaignApi, a as CampaignService } from './chunks/campaign-service-Dd7gMjC9.js';
2
- export { AccountOwnerType } from '@explorins/pers-shared';
2
+ export { AccountOwnerType, ApiKeyType } from '@explorins/pers-shared';
3
3
  //# sourceMappingURL=campaign.js.map
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var persShared = require('@explorins/pers-shared');
4
- var web3ChainService = require('./web3-chain-service-BUKWdi0r.cjs');
4
+ var web3ChainService = require('./web3-chain-service-oMqWfd61.cjs');
5
5
  var userService = require('./user-service-D1Rn4U8u.cjs');
6
6
  var userStatus = require('../user-status.cjs');
7
7
  var tokenService = require('./token-service-BWScn8Qa.cjs');
@@ -10,7 +10,7 @@ var campaignService = require('./campaign-service-CWK9I388.cjs');
10
10
  var redemptionService = require('./redemption-service-7qbeQxEM.cjs');
11
11
  var transaction = require('../transaction.cjs');
12
12
  var paymentService = require('./payment-service-B4qx0qiE.cjs');
13
- var tenantService = require('./tenant-service-Ba7xrWED.cjs');
13
+ var tenantService = require('./tenant-service-DME24vr1.cjs');
14
14
  var analyticsService = require('./analytics-service-CitlimKJ.cjs');
15
15
  var donationService = require('./donation-service-D-xFrONi.cjs');
16
16
  var explorer_utils = require('./explorer.utils-Bj4uQw83.cjs');
@@ -102,10 +102,28 @@ class AuthApi {
102
102
  * Refresh access token
103
103
  */
104
104
  async refreshAccessToken(refreshToken) {
105
- return this.apiClient.post(`${this.basePath}/refresh`, { refreshToken }, { bypassAuth: true });
105
+ return this.apiClient.post(`${this.basePath}/refresh`, { refreshToken }, { bypassAuth: true, isRefreshRequest: true });
106
106
  }
107
107
  }
108
108
 
109
+ /**
110
+ * Authentication status enumeration
111
+ * Represents the current state of the authentication system
112
+ */
113
+ exports.AuthStatus = void 0;
114
+ (function (AuthStatus) {
115
+ /** User is authenticated with valid tokens */
116
+ AuthStatus["AUTHENTICATED"] = "authenticated";
117
+ /** Access token has expired, refresh may be possible */
118
+ AuthStatus["TOKEN_EXPIRED"] = "token_expired";
119
+ /** Authentication system has failed, manual re-authentication required */
120
+ AuthStatus["AUTH_FAILED"] = "auth_failed";
121
+ /** Currently attempting to refresh tokens */
122
+ AuthStatus["REFRESHING"] = "refreshing";
123
+ /** No authentication present */
124
+ AuthStatus["UNAUTHENTICATED"] = "unauthenticated";
125
+ })(exports.AuthStatus || (exports.AuthStatus = {}));
126
+
109
127
  /**
110
128
  * Platform-agnostic authentication service
111
129
  * Handles login, token refresh, and storage operations
@@ -115,6 +133,23 @@ class AuthService {
115
133
  this.authApi = authApi;
116
134
  this.authProvider = authProvider;
117
135
  this.activeRefreshPromise = null;
136
+ this.currentAuthStatus = exports.AuthStatus.UNAUTHENTICATED;
137
+ }
138
+ /**
139
+ * Emit auth status change to the app
140
+ */
141
+ async emitAuthStatus(status) {
142
+ if (this.currentAuthStatus === status)
143
+ return; // No change
144
+ this.currentAuthStatus = status;
145
+ if (this.authProvider && typeof this.authProvider.onAuthStatusChange === 'function') {
146
+ try {
147
+ await this.authProvider.onAuthStatusChange(status);
148
+ }
149
+ catch (error) {
150
+ console.warn('[AuthService] Auth status change callback failed:', error);
151
+ }
152
+ }
118
153
  }
119
154
  // ==========================================
120
155
  // AUTHENTICATION OPERATIONS
@@ -153,15 +188,13 @@ class AuthService {
153
188
  * Refresh access token with race condition protection
154
189
  */
155
190
  async refreshAccessToken(refreshToken) {
191
+ if (this.currentAuthStatus === exports.AuthStatus.AUTH_FAILED) {
192
+ throw new Error('Auth failure has occurred, cannot refresh token');
193
+ }
156
194
  if (this.activeRefreshPromise) {
157
- try {
158
- return await this.activeRefreshPromise;
159
- }
160
- catch (error) {
161
- console.warn('[AuthService] Active refresh failed, attempting new refresh:', error);
162
- this.activeRefreshPromise = null;
163
- }
195
+ return await this.activeRefreshPromise;
164
196
  }
197
+ // Create the refresh promise
165
198
  this.activeRefreshPromise = this.performRefresh(refreshToken);
166
199
  try {
167
200
  return await this.activeRefreshPromise;
@@ -197,9 +230,16 @@ class AuthService {
197
230
  * Handle authentication failure with proper cleanup
198
231
  * Centralized method to avoid redundant token cleanup logic
199
232
  */
200
- async handleAuthFailure(reason) {
201
- console.warn(`[AuthService] ${reason}, clearing all tokens`);
233
+ async handleAuthFailure() {
234
+ if (this.currentAuthStatus === exports.AuthStatus.AUTH_FAILED) {
235
+ return;
236
+ }
237
+ // Clear active refresh operations to prevent hanging promises
238
+ this.activeRefreshPromise = null;
239
+ // Clear all stored tokens
202
240
  await this.clearTokens();
241
+ // Emit auth failure status to notify the app
242
+ await this.emitAuthStatus(exports.AuthStatus.AUTH_FAILED);
203
243
  }
204
244
  /**
205
245
  * Check if we have valid authentication tokens
@@ -232,6 +272,8 @@ class AuthService {
232
272
  if (authType && extendedProvider.setAuthType) {
233
273
  await extendedProvider.setAuthType(authType);
234
274
  }
275
+ // Emit authenticated status on successful token storage
276
+ await this.emitAuthStatus(exports.AuthStatus.AUTHENTICATED);
235
277
  }
236
278
  catch (error) {
237
279
  console.warn('[AuthService] Failed to store tokens:', error);
@@ -259,13 +301,13 @@ class TokenRefreshManager {
259
301
  const refreshSuccess = await this.attemptInternalRefresh();
260
302
  if (!refreshSuccess) {
261
303
  // Failed to refresh - delegate cleanup to AuthService
262
- await this.authService.handleAuthFailure('Failed to refresh expired token');
304
+ await this.authService.handleAuthFailure();
263
305
  }
264
306
  }
265
307
  }
266
308
  catch (error) {
267
309
  // Delegate token cleanup to AuthService for consistency
268
- await this.authService.handleAuthFailure('Token validation failed');
310
+ await this.authService.handleAuthFailure();
269
311
  }
270
312
  }
271
313
  async attemptInternalRefresh() {
@@ -274,7 +316,11 @@ class TokenRefreshManager {
274
316
  return true;
275
317
  }
276
318
  catch (error) {
277
- console.warn('[TokenRefreshManager] Internal refresh failed:', error);
319
+ // Check if this is a 401 error and set auth failure flag
320
+ const isAuthError = error && typeof error === 'object' && 'status' in error && error.status === 401;
321
+ if (isAuthError) {
322
+ await this.authService.handleAuthFailure();
323
+ }
278
324
  return false;
279
325
  }
280
326
  }
@@ -412,26 +458,23 @@ class DefaultAuthProvider {
412
458
  async getProjectKey() {
413
459
  return this.config.projectKey || null;
414
460
  }
415
- async onTokenExpired() {
461
+ async onAuthStatusChange(status) {
416
462
  try {
417
- if (this.config.onTokenExpired) {
418
- await this.config.onTokenExpired();
419
- // No need to clear tokens here - caller (PersApiClient) will handle cleanup if this fails
420
- return;
421
- }
422
- if (this.config.tokenProvider) {
463
+ // Handle provider-level responsibilities first
464
+ if (status === exports.AuthStatus.TOKEN_EXPIRED && this.config.tokenProvider) {
423
465
  const newToken = await this.config.tokenProvider();
424
466
  if (newToken) {
425
467
  await this.tokenManager.setAccessToken(newToken);
426
- this.config.onTokenRefreshed?.(newToken);
427
- return;
468
+ // Don't return - still notify the app about the status
428
469
  }
429
470
  }
430
- // No recovery mechanism available - throw error to let caller handle cleanup
431
- throw new Error('No token recovery mechanism available');
471
+ // Then delegate to config callback if available
472
+ if (this.config.onAuthStatusChange) {
473
+ await this.config.onAuthStatusChange(status);
474
+ }
432
475
  }
433
476
  catch (error) {
434
- // Re-throw error to let caller (PersApiClient/AuthService) handle cleanup
477
+ // Re-throw error to let caller (AuthService) handle cleanup
435
478
  throw error;
436
479
  }
437
480
  }
@@ -561,32 +604,30 @@ class PersApiClient {
561
604
  // Error handling - proactive token refresh should prevent most 401s
562
605
  const status = web3ChainService.ErrorUtils.getStatus(error);
563
606
  const errorMessage = web3ChainService.ErrorUtils.getMessage(error);
564
- // Fallback: reactive token refresh only if proactive check missed something
565
- // Only retry once (retryCount === 0) and only for 401 errors
566
- if (retryCount === 0 && this.mergedConfig.authProvider && status === 401) {
567
- try {
568
- // First attempt: try internal refresh token before external callback
569
- const refreshSuccessful = await this.attemptInternalRefresh();
570
- if (!refreshSuccessful) {
571
- // Second attempt: call external onTokenExpired callback
572
- if (this.mergedConfig.authProvider.onTokenExpired) {
573
- await this.mergedConfig.authProvider.onTokenExpired();
574
- }
575
- else {
576
- console.warn('[PersApiClient] No refresh token or onTokenExpired callback available');
577
- throw new Error('No token refresh mechanism available');
607
+ // Handle 401 errors centrally through AuthService
608
+ if (status === 401) {
609
+ // Extract backend error details for better error reporting
610
+ const backendError = web3ChainService.ErrorUtils.extractBackendErrorDetails(error);
611
+ // If this IS a refresh request that failed with 401, don't retry to avoid infinite loop
612
+ if (options?.isRefreshRequest) {
613
+ throw new web3ChainService.AuthenticationError(backendError.userMessage || backendError.message || 'Refresh token expired', endpoint, method, backendError.code, backendError.userMessage, backendError.title);
614
+ }
615
+ // For regular requests: try refresh once, then fail
616
+ if (retryCount === 0 && this.mergedConfig.authProvider) {
617
+ try {
618
+ const refreshSuccessful = await this.refreshManager.attemptInternalRefresh();
619
+ if (refreshSuccessful) {
620
+ // Retry the request with retryCount = 1 to prevent further retries
621
+ return await this.request(method, endpoint, body, { ...options, retryCount: 1 });
578
622
  }
579
623
  }
580
- // Retry the request with retryCount = 1 to prevent further retries
581
- return await this.request(method, endpoint, body, { ...options, retryCount: 1 });
582
- }
583
- catch (refreshError) {
584
- // Delegate token cleanup to AuthService for consistency
585
- if (this.authService) {
586
- await this.authService.handleAuthFailure('Auth refresh failed in API client');
624
+ catch (refreshError) {
625
+ // Refresh failed - let auth service handle it
587
626
  }
588
- throw new web3ChainService.PersApiError(`Auth refresh failed: ${refreshError.message || refreshError}`, endpoint, method, 401);
589
627
  }
628
+ // Auth failure - let AuthService handle cleanup and notify app
629
+ await this.authService.handleAuthFailure();
630
+ throw new web3ChainService.AuthenticationError(backendError.userMessage || backendError.message || 'Authentication required', endpoint, method, backendError.code, backendError.userMessage, backendError.title);
590
631
  }
591
632
  throw new web3ChainService.PersApiError(errorMessage, endpoint, method, status || undefined, web3ChainService.ErrorUtils.isRetryable(error));
592
633
  }
@@ -4782,6 +4823,182 @@ class TenantManager {
4782
4823
  }
4783
4824
  }
4784
4825
 
4826
+ /**
4827
+ * Platform-Agnostic API Key API Client
4828
+ *
4829
+ * Handles API key management operations for tenant admins.
4830
+ * All operations require admin authentication and operate within tenant context.
4831
+ */
4832
+ class ApiKeyApi {
4833
+ constructor(apiClient) {
4834
+ this.apiClient = apiClient;
4835
+ this.basePath = '/api-keys';
4836
+ }
4837
+ /**
4838
+ * ADMIN: Get all tenant API keys
4839
+ *
4840
+ * @param type Optional filter by integration API key type (database-stored tokens that can be revoked)
4841
+ * @param includeRevoked Include revoked API keys in results (default: false)
4842
+ * @returns Array of API keys for the current tenant
4843
+ */
4844
+ async getTenantApiKeys(type, includeRevoked = false) {
4845
+ const params = new URLSearchParams();
4846
+ if (type)
4847
+ params.append('type', type);
4848
+ if (includeRevoked)
4849
+ params.append('includeRevoked', 'true');
4850
+ const queryString = params.toString();
4851
+ const url = queryString ? `${this.basePath}?${queryString}` : this.basePath;
4852
+ return this.apiClient.get(url);
4853
+ }
4854
+ /**
4855
+ * ADMIN: Create new API key
4856
+ *
4857
+ * @param type Type of API key to create
4858
+ * @param name Name for the API key
4859
+ * @returns Created API key with the actual key (store securely - only returned once)
4860
+ */
4861
+ async createApiKey(req) {
4862
+ return this.apiClient.post(this.basePath, req);
4863
+ }
4864
+ /**
4865
+ * ADMIN: Revoke API key
4866
+ *
4867
+ * @param apiKeyId Unique identifier of the API key to revoke
4868
+ * @returns API key verification details with revocation status
4869
+ */
4870
+ async revokeApiKey(apiKeyId) {
4871
+ return this.apiClient.delete(`${this.basePath}/${apiKeyId}`);
4872
+ }
4873
+ }
4874
+
4875
+ /**
4876
+ * API Key Manager
4877
+ *
4878
+ * Provides high-level API key management operations for tenant admins.
4879
+ * Handles JWT token creation, API key listing, and revocation with proper error handling.
4880
+ *
4881
+ * **Admin Access Required**: All operations require tenant admin authentication
4882
+ *
4883
+ * @example
4884
+ * ```typescript
4885
+ * // Create JWT token for tenant
4886
+ * const jwtToken = await sdk.apiKeys.createJwtToken('Frontend App');
4887
+ * console.log('Store this JWT securely:', jwtToken.key);
4888
+ *
4889
+ * // List all tenant API keys
4890
+ * const apiKeys = await sdk.apiKeys.listApiKeys();
4891
+ * apiKeys.forEach(key => {
4892
+ * console.log(`${key.name} (${key.type}) - Active: ${key.isActive}`);
4893
+ * });
4894
+ *
4895
+ * // Revoke an API key
4896
+ * await sdk.apiKeys.revokeApiKey('key-id-to-revoke');
4897
+ * ```
4898
+ */
4899
+ class ApiKeyManager {
4900
+ constructor(apiClient) {
4901
+ this.apiKeyApi = new ApiKeyApi(apiClient);
4902
+ }
4903
+ // ==========================================
4904
+ // TENANT API KEY OPERATIONS (Admin Only)
4905
+ // ==========================================
4906
+ /**
4907
+ * Get all API keys for the current tenant
4908
+ *
4909
+ * **Admin Only**: Requires tenant admin authentication
4910
+ *
4911
+ * @param type Optional filter by integration API key type (database-stored tokens)
4912
+ * @param includeRevoked Include revoked API keys in results (default: false)
4913
+ * @returns Array of API keys with metadata (excludes actual key values)
4914
+ *
4915
+ * @example
4916
+ * ```typescript
4917
+ * // Get all active API keys
4918
+ * const allKeys = await sdk.apiKeys.listApiKeys();
4919
+ *
4920
+ * // Get only active JWT tokens
4921
+ * const jwtKeys = await sdk.apiKeys.listApiKeys('TENANT_SYSTEM_JWT');
4922
+ *
4923
+ * // Get all JWT tokens including revoked ones
4924
+ * const allJwtKeys = await sdk.apiKeys.listApiKeys('TENANT_SYSTEM_JWT', true);
4925
+ * ```
4926
+ */
4927
+ async listApiKeys(type, includeRevoked = false) {
4928
+ try {
4929
+ return await this.apiKeyApi.getTenantApiKeys(type, includeRevoked);
4930
+ }
4931
+ catch (error) {
4932
+ console.error('[ApiKeyManager] Failed to list API keys:', error);
4933
+ throw error;
4934
+ }
4935
+ }
4936
+ /**
4937
+ * Create a new API key with specified type
4938
+ *
4939
+ * **Admin Only**: Requires tenant admin authentication
4940
+ * **Security Warning**: The returned API key is only shown once - store it securely
4941
+ *
4942
+ * @param type Type of API key to create
4943
+ * @param name Human-readable name for the API key
4944
+ * @returns Created API key with the actual key value
4945
+ *
4946
+ * @example
4947
+ * ```typescript
4948
+ * // Create a JWT token
4949
+ * const jwtKey = await sdk.apiKeys.createApiKey('TENANT_SYSTEM_JWT', 'Frontend App');
4950
+ * console.log('Store this JWT securely:', jwtKey.privateKey);
4951
+ * ```
4952
+ */
4953
+ async createApiKey(req) {
4954
+ try {
4955
+ return await this.apiKeyApi.createApiKey(req);
4956
+ }
4957
+ catch (error) {
4958
+ console.error('[ApiKeyManager] Failed to create API key:', error);
4959
+ throw error;
4960
+ }
4961
+ }
4962
+ /**
4963
+ * Permanently revoke an API key
4964
+ *
4965
+ * **Admin Only**: Requires tenant admin authentication
4966
+ * **Warning**: This operation cannot be undone. The API key will be permanently disabled.
4967
+ *
4968
+ * @param apiKeyId Unique identifier of the API key to revoke
4969
+ * @returns API key verification details with revocation status
4970
+ *
4971
+ * @example
4972
+ * ```typescript
4973
+ * try {
4974
+ * // List keys to find the one to revoke
4975
+ * const apiKeys = await sdk.apiKeys.listApiKeys();
4976
+ * const oldKey = apiKeys.find(key => key.name === 'Old Frontend App');
4977
+ *
4978
+ * if (oldKey) {
4979
+ * const result = await sdk.apiKeys.revokeApiKey(oldKey.id);
4980
+ * console.log('Revocation successful:', result.success);
4981
+ * if (result.apiKey) {
4982
+ * console.log('Revoked key:', result.apiKey.name);
4983
+ * }
4984
+ * }
4985
+ * } catch (error) {
4986
+ * console.error('Failed to revoke API key:', error.message);
4987
+ * }
4988
+ * ```
4989
+ */
4990
+ async revokeApiKey(apiKeyId) {
4991
+ try {
4992
+ const result = await this.apiKeyApi.revokeApiKey(apiKeyId);
4993
+ return result;
4994
+ }
4995
+ catch (error) {
4996
+ console.error('[ApiKeyManager] Failed to revoke API key:', error);
4997
+ throw error;
4998
+ }
4999
+ }
5000
+ }
5001
+
4785
5002
  /**
4786
5003
  * Analytics Manager - Clean, high-level interface for analytics operations
4787
5004
  *
@@ -5339,6 +5556,7 @@ class PersSDK {
5339
5556
  this._purchases = new PurchaseManager(this.apiClient);
5340
5557
  this._files = new FileManager(this.apiClient);
5341
5558
  this._tenants = new TenantManager(this.apiClient);
5559
+ this._apiKeys = new ApiKeyManager(this.apiClient);
5342
5560
  this._analytics = new AnalyticsManager(this.apiClient);
5343
5561
  this._donations = new DonationManager(this.apiClient);
5344
5562
  this._web3 = new Web3Manager(this.apiClient);
@@ -5512,6 +5730,30 @@ class PersSDK {
5512
5730
  get tenants() {
5513
5731
  return this._tenants;
5514
5732
  }
5733
+ /**
5734
+ * API Key manager - High-level API key management operations (Admin Only)
5735
+ *
5736
+ * Provides methods for creating, listing, and revoking API keys for the tenant.
5737
+ * All operations require tenant admin authentication.
5738
+ *
5739
+ * @returns ApiKeyManager instance
5740
+ *
5741
+ * @example API Key Operations
5742
+ * ```typescript
5743
+ * // Create a JWT token for frontend authentication
5744
+ * const jwtToken = await sdk.apiKeys.createJwtToken('Frontend App');
5745
+ * console.log('Store this JWT securely:', jwtToken.key);
5746
+ *
5747
+ * // List all API keys
5748
+ * const apiKeys = await sdk.apiKeys.listApiKeys();
5749
+ *
5750
+ * // Revoke an old API key
5751
+ * await sdk.apiKeys.revokeApiKey('old-key-id');
5752
+ * ```
5753
+ */
5754
+ get apiKeys() {
5755
+ return this._apiKeys;
5756
+ }
5515
5757
  /**
5516
5758
  * Analytics manager - High-level analytics operations
5517
5759
  *
@@ -5597,6 +5839,8 @@ function createPersSDK(httpClient, config) {
5597
5839
  }
5598
5840
 
5599
5841
  exports.AnalyticsManager = AnalyticsManager;
5842
+ exports.ApiKeyApi = ApiKeyApi;
5843
+ exports.ApiKeyManager = ApiKeyManager;
5600
5844
  exports.AuthApi = AuthApi;
5601
5845
  exports.AuthManager = AuthManager;
5602
5846
  exports.AuthService = AuthService;
@@ -5627,4 +5871,4 @@ exports.detectEnvironment = detectEnvironment;
5627
5871
  exports.environment = environment;
5628
5872
  exports.mergeWithDefaults = mergeWithDefaults;
5629
5873
  exports.warnIfProblematicEnvironment = warnIfProblematicEnvironment;
5630
- //# sourceMappingURL=pers-sdk-tfJJbxVi.cjs.map
5874
+ //# sourceMappingURL=pers-sdk-CCegy2bB.cjs.map