@explorins/pers-sdk 1.2.5 → 1.2.6
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/analytics.cjs +6 -0
- package/dist/analytics.cjs.map +1 -1
- package/dist/analytics.js +2 -0
- package/dist/analytics.js.map +1 -1
- package/dist/business.cjs +6 -0
- package/dist/business.cjs.map +1 -1
- package/dist/business.js +2 -0
- package/dist/business.js.map +1 -1
- package/dist/campaign.cjs +6 -0
- package/dist/campaign.cjs.map +1 -1
- package/dist/campaign.js +2 -0
- package/dist/campaign.js.map +1 -1
- package/dist/{auth-admin/api/auth-admin-api.d.ts → core/auth/api/auth-api.d.ts} +7 -8
- package/dist/core/auth/api/auth-api.d.ts.map +1 -0
- package/dist/core/auth/auth-provider.interface.d.ts +25 -1
- package/dist/core/auth/auth-provider.interface.d.ts.map +1 -1
- package/dist/core/auth/create-auth-provider.d.ts +3 -3
- package/dist/core/auth/create-auth-provider.d.ts.map +1 -1
- package/dist/core/auth/index.d.ts +38 -0
- package/dist/core/auth/index.d.ts.map +1 -0
- package/dist/core/auth/services/auth-service.d.ts +49 -0
- package/dist/core/auth/services/auth-service.d.ts.map +1 -0
- package/dist/core/auth/simple-sdk-auth-provider.d.ts +27 -0
- package/dist/core/auth/simple-sdk-auth-provider.d.ts.map +1 -0
- package/dist/core/index.d.ts +1 -2
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/pers-api-client.d.ts +25 -3
- package/dist/core/pers-api-client.d.ts.map +1 -1
- package/dist/core.cjs +470 -156
- package/dist/core.cjs.map +1 -1
- package/dist/core.js +464 -157
- package/dist/core.js.map +1 -1
- package/dist/donation.cjs +6 -0
- package/dist/donation.cjs.map +1 -1
- package/dist/donation.js +2 -0
- package/dist/donation.js.map +1 -1
- package/dist/index.cjs +523 -360
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +518 -359
- package/dist/index.js.map +1 -1
- package/dist/package.json +5 -5
- package/dist/payment.cjs +6 -0
- package/dist/payment.cjs.map +1 -1
- package/dist/payment.js +2 -0
- package/dist/payment.js.map +1 -1
- package/dist/redemption/api/redemption-api.d.ts +26 -64
- package/dist/redemption/api/redemption-api.d.ts.map +1 -1
- package/dist/redemption/services/redemption-service.d.ts +21 -3
- package/dist/redemption/services/redemption-service.d.ts.map +1 -1
- package/dist/redemption.cjs +61 -94
- package/dist/redemption.cjs.map +1 -1
- package/dist/redemption.js +57 -94
- package/dist/redemption.js.map +1 -1
- package/dist/shared/interfaces/pers-shared-lib.interfaces.d.ts +1 -1
- package/dist/shared/interfaces/pers-shared-lib.interfaces.d.ts.map +1 -1
- package/dist/tenant.cjs +6 -0
- package/dist/tenant.cjs.map +1 -1
- package/dist/tenant.js +2 -0
- package/dist/tenant.js.map +1 -1
- package/dist/token.cjs +6 -0
- package/dist/token.cjs.map +1 -1
- package/dist/token.js +2 -0
- package/dist/token.js.map +1 -1
- package/dist/transaction.cjs +4 -0
- package/dist/transaction.cjs.map +1 -1
- package/dist/transaction.js +1 -0
- package/dist/transaction.js.map +1 -1
- package/dist/user-status.cjs +6 -0
- package/dist/user-status.cjs.map +1 -1
- package/dist/user-status.js +2 -0
- package/dist/user-status.js.map +1 -1
- package/dist/user.cjs +6 -0
- package/dist/user.cjs.map +1 -1
- package/dist/user.js +2 -0
- package/dist/user.js.map +1 -1
- package/dist/web3-chain.cjs +5 -0
- package/dist/web3-chain.cjs.map +1 -1
- package/dist/web3-chain.js +1 -0
- package/dist/web3-chain.js.map +1 -1
- package/dist/web3.cjs +1 -0
- package/dist/web3.cjs.map +1 -1
- package/dist/web3.js +1 -0
- package/dist/web3.js.map +1 -1
- package/package.json +5 -5
- package/dist/auth-admin/api/auth-admin-api.d.ts.map +0 -1
- package/dist/auth-admin/index.d.ts +0 -27
- package/dist/auth-admin/index.d.ts.map +0 -1
- package/dist/auth-admin/services/auth-admin-service.d.ts +0 -27
- package/dist/auth-admin/services/auth-admin-service.d.ts.map +0 -1
- package/dist/auth-admin.cjs +0 -115
- package/dist/auth-admin.cjs.map +0 -1
- package/dist/auth-admin.js +0 -111
- package/dist/auth-admin.js.map +0 -1
- package/dist/core/auth/simple-auth-config.interface.d.ts +0 -15
- package/dist/core/auth/simple-auth-config.interface.d.ts.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { AccountOwnerType, TransactionRole } from '@explorins/pers-shared';
|
|
2
|
+
export { AccountOwnerType } from '@explorins/pers-shared';
|
|
2
3
|
import { jwtDecode } from 'jwt-decode';
|
|
3
4
|
import Web3 from 'web3';
|
|
4
5
|
import { FetchRequest, JsonRpcProvider } from 'ethers';
|
|
@@ -42,6 +43,241 @@ function mergeWithDefaults(config) {
|
|
|
42
43
|
};
|
|
43
44
|
}
|
|
44
45
|
|
|
46
|
+
/**
|
|
47
|
+
* Platform-Agnostic Auth Admin API Client
|
|
48
|
+
*
|
|
49
|
+
* Handles authentication and authorization admin operations using the PERS backend.
|
|
50
|
+
* Uses @explorins/pers-shared DTOs for consistency with backend.
|
|
51
|
+
*
|
|
52
|
+
* Note: Special header handling (bypass-auth-interceptor) may need to be implemented
|
|
53
|
+
* at the PersApiClient level or through a specialized auth client.
|
|
54
|
+
*/
|
|
55
|
+
class AuthApi {
|
|
56
|
+
constructor(apiClient) {
|
|
57
|
+
this.apiClient = apiClient;
|
|
58
|
+
this.basePath = '/auth';
|
|
59
|
+
}
|
|
60
|
+
// ==========================================
|
|
61
|
+
// ADMIN AUTHENTICATION OPERATIONS
|
|
62
|
+
// ==========================================
|
|
63
|
+
/**
|
|
64
|
+
* ADMIN: Login tenant admin with JWT
|
|
65
|
+
* Note: JWT handling and auth bypass headers may need special implementation
|
|
66
|
+
*/
|
|
67
|
+
async loginTenantAdmin(jwt) {
|
|
68
|
+
const body = {
|
|
69
|
+
authToken: jwt,
|
|
70
|
+
authType: AccountOwnerType.TENANT
|
|
71
|
+
};
|
|
72
|
+
return this.apiClient.post(`${this.basePath}/token`, body);
|
|
73
|
+
}
|
|
74
|
+
async loginUser(jwt) {
|
|
75
|
+
const body = {
|
|
76
|
+
authToken: jwt,
|
|
77
|
+
authType: AccountOwnerType.USER
|
|
78
|
+
};
|
|
79
|
+
return this.apiClient.post(`${this.basePath}/token`, body);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* ADMIN: Refresh access token
|
|
83
|
+
* Note: Bypass header handling may need special implementation
|
|
84
|
+
*/
|
|
85
|
+
async refreshAccessToken(refreshToken) {
|
|
86
|
+
return this.apiClient.post(`${this.basePath}/refresh`, { refreshToken });
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Platform-Agnostic Auth Admin Service
|
|
92
|
+
*
|
|
93
|
+
* Contains auth admin business logic and operations that work across platforms.
|
|
94
|
+
* No framework dependencies - pure TypeScript business logic.
|
|
95
|
+
*
|
|
96
|
+
* Focuses only on actual backend capabilities.
|
|
97
|
+
*/
|
|
98
|
+
class AuthService {
|
|
99
|
+
constructor(authApi, authProvider) {
|
|
100
|
+
this.authApi = authApi;
|
|
101
|
+
this.authProvider = authProvider;
|
|
102
|
+
}
|
|
103
|
+
// ==========================================
|
|
104
|
+
// ADMIN AUTHENTICATION OPERATIONS
|
|
105
|
+
// ==========================================
|
|
106
|
+
/**
|
|
107
|
+
* ADMIN: Login tenant admin with JWT
|
|
108
|
+
* Automatically stores tokens if auth provider supports token storage
|
|
109
|
+
*/
|
|
110
|
+
async loginTenantAdmin(jwt) {
|
|
111
|
+
const response = await this.authApi.loginTenantAdmin(jwt);
|
|
112
|
+
// Store tokens if auth provider supports it
|
|
113
|
+
if (this.authProvider && response.accessToken) {
|
|
114
|
+
await this.storeTokens(response.accessToken, response.refreshToken);
|
|
115
|
+
}
|
|
116
|
+
return response;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* ADMIN: Login user with JWT
|
|
120
|
+
* Automatically stores tokens if auth provider supports token storage
|
|
121
|
+
*/
|
|
122
|
+
async loginUser(jwt) {
|
|
123
|
+
const response = await this.authApi.loginUser(jwt);
|
|
124
|
+
// Store tokens if auth provider supports it
|
|
125
|
+
if (this.authProvider && response.accessToken) {
|
|
126
|
+
await this.storeTokens(response.accessToken, response.refreshToken);
|
|
127
|
+
}
|
|
128
|
+
return response;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* ADMIN: Refresh access token
|
|
132
|
+
* Automatically stores new tokens if auth provider supports token storage
|
|
133
|
+
*/
|
|
134
|
+
async refreshAccessToken(refreshToken) {
|
|
135
|
+
// Use provided refresh token or get from auth provider
|
|
136
|
+
const tokenToUse = refreshToken || (this.authProvider?.getRefreshToken ? await this.authProvider.getRefreshToken() : null);
|
|
137
|
+
if (!tokenToUse) {
|
|
138
|
+
throw new Error('No refresh token available for token refresh');
|
|
139
|
+
}
|
|
140
|
+
const response = await this.authApi.refreshAccessToken(tokenToUse);
|
|
141
|
+
// Store new tokens if auth provider supports it
|
|
142
|
+
if (this.authProvider && response.accessToken) {
|
|
143
|
+
await this.storeTokens(response.accessToken, response.refreshToken);
|
|
144
|
+
}
|
|
145
|
+
return response;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Automatic token refresh using stored refresh token
|
|
149
|
+
* Convenience method for 401 error handling
|
|
150
|
+
*/
|
|
151
|
+
async autoRefreshToken() {
|
|
152
|
+
return this.refreshAccessToken(); // Uses stored refresh token
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Clear stored tokens if auth provider supports it
|
|
156
|
+
*/
|
|
157
|
+
async clearTokens() {
|
|
158
|
+
if (this.authProvider?.clearTokens) {
|
|
159
|
+
await this.authProvider.clearTokens();
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Check if we have valid tokens for authentication
|
|
164
|
+
*/
|
|
165
|
+
hasValidAuth() {
|
|
166
|
+
return this.authProvider?.hasValidToken?.() ?? false;
|
|
167
|
+
}
|
|
168
|
+
// ==========================================
|
|
169
|
+
// PRIVATE HELPERS
|
|
170
|
+
// ==========================================
|
|
171
|
+
/**
|
|
172
|
+
* Store tokens using auth provider if it supports token storage
|
|
173
|
+
*/
|
|
174
|
+
async storeTokens(accessToken, refreshToken) {
|
|
175
|
+
if (!this.authProvider)
|
|
176
|
+
return;
|
|
177
|
+
try {
|
|
178
|
+
// Store access token
|
|
179
|
+
if (this.authProvider.setAccessToken) {
|
|
180
|
+
await this.authProvider.setAccessToken(accessToken);
|
|
181
|
+
}
|
|
182
|
+
// Store refresh token if provided and supported
|
|
183
|
+
if (refreshToken && this.authProvider.setRefreshToken) {
|
|
184
|
+
await this.authProvider.setRefreshToken(refreshToken);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
catch (error) {
|
|
188
|
+
console.error('Failed to store tokens in auth provider:', error);
|
|
189
|
+
// Don't throw - token storage failure shouldn't break authentication
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Simple, self-contained authentication provider for SDK
|
|
196
|
+
*
|
|
197
|
+
* Manages tokens internally without external dependencies.
|
|
198
|
+
* Perfect for platform-agnostic usage.
|
|
199
|
+
*/
|
|
200
|
+
class SimpleSdkAuthProvider {
|
|
201
|
+
constructor(projectKey) {
|
|
202
|
+
this.accessToken = null;
|
|
203
|
+
this.refreshToken = null;
|
|
204
|
+
this.projectKey = null;
|
|
205
|
+
this.authType = 'admin';
|
|
206
|
+
this.projectKey = projectKey || null;
|
|
207
|
+
// Try to load tokens from localStorage if available
|
|
208
|
+
this.loadTokensFromStorage();
|
|
209
|
+
}
|
|
210
|
+
async getToken() {
|
|
211
|
+
// Return stored access token
|
|
212
|
+
return this.accessToken;
|
|
213
|
+
}
|
|
214
|
+
async getProjectKey() {
|
|
215
|
+
return this.projectKey;
|
|
216
|
+
}
|
|
217
|
+
async onTokenExpired() {
|
|
218
|
+
console.log('SimpleSdkAuthProvider: Token expired, attempting refresh...');
|
|
219
|
+
if (!this.refreshToken) {
|
|
220
|
+
console.warn('SimpleSdkAuthProvider: No refresh token available');
|
|
221
|
+
throw new Error('No refresh token available for refresh');
|
|
222
|
+
}
|
|
223
|
+
// Note: Actual refresh logic would be handled by the SDK's AuthService
|
|
224
|
+
// This provider just manages token storage
|
|
225
|
+
console.warn('SimpleSdkAuthProvider: Token refresh should be handled by SDK AuthService');
|
|
226
|
+
}
|
|
227
|
+
// Token storage methods
|
|
228
|
+
async setAccessToken(token) {
|
|
229
|
+
this.accessToken = token;
|
|
230
|
+
this.saveTokenToStorage('pers_access_token', token);
|
|
231
|
+
}
|
|
232
|
+
async setRefreshToken(token) {
|
|
233
|
+
this.refreshToken = token;
|
|
234
|
+
this.saveTokenToStorage('pers_refresh_token', token);
|
|
235
|
+
}
|
|
236
|
+
async getRefreshToken() {
|
|
237
|
+
return this.refreshToken;
|
|
238
|
+
}
|
|
239
|
+
async clearTokens() {
|
|
240
|
+
this.accessToken = null;
|
|
241
|
+
this.refreshToken = null;
|
|
242
|
+
// Clear from storage
|
|
243
|
+
this.removeTokenFromStorage('pers_access_token');
|
|
244
|
+
this.removeTokenFromStorage('pers_refresh_token');
|
|
245
|
+
}
|
|
246
|
+
// Internal methods for token persistence
|
|
247
|
+
loadTokensFromStorage() {
|
|
248
|
+
if (typeof localStorage !== 'undefined') {
|
|
249
|
+
try {
|
|
250
|
+
this.accessToken = localStorage.getItem('pers_access_token');
|
|
251
|
+
this.refreshToken = localStorage.getItem('pers_refresh_token');
|
|
252
|
+
}
|
|
253
|
+
catch (error) {
|
|
254
|
+
console.error('Failed to load tokens from localStorage:', error);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
else {
|
|
258
|
+
console.warn('localStorage is not available for token persistence');
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
saveTokenToStorage(key, value) {
|
|
262
|
+
if (typeof localStorage !== 'undefined') {
|
|
263
|
+
localStorage.setItem(key, value);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
removeTokenFromStorage(key) {
|
|
267
|
+
if (typeof localStorage !== 'undefined') {
|
|
268
|
+
localStorage.removeItem(key);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
// Utility methods for external integration
|
|
272
|
+
hasValidToken() {
|
|
273
|
+
const hasToken = !!this.accessToken;
|
|
274
|
+
return hasToken;
|
|
275
|
+
}
|
|
276
|
+
hasRefreshToken() {
|
|
277
|
+
return !!this.refreshToken;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
45
281
|
// packages/pers-sdk/src/core/pers-api-client.ts
|
|
46
282
|
/**
|
|
47
283
|
* PERS API Client - Core platform-agnostic client for PERS backend
|
|
@@ -52,8 +288,15 @@ class PersApiClient {
|
|
|
52
288
|
this.config = config;
|
|
53
289
|
// Merge user config with defaults (production + v2)
|
|
54
290
|
this.mergedConfig = mergeWithDefaults(config);
|
|
291
|
+
// Auto-create auth provider if none provided
|
|
292
|
+
if (!this.mergedConfig.authProvider) {
|
|
293
|
+
this.mergedConfig.authProvider = new SimpleSdkAuthProvider(this.mergedConfig.apiProjectKey);
|
|
294
|
+
}
|
|
55
295
|
// Build API root from merged environment and version
|
|
56
296
|
this.apiRoot = buildApiRoot(this.mergedConfig.environment, this.mergedConfig.apiVersion);
|
|
297
|
+
// Initialize auth services for direct authentication
|
|
298
|
+
this.authApi = new AuthApi(this);
|
|
299
|
+
this.authService = new AuthService(this.authApi, this.mergedConfig.authProvider);
|
|
57
300
|
}
|
|
58
301
|
/**
|
|
59
302
|
* Get request headers including auth token and project key
|
|
@@ -158,6 +401,45 @@ class PersApiClient {
|
|
|
158
401
|
async delete(endpoint) {
|
|
159
402
|
return this.request('DELETE', endpoint);
|
|
160
403
|
}
|
|
404
|
+
// ==========================================
|
|
405
|
+
// AUTHENTICATION METHODS
|
|
406
|
+
// ==========================================
|
|
407
|
+
/**
|
|
408
|
+
* Login admin user with external JWT (e.g., Firebase)
|
|
409
|
+
* Automatically stores tokens in auth provider if available
|
|
410
|
+
*/
|
|
411
|
+
async loginAdmin(externalJwt) {
|
|
412
|
+
return this.authService.loginTenantAdmin(externalJwt);
|
|
413
|
+
}
|
|
414
|
+
/**
|
|
415
|
+
* Login regular user with external JWT
|
|
416
|
+
* Automatically stores tokens in auth provider if available
|
|
417
|
+
*/
|
|
418
|
+
async loginUser(externalJwt) {
|
|
419
|
+
return this.authService.loginUser(externalJwt);
|
|
420
|
+
}
|
|
421
|
+
/**
|
|
422
|
+
* Refresh access token using stored refresh token
|
|
423
|
+
*/
|
|
424
|
+
async refreshToken() {
|
|
425
|
+
const refreshToken = await this.mergedConfig.authProvider?.getRefreshToken?.();
|
|
426
|
+
if (!refreshToken) {
|
|
427
|
+
throw new Error('No refresh token available');
|
|
428
|
+
}
|
|
429
|
+
return this.authService.refreshAccessToken(refreshToken);
|
|
430
|
+
}
|
|
431
|
+
/**
|
|
432
|
+
* Clear all stored authentication tokens
|
|
433
|
+
*/
|
|
434
|
+
async clearAuth() {
|
|
435
|
+
return this.authService.clearTokens();
|
|
436
|
+
}
|
|
437
|
+
/**
|
|
438
|
+
* Check if user has valid authentication token
|
|
439
|
+
*/
|
|
440
|
+
hasValidAuth() {
|
|
441
|
+
return this.mergedConfig.authProvider?.hasValidToken?.() || false;
|
|
442
|
+
}
|
|
161
443
|
/**
|
|
162
444
|
* Get current configuration (returns merged config)
|
|
163
445
|
*/
|
|
@@ -180,168 +462,48 @@ class PersApiError extends Error {
|
|
|
180
462
|
this.name = 'PersApiError';
|
|
181
463
|
}
|
|
182
464
|
}
|
|
183
|
-
/**
|
|
184
|
-
* PERS API Client - Core platform-agnostic client for PERS backend
|
|
185
|
-
*/
|
|
186
|
-
/*import { HttpClient, RequestOptions } from './abstractions/http-client';
|
|
187
|
-
import { PersConfig, buildApiRoot, mergeWithDefaults } from './pers-config';
|
|
188
|
-
|
|
189
|
-
export class PersApiClient {
|
|
190
|
-
private readonly apiRoot: string;
|
|
191
|
-
private readonly mergedConfig: ReturnType<typeof mergeWithDefaults>;
|
|
192
|
-
|
|
193
|
-
constructor(
|
|
194
|
-
private httpClient: HttpClient,
|
|
195
|
-
private config: PersConfig
|
|
196
|
-
) {
|
|
197
|
-
// Merge user config with defaults (production + v2)
|
|
198
|
-
this.mergedConfig = mergeWithDefaults(config);
|
|
199
|
-
|
|
200
|
-
// Build API root from merged environment and version
|
|
201
|
-
this.apiRoot = buildApiRoot(this.mergedConfig.environment, this.mergedConfig.apiVersion);
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
/**
|
|
205
|
-
* Get request headers including auth token and project key
|
|
206
|
-
*/
|
|
207
|
-
/*private async getHeaders(): Promise<Record<string, string>> {
|
|
208
|
-
const headers: Record<string, string> = {
|
|
209
|
-
'Content-Type': 'application/json',
|
|
210
|
-
};
|
|
211
|
-
|
|
212
|
-
// Add authentication token
|
|
213
|
-
if (this.mergedConfig.authProvider) {
|
|
214
|
-
const token = await this.mergedConfig.authProvider.getToken();
|
|
215
|
-
if (token) {
|
|
216
|
-
headers['Authorization'] = `Bearer ${token}`;
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
// Add project key
|
|
221
|
-
if (this.mergedConfig.authProvider) {
|
|
222
|
-
const projectKey = await this.mergedConfig.authProvider.getProjectKey();
|
|
223
|
-
if (projectKey) {
|
|
224
|
-
headers['x-project-key'] = projectKey;
|
|
225
|
-
}
|
|
226
|
-
} else if(this.mergedConfig.apiProjectKey) {
|
|
227
|
-
// Fallback to config project key if no auth provider
|
|
228
|
-
headers['x-project-key'] = this.mergedConfig.apiProjectKey;
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
return headers;
|
|
232
|
-
}
|
|
233
465
|
|
|
234
466
|
/**
|
|
235
|
-
*
|
|
467
|
+
* Memory-based token storage (default)
|
|
236
468
|
*/
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
)
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
};
|
|
250
|
-
|
|
251
|
-
try {
|
|
252
|
-
switch (method) {
|
|
253
|
-
case 'GET':
|
|
254
|
-
return await this.httpClient.get<T>(url, requestOptions);
|
|
255
|
-
case 'POST':
|
|
256
|
-
return await this.httpClient.post<T>(url, body, requestOptions);
|
|
257
|
-
case 'PUT':
|
|
258
|
-
return await this.httpClient.put<T>(url, body, requestOptions);
|
|
259
|
-
case 'DELETE':
|
|
260
|
-
return await this.httpClient.delete<T>(url, requestOptions);
|
|
261
|
-
default:
|
|
262
|
-
throw new Error(`Unsupported HTTP method: ${method}`);
|
|
263
|
-
}
|
|
264
|
-
} catch (error: any) {
|
|
265
|
-
// Handle 401 errors with automatic token refresh
|
|
266
|
-
if (error.status === 401 && retryCount === 0 && this.mergedConfig.authProvider?.onTokenExpired) {
|
|
267
|
-
try {
|
|
268
|
-
await this.mergedConfig.authProvider.onTokenExpired();
|
|
269
|
-
// Retry once with refreshed token
|
|
270
|
-
return this.request<T>(method, endpoint, body, { ...options, retryCount: 1 });
|
|
271
|
-
} catch (refreshError) {
|
|
272
|
-
throw new PersApiError(
|
|
273
|
-
`Authentication refresh failed: ${refreshError}`,
|
|
274
|
-
endpoint,
|
|
275
|
-
method,
|
|
276
|
-
401
|
|
277
|
-
);
|
|
278
|
-
}
|
|
469
|
+
class MemoryTokenStorage {
|
|
470
|
+
constructor() {
|
|
471
|
+
this.storage = new Map();
|
|
472
|
+
}
|
|
473
|
+
async setItem(key, value) {
|
|
474
|
+
this.storage.set(key, value);
|
|
475
|
+
}
|
|
476
|
+
async getItem(key) {
|
|
477
|
+
return this.storage.get(key) || null;
|
|
478
|
+
}
|
|
479
|
+
async removeItem(key) {
|
|
480
|
+
this.storage.delete(key);
|
|
279
481
|
}
|
|
280
|
-
|
|
281
|
-
throw new PersApiError(
|
|
282
|
-
`PERS API request failed: ${error.message || error}`,
|
|
283
|
-
endpoint,
|
|
284
|
-
method,
|
|
285
|
-
error.status
|
|
286
|
-
);
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
/**
|
|
291
|
-
* Generic GET request
|
|
292
|
-
*/
|
|
293
|
-
/*async get<T>(endpoint: string): Promise<T> {
|
|
294
|
-
return this.request<T>('GET', endpoint);
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
/**
|
|
298
|
-
* Generic POST request
|
|
299
|
-
*/
|
|
300
|
-
/*async post<T>(endpoint: string, body?: any): Promise<T> {
|
|
301
|
-
return this.request<T>('POST', endpoint, body);
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
/**
|
|
305
|
-
* Generic PUT request
|
|
306
|
-
*/
|
|
307
|
-
/*async put<T>(endpoint: string, body?: any): Promise<T> {
|
|
308
|
-
return this.request<T>('PUT', endpoint, body);
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
/**
|
|
312
|
-
* Generic DELETE request
|
|
313
|
-
*/
|
|
314
|
-
/*async delete<T>(endpoint: string): Promise<T> {
|
|
315
|
-
return this.request<T>('DELETE', endpoint);
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
/**
|
|
319
|
-
* Get current configuration (returns merged config)
|
|
320
|
-
*/
|
|
321
|
-
/*getConfig(): ReturnType<typeof mergeWithDefaults> {
|
|
322
|
-
return this.mergedConfig;
|
|
323
482
|
}
|
|
324
|
-
|
|
325
483
|
/**
|
|
326
|
-
*
|
|
484
|
+
* localStorage-based token storage (browser only)
|
|
327
485
|
*/
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
)
|
|
340
|
-
|
|
341
|
-
|
|
486
|
+
class LocalStorageTokenStorage {
|
|
487
|
+
async setItem(key, value) {
|
|
488
|
+
if (typeof localStorage !== 'undefined') {
|
|
489
|
+
localStorage.setItem(key, value);
|
|
490
|
+
}
|
|
491
|
+
else {
|
|
492
|
+
throw new Error('localStorage is not available in this environment');
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
async getItem(key) {
|
|
496
|
+
if (typeof localStorage !== 'undefined') {
|
|
497
|
+
return localStorage.getItem(key);
|
|
498
|
+
}
|
|
499
|
+
return null;
|
|
500
|
+
}
|
|
501
|
+
async removeItem(key) {
|
|
502
|
+
if (typeof localStorage !== 'undefined') {
|
|
503
|
+
localStorage.removeItem(key);
|
|
504
|
+
}
|
|
505
|
+
}
|
|
342
506
|
}
|
|
343
|
-
}*/
|
|
344
|
-
|
|
345
507
|
/**
|
|
346
508
|
* Creates a platform-agnostic AuthProvider from simple configuration
|
|
347
509
|
*
|
|
@@ -352,12 +514,33 @@ constructor(
|
|
|
352
514
|
* - Token caching with refresh support
|
|
353
515
|
* - Automatic token refresh on expiration
|
|
354
516
|
* - Configurable token providers
|
|
355
|
-
* -
|
|
517
|
+
* - Token storage (memory, localStorage, custom)
|
|
518
|
+
* - Platform-independent
|
|
356
519
|
*
|
|
357
520
|
* @param config - Simple auth configuration
|
|
358
521
|
* @returns AuthProvider implementation
|
|
359
522
|
*/
|
|
360
523
|
function createAuthProvider(config) {
|
|
524
|
+
// Initialize token storage
|
|
525
|
+
let tokenStorage;
|
|
526
|
+
switch (config.tokenStorage) {
|
|
527
|
+
case 'localStorage':
|
|
528
|
+
tokenStorage = new LocalStorageTokenStorage();
|
|
529
|
+
break;
|
|
530
|
+
case 'custom':
|
|
531
|
+
if (!config.customTokenStorage) {
|
|
532
|
+
throw new Error('Custom token storage configuration is required when tokenStorage is "custom"');
|
|
533
|
+
}
|
|
534
|
+
tokenStorage = config.customTokenStorage;
|
|
535
|
+
break;
|
|
536
|
+
case 'memory':
|
|
537
|
+
default:
|
|
538
|
+
tokenStorage = new MemoryTokenStorage();
|
|
539
|
+
break;
|
|
540
|
+
}
|
|
541
|
+
// Token storage keys
|
|
542
|
+
const ACCESS_TOKEN_KEY = `pers_access_token_${config.authType || 'user'}`;
|
|
543
|
+
const REFRESH_TOKEN_KEY = `pers_refresh_token_${config.authType || 'user'}`;
|
|
361
544
|
// Store current token for refresh scenarios and caching
|
|
362
545
|
let currentToken = config.token || null;
|
|
363
546
|
let isRefreshing = false; // Prevent concurrent refresh attempts
|
|
@@ -374,6 +557,17 @@ function createAuthProvider(config) {
|
|
|
374
557
|
if (currentToken) {
|
|
375
558
|
return currentToken;
|
|
376
559
|
}
|
|
560
|
+
// Try to get token from storage
|
|
561
|
+
try {
|
|
562
|
+
const storedToken = await tokenStorage.getItem(ACCESS_TOKEN_KEY);
|
|
563
|
+
if (storedToken) {
|
|
564
|
+
currentToken = storedToken;
|
|
565
|
+
return storedToken;
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
catch (error) {
|
|
569
|
+
console.warn('Failed to retrieve token from storage:', error);
|
|
570
|
+
}
|
|
377
571
|
// Custom token provider function (always fresh)
|
|
378
572
|
if (config.tokenProvider) {
|
|
379
573
|
const token = await config.tokenProvider();
|
|
@@ -386,6 +580,48 @@ function createAuthProvider(config) {
|
|
|
386
580
|
async getProjectKey() {
|
|
387
581
|
return config.projectKey || null;
|
|
388
582
|
},
|
|
583
|
+
// Token storage methods
|
|
584
|
+
async setAccessToken(token) {
|
|
585
|
+
currentToken = token;
|
|
586
|
+
try {
|
|
587
|
+
await tokenStorage.setItem(ACCESS_TOKEN_KEY, token);
|
|
588
|
+
}
|
|
589
|
+
catch (error) {
|
|
590
|
+
console.error('Failed to store access token:', error);
|
|
591
|
+
throw error;
|
|
592
|
+
}
|
|
593
|
+
},
|
|
594
|
+
async setRefreshToken(token) {
|
|
595
|
+
try {
|
|
596
|
+
await tokenStorage.setItem(REFRESH_TOKEN_KEY, token);
|
|
597
|
+
}
|
|
598
|
+
catch (error) {
|
|
599
|
+
console.error('Failed to store refresh token:', error);
|
|
600
|
+
throw error;
|
|
601
|
+
}
|
|
602
|
+
},
|
|
603
|
+
async getRefreshToken() {
|
|
604
|
+
try {
|
|
605
|
+
return await tokenStorage.getItem(REFRESH_TOKEN_KEY);
|
|
606
|
+
}
|
|
607
|
+
catch (error) {
|
|
608
|
+
console.warn('Failed to retrieve refresh token from storage:', error);
|
|
609
|
+
return null;
|
|
610
|
+
}
|
|
611
|
+
},
|
|
612
|
+
async clearTokens() {
|
|
613
|
+
currentToken = null;
|
|
614
|
+
try {
|
|
615
|
+
await Promise.all([
|
|
616
|
+
tokenStorage.removeItem(ACCESS_TOKEN_KEY),
|
|
617
|
+
tokenStorage.removeItem(REFRESH_TOKEN_KEY)
|
|
618
|
+
]);
|
|
619
|
+
}
|
|
620
|
+
catch (error) {
|
|
621
|
+
console.error('Failed to clear tokens from storage:', error);
|
|
622
|
+
throw error;
|
|
623
|
+
}
|
|
624
|
+
},
|
|
389
625
|
async onTokenExpired() {
|
|
390
626
|
// Prevent concurrent refresh attempts
|
|
391
627
|
if (isRefreshing) {
|
|
@@ -397,7 +633,13 @@ function createAuthProvider(config) {
|
|
|
397
633
|
// No refresh logic provided
|
|
398
634
|
if (!config.onTokenExpired) {
|
|
399
635
|
console.warn('Token expired but no refresh logic provided');
|
|
400
|
-
currentToken = null;
|
|
636
|
+
currentToken = null;
|
|
637
|
+
try {
|
|
638
|
+
await tokenStorage.removeItem(ACCESS_TOKEN_KEY);
|
|
639
|
+
}
|
|
640
|
+
catch (error) {
|
|
641
|
+
console.warn('Failed to clear expired token from storage:', error);
|
|
642
|
+
}
|
|
401
643
|
return;
|
|
402
644
|
}
|
|
403
645
|
// Start refresh process
|
|
@@ -411,6 +653,13 @@ function createAuthProvider(config) {
|
|
|
411
653
|
const newToken = await config.tokenProvider();
|
|
412
654
|
if (newToken && newToken !== currentToken) {
|
|
413
655
|
currentToken = newToken;
|
|
656
|
+
// Store the new token
|
|
657
|
+
try {
|
|
658
|
+
await tokenStorage.setItem(ACCESS_TOKEN_KEY, newToken);
|
|
659
|
+
}
|
|
660
|
+
catch (error) {
|
|
661
|
+
console.warn('Failed to store refreshed token:', error);
|
|
662
|
+
}
|
|
414
663
|
// Notify about successful token refresh
|
|
415
664
|
if (config.onTokenRefreshed) {
|
|
416
665
|
config.onTokenRefreshed(newToken);
|
|
@@ -419,17 +668,35 @@ function createAuthProvider(config) {
|
|
|
419
668
|
else {
|
|
420
669
|
console.warn('Token refresh completed but no new token received');
|
|
421
670
|
currentToken = null;
|
|
671
|
+
try {
|
|
672
|
+
await tokenStorage.removeItem(ACCESS_TOKEN_KEY);
|
|
673
|
+
}
|
|
674
|
+
catch (error) {
|
|
675
|
+
console.warn('Failed to clear token after failed refresh:', error);
|
|
676
|
+
}
|
|
422
677
|
}
|
|
423
678
|
}
|
|
424
679
|
else {
|
|
425
680
|
// For static token configs, clear the token since we can't refresh
|
|
426
681
|
console.warn('Token expired for static token config - clearing token');
|
|
427
682
|
currentToken = null;
|
|
683
|
+
try {
|
|
684
|
+
await tokenStorage.removeItem(ACCESS_TOKEN_KEY);
|
|
685
|
+
}
|
|
686
|
+
catch (error) {
|
|
687
|
+
console.warn('Failed to clear expired static token:', error);
|
|
688
|
+
}
|
|
428
689
|
}
|
|
429
690
|
}
|
|
430
691
|
catch (error) {
|
|
431
692
|
console.error('Token refresh failed:', error);
|
|
432
693
|
currentToken = null; // Clear token on refresh failure
|
|
694
|
+
try {
|
|
695
|
+
await tokenStorage.removeItem(ACCESS_TOKEN_KEY);
|
|
696
|
+
}
|
|
697
|
+
catch (storageError) {
|
|
698
|
+
console.warn('Failed to clear token after refresh failure:', storageError);
|
|
699
|
+
}
|
|
433
700
|
throw error; // Re-throw to let SDK handle the error
|
|
434
701
|
}
|
|
435
702
|
finally {
|
|
@@ -466,6 +733,44 @@ function createAuthProvider(config) {
|
|
|
466
733
|
};
|
|
467
734
|
} */
|
|
468
735
|
|
|
736
|
+
/**
|
|
737
|
+
* @explorins/pers-sdk/core/auth - Consolidated Auth Module
|
|
738
|
+
*
|
|
739
|
+
* All authentication functionality in one place:
|
|
740
|
+
* - Auth provider interfaces and implementations
|
|
741
|
+
* - Auth API and service logic
|
|
742
|
+
* - Token management
|
|
743
|
+
*/
|
|
744
|
+
// Auth provider interfaces and implementations
|
|
745
|
+
/**
|
|
746
|
+
* Create a complete Auth SDK instance (for backward compatibility)
|
|
747
|
+
* Note: This is now handled directly by PersApiClient
|
|
748
|
+
*
|
|
749
|
+
* @param apiClient - Configured PERS API client
|
|
750
|
+
* @param authProvider - Optional auth provider. If not provided, uses SimpleSdkAuthProvider
|
|
751
|
+
* @returns Auth SDK with flattened structure for better DX
|
|
752
|
+
*/
|
|
753
|
+
function createAuthSDK(apiClient, authProvider) {
|
|
754
|
+
// Use simple internal auth provider if none provided
|
|
755
|
+
const provider = authProvider || new SimpleSdkAuthProvider();
|
|
756
|
+
const authApi = new AuthApi(apiClient);
|
|
757
|
+
const authService = new AuthService(authApi, provider);
|
|
758
|
+
return {
|
|
759
|
+
// Direct access to service methods (primary interface)
|
|
760
|
+
// Admin authentication methods
|
|
761
|
+
loginTenantAdmin: (jwt) => authService.loginTenantAdmin(jwt),
|
|
762
|
+
loginUser: (jwt) => authService.loginUser(jwt),
|
|
763
|
+
refreshAccessToken: (refreshToken) => authService.refreshAccessToken(refreshToken),
|
|
764
|
+
clearTokens: () => authService.clearTokens(),
|
|
765
|
+
// Auth provider access for external integration
|
|
766
|
+
getAuthProvider: () => provider,
|
|
767
|
+
hasValidToken: () => provider.hasValidToken?.() || false,
|
|
768
|
+
// Advanced access for edge cases
|
|
769
|
+
api: authApi,
|
|
770
|
+
service: authService
|
|
771
|
+
};
|
|
772
|
+
}
|
|
773
|
+
|
|
469
774
|
/**
|
|
470
775
|
* PERS SDK - Minimal platform-agnostic client with built-in authentication
|
|
471
776
|
* Authentication is now handled at the SDK core level for better scalability
|
|
@@ -1263,113 +1568,6 @@ function createAnalyticsSDK(apiClient) {
|
|
|
1263
1568
|
};
|
|
1264
1569
|
}
|
|
1265
1570
|
|
|
1266
|
-
/**
|
|
1267
|
-
* Platform-Agnostic Auth Admin API Client
|
|
1268
|
-
*
|
|
1269
|
-
* Handles authentication and authorization admin operations using the PERS backend.
|
|
1270
|
-
* Uses @explorins/pers-shared DTOs for consistency with backend.
|
|
1271
|
-
*
|
|
1272
|
-
* Note: Special header handling (bypass-auth-interceptor) may need to be implemented
|
|
1273
|
-
* at the PersApiClient level or through a specialized auth client.
|
|
1274
|
-
*/
|
|
1275
|
-
class AuthAdminApi {
|
|
1276
|
-
constructor(apiClient) {
|
|
1277
|
-
this.apiClient = apiClient;
|
|
1278
|
-
this.basePath = '/auth';
|
|
1279
|
-
}
|
|
1280
|
-
// ==========================================
|
|
1281
|
-
// ADMIN AUTHENTICATION OPERATIONS
|
|
1282
|
-
// ==========================================
|
|
1283
|
-
/**
|
|
1284
|
-
* ADMIN: Login tenant admin with JWT
|
|
1285
|
-
* Note: JWT handling and auth bypass headers may need special implementation
|
|
1286
|
-
*/
|
|
1287
|
-
async loginTenantAdmin(jwt) {
|
|
1288
|
-
const body = {
|
|
1289
|
-
authToken: jwt,
|
|
1290
|
-
authType: AccountOwnerType.TENANT
|
|
1291
|
-
};
|
|
1292
|
-
return this.apiClient.post(`${this.basePath}/token`, body);
|
|
1293
|
-
}
|
|
1294
|
-
async loginUser(jwt) {
|
|
1295
|
-
const body = {
|
|
1296
|
-
authToken: jwt,
|
|
1297
|
-
authType: AccountOwnerType.USER
|
|
1298
|
-
};
|
|
1299
|
-
return this.apiClient.post(`${this.basePath}/token`, body);
|
|
1300
|
-
}
|
|
1301
|
-
/**
|
|
1302
|
-
* ADMIN: Refresh access token
|
|
1303
|
-
* Note: Bypass header handling may need special implementation
|
|
1304
|
-
*/
|
|
1305
|
-
async refreshAccessToken(refreshToken) {
|
|
1306
|
-
return this.apiClient.post(`${this.basePath}/refresh`, { refreshToken });
|
|
1307
|
-
}
|
|
1308
|
-
}
|
|
1309
|
-
|
|
1310
|
-
/**
|
|
1311
|
-
* Platform-Agnostic Auth Admin Service
|
|
1312
|
-
*
|
|
1313
|
-
* Contains auth admin business logic and operations that work across platforms.
|
|
1314
|
-
* No framework dependencies - pure TypeScript business logic.
|
|
1315
|
-
*
|
|
1316
|
-
* Focuses only on actual backend capabilities.
|
|
1317
|
-
*/
|
|
1318
|
-
class AuthAdminService {
|
|
1319
|
-
constructor(authAdminApi) {
|
|
1320
|
-
this.authAdminApi = authAdminApi;
|
|
1321
|
-
}
|
|
1322
|
-
// ==========================================
|
|
1323
|
-
// ADMIN AUTHENTICATION OPERATIONS
|
|
1324
|
-
// ==========================================
|
|
1325
|
-
/**
|
|
1326
|
-
* ADMIN: Login tenant admin with JWT
|
|
1327
|
-
*/
|
|
1328
|
-
async loginTenantAdmin(jwt) {
|
|
1329
|
-
return this.authAdminApi.loginTenantAdmin(jwt);
|
|
1330
|
-
}
|
|
1331
|
-
/**
|
|
1332
|
-
* ADMIN: Login user with JWT
|
|
1333
|
-
*/
|
|
1334
|
-
async loginUser(jwt) {
|
|
1335
|
-
return this.authAdminApi.loginUser(jwt);
|
|
1336
|
-
}
|
|
1337
|
-
/**
|
|
1338
|
-
* ADMIN: Refresh access token
|
|
1339
|
-
*/
|
|
1340
|
-
async refreshAccessToken(refreshToken) {
|
|
1341
|
-
return this.authAdminApi.refreshAccessToken(refreshToken);
|
|
1342
|
-
}
|
|
1343
|
-
}
|
|
1344
|
-
|
|
1345
|
-
/**
|
|
1346
|
-
* @explorins/pers-sdk-auth-admin
|
|
1347
|
-
*
|
|
1348
|
-
* Platform-agnostic Auth Admin Domain SDK for PERS ecosystem
|
|
1349
|
-
* Handles authentication and authorization admin operations
|
|
1350
|
-
*/
|
|
1351
|
-
// API Layer
|
|
1352
|
-
/**
|
|
1353
|
-
* Create a complete Auth Admin SDK instance
|
|
1354
|
-
*
|
|
1355
|
-
* @param apiClient - Configured PERS API client
|
|
1356
|
-
* @returns Auth Admin SDK with flattened structure for better DX
|
|
1357
|
-
*/
|
|
1358
|
-
function createAuthAdminSDK(apiClient) {
|
|
1359
|
-
const authAdminApi = new AuthAdminApi(apiClient);
|
|
1360
|
-
const authAdminService = new AuthAdminService(authAdminApi);
|
|
1361
|
-
return {
|
|
1362
|
-
// Direct access to service methods (primary interface)
|
|
1363
|
-
// Admin authentication methods
|
|
1364
|
-
loginTenantAdmin: (jwt) => authAdminService.loginTenantAdmin(jwt),
|
|
1365
|
-
loginUser: (jwt) => authAdminService.loginUser(jwt),
|
|
1366
|
-
refreshAccessToken: (refreshToken) => authAdminService.refreshAccessToken(refreshToken),
|
|
1367
|
-
// Advanced access for edge cases
|
|
1368
|
-
api: authAdminApi,
|
|
1369
|
-
service: authAdminService
|
|
1370
|
-
};
|
|
1371
|
-
}
|
|
1372
|
-
|
|
1373
1571
|
/**
|
|
1374
1572
|
* Platform-Agnostic Campaign API Client (NEW - RESTful Design)
|
|
1375
1573
|
*
|
|
@@ -2238,29 +2436,22 @@ class RedemptionApi {
|
|
|
2238
2436
|
// PUBLIC OPERATIONS (Project Key)
|
|
2239
2437
|
// ==========================================
|
|
2240
2438
|
/**
|
|
2241
|
-
*
|
|
2439
|
+
* UNIFIED: Get redemptions with intelligent access control
|
|
2242
2440
|
*
|
|
2243
|
-
*
|
|
2441
|
+
* Intelligent endpoint that adapts based on authentication:
|
|
2244
2442
|
* - Public users: Get active redemptions only
|
|
2245
2443
|
* - Admin users: Get all redemptions with optional filtering
|
|
2246
2444
|
*
|
|
2247
|
-
*
|
|
2445
|
+
* @param options.active - Filter by active status (undefined = all for admins/active for public)
|
|
2446
|
+
* @param options.adminAccess - Force admin access (requires admin auth)
|
|
2248
2447
|
*/
|
|
2249
|
-
async getRedemptions(
|
|
2448
|
+
async getRedemptions(options) {
|
|
2250
2449
|
let url = `${this.basePath}`;
|
|
2251
|
-
if (active !== undefined) {
|
|
2252
|
-
url += `?active=${active}`;
|
|
2450
|
+
if (options?.active !== undefined) {
|
|
2451
|
+
url += `?active=${options.active}`;
|
|
2253
2452
|
}
|
|
2254
2453
|
return this.apiClient.get(url);
|
|
2255
2454
|
}
|
|
2256
|
-
/**
|
|
2257
|
-
* PUBLIC: Get active redemptions
|
|
2258
|
-
*
|
|
2259
|
-
* Updated: Now uses unified endpoint (backward compatibility)
|
|
2260
|
-
*/
|
|
2261
|
-
async getActiveRedemptions() {
|
|
2262
|
-
return this.getRedemptions(); // Will return active only for public access
|
|
2263
|
-
}
|
|
2264
2455
|
/**
|
|
2265
2456
|
* PUBLIC: Get redemption types
|
|
2266
2457
|
*
|
|
@@ -2306,12 +2497,27 @@ class RedemptionApi {
|
|
|
2306
2497
|
// REDEMPTION REDEEMS QUERIES (NEW ENDPOINTS)
|
|
2307
2498
|
// ==========================================
|
|
2308
2499
|
/**
|
|
2309
|
-
* Get redemption redeems with filtering
|
|
2500
|
+
* UNIFIED: Get redemption redeems with filtering and intelligent access
|
|
2310
2501
|
*
|
|
2311
|
-
*
|
|
2312
|
-
*
|
|
2502
|
+
* Role-based access with unified filtering:
|
|
2503
|
+
* - Users: See only their own redeems (userId/businessId filters ignored)
|
|
2504
|
+
* - Admins: Can filter by userId, businessId, or redemptionId
|
|
2505
|
+
*
|
|
2506
|
+
* @param filters.redemptionId - Filter by specific redemption
|
|
2507
|
+
* @param filters.userId - Admin only: Filter by user ID
|
|
2508
|
+
* @param filters.businessId - Admin only: Filter by business ID
|
|
2509
|
+
* @param filters.myRedeems - Force user's own redeems (uses /me endpoint)
|
|
2313
2510
|
*/
|
|
2314
2511
|
async getRedemptionRedeems(filters) {
|
|
2512
|
+
// Use convenience endpoint for user's own redeems
|
|
2513
|
+
if (filters?.myRedeems) {
|
|
2514
|
+
let url = `${this.redeemsPath}/me`;
|
|
2515
|
+
if (filters.redemptionId) {
|
|
2516
|
+
url += `?redemptionId=${filters.redemptionId}`;
|
|
2517
|
+
}
|
|
2518
|
+
return this.apiClient.get(url);
|
|
2519
|
+
}
|
|
2520
|
+
// Use admin endpoint with filtering
|
|
2315
2521
|
let url = this.redeemsPath;
|
|
2316
2522
|
const params = new URLSearchParams();
|
|
2317
2523
|
if (filters?.redemptionId)
|
|
@@ -2327,67 +2533,22 @@ class RedemptionApi {
|
|
|
2327
2533
|
return this.apiClient.get(url);
|
|
2328
2534
|
}
|
|
2329
2535
|
/**
|
|
2330
|
-
* Get specific redemption redeem by ID
|
|
2331
|
-
*
|
|
2332
|
-
* NEW: GET /redemption-redeems/:id
|
|
2536
|
+
* UNIFIED: Get specific redemption redeem by ID
|
|
2333
2537
|
*/
|
|
2334
2538
|
async getRedemptionRedeemById(id) {
|
|
2335
2539
|
return this.apiClient.get(`${this.redeemsPath}/${id}`);
|
|
2336
2540
|
}
|
|
2337
|
-
/**
|
|
2338
|
-
* USER: Get my redemption redeems (convenience endpoint)
|
|
2339
|
-
*
|
|
2340
|
-
* NEW: GET /redemption-redeems/me with optional filtering
|
|
2341
|
-
*/
|
|
2342
|
-
async getMyRedemptionRedeems(redemptionId) {
|
|
2343
|
-
let url = `${this.redeemsPath}/me`;
|
|
2344
|
-
if (redemptionId) {
|
|
2345
|
-
url += `?redemptionId=${redemptionId}`;
|
|
2346
|
-
}
|
|
2347
|
-
return this.apiClient.get(url);
|
|
2348
|
-
}
|
|
2349
|
-
/**
|
|
2350
|
-
* ADMIN: Get redemption redeems by user ID
|
|
2351
|
-
*
|
|
2352
|
-
* NEW: GET /redemption-redeems?userId=X
|
|
2353
|
-
*/
|
|
2354
|
-
async getRedemptionRedeemsByUserId(userId, redemptionId) {
|
|
2355
|
-
return this.getRedemptionRedeems({ userId, redemptionId });
|
|
2356
|
-
}
|
|
2357
|
-
/**
|
|
2358
|
-
* ADMIN: Get redemption redeems by business ID
|
|
2359
|
-
*
|
|
2360
|
-
* NEW: GET /redemption-redeems?businessId=X
|
|
2361
|
-
*/
|
|
2362
|
-
async getRedemptionRedeemsByBusinessId(businessId, redemptionId) {
|
|
2363
|
-
return this.getRedemptionRedeems({ businessId, redemptionId });
|
|
2364
|
-
}
|
|
2365
|
-
/**
|
|
2366
|
-
* ADMIN: Get redemption redeems by redemption ID
|
|
2367
|
-
*
|
|
2368
|
-
* NEW: GET /redemption-redeems?redemptionId=X
|
|
2369
|
-
*/
|
|
2370
|
-
async getRedemptionRedeemsByRedemptionId(redemptionId) {
|
|
2371
|
-
return this.getRedemptionRedeems({ redemptionId });
|
|
2372
|
-
}
|
|
2373
2541
|
// ==========================================
|
|
2374
2542
|
// USER OPERATIONS (JWT + Project Key)
|
|
2375
2543
|
// ==========================================
|
|
2376
2544
|
/**
|
|
2377
|
-
*
|
|
2378
|
-
*
|
|
2379
|
-
* Updated: Uses new convenience endpoint /redemption-redeems/me
|
|
2380
|
-
*/
|
|
2381
|
-
async getUserRedemptionHistory() {
|
|
2382
|
-
return this.getMyRedemptionRedeems();
|
|
2383
|
-
}
|
|
2384
|
-
/**
|
|
2385
|
-
* USER: Get user redemptions (backward compatibility)
|
|
2545
|
+
* UNIFIED: Get user redemption history
|
|
2386
2546
|
*
|
|
2387
|
-
*
|
|
2547
|
+
* Uses convenience endpoint /redemption-redeems/me with optional filtering
|
|
2548
|
+
* @param redemptionId - Optional filter by specific redemption
|
|
2388
2549
|
*/
|
|
2389
|
-
async getUserRedeems() {
|
|
2390
|
-
return this.
|
|
2550
|
+
async getUserRedeems(redemptionId) {
|
|
2551
|
+
return this.getRedemptionRedeems({ myRedeems: true, redemptionId });
|
|
2391
2552
|
}
|
|
2392
2553
|
// ==========================================
|
|
2393
2554
|
// ADMIN OPERATIONS (Tenant Admin JWT)
|
|
@@ -2399,7 +2560,7 @@ class RedemptionApi {
|
|
|
2399
2560
|
* The unified endpoint will detect admin privileges and allow filtering
|
|
2400
2561
|
*/
|
|
2401
2562
|
async getRedemptionsAsAdmin(active) {
|
|
2402
|
-
return this.getRedemptions(active
|
|
2563
|
+
return this.getRedemptions({ active, adminAccess: true });
|
|
2403
2564
|
}
|
|
2404
2565
|
/**
|
|
2405
2566
|
* ADMIN: Create redemption
|
|
@@ -2418,21 +2579,13 @@ class RedemptionApi {
|
|
|
2418
2579
|
return this.apiClient.put(`${this.basePath}/${id}`, redemptionCreateRequest);
|
|
2419
2580
|
}
|
|
2420
2581
|
/**
|
|
2421
|
-
*
|
|
2582
|
+
* UNIFIED: Toggle redemption active status
|
|
2422
2583
|
*
|
|
2423
2584
|
* Updated: /redemption/admin/:id/toggle-active → /redemptions/:id/status
|
|
2424
2585
|
* Following standard /status pattern used across domains
|
|
2425
2586
|
*/
|
|
2426
|
-
async toggleRedemptionStatus(redemptionId) {
|
|
2427
|
-
return this.apiClient.put(`${this.basePath}/${redemptionId}/status`, {});
|
|
2428
|
-
}
|
|
2429
|
-
/**
|
|
2430
|
-
* ADMIN: Toggle redemption active (backward compatibility)
|
|
2431
|
-
*
|
|
2432
|
-
* Deprecated: Use toggleRedemptionStatus() instead
|
|
2433
|
-
*/
|
|
2434
2587
|
async toggleRedemptionActive(redemptionId) {
|
|
2435
|
-
return this.
|
|
2588
|
+
return this.apiClient.put(`${this.basePath}/${redemptionId}/status`, {});
|
|
2436
2589
|
}
|
|
2437
2590
|
/**
|
|
2438
2591
|
* ADMIN: Delete redemption
|
|
@@ -2478,21 +2631,13 @@ class RedemptionApi {
|
|
|
2478
2631
|
return this.apiClient.delete(`${this.basePath}/${redemptionId}/token-units/${redemptionTokenUnitId}`);
|
|
2479
2632
|
}
|
|
2480
2633
|
// ==========================================
|
|
2481
|
-
//
|
|
2634
|
+
// CONVENIENCE METHODS (Legacy Support)
|
|
2482
2635
|
// ==========================================
|
|
2483
2636
|
/**
|
|
2484
|
-
*
|
|
2485
|
-
* Backward compatibility for old admin endpoint
|
|
2637
|
+
* Convenience: Get active redemptions (public access)
|
|
2486
2638
|
*/
|
|
2487
|
-
async
|
|
2488
|
-
return this.
|
|
2489
|
-
}
|
|
2490
|
-
/**
|
|
2491
|
-
* @deprecated Use redeemRedemption() instead
|
|
2492
|
-
* Backward compatibility for old redeem method
|
|
2493
|
-
*/
|
|
2494
|
-
async redeem(redemptionId) {
|
|
2495
|
-
return this.redeemRedemption(redemptionId);
|
|
2639
|
+
async getActiveRedemptions() {
|
|
2640
|
+
return this.getRedemptions({ active: true });
|
|
2496
2641
|
}
|
|
2497
2642
|
}
|
|
2498
2643
|
|
|
@@ -2512,7 +2657,15 @@ class RedemptionService {
|
|
|
2512
2657
|
// PUBLIC OPERATIONS
|
|
2513
2658
|
// ==========================================
|
|
2514
2659
|
/**
|
|
2515
|
-
*
|
|
2660
|
+
* UNIFIED: Get redemptions with intelligent access control
|
|
2661
|
+
* @param options.active - Filter by active status
|
|
2662
|
+
* @param options.adminAccess - Force admin access
|
|
2663
|
+
*/
|
|
2664
|
+
async getRedemptions(options) {
|
|
2665
|
+
return this.redemptionApi.getRedemptions(options);
|
|
2666
|
+
}
|
|
2667
|
+
/**
|
|
2668
|
+
* Convenience: Get active redemptions (public)
|
|
2516
2669
|
*/
|
|
2517
2670
|
async getActiveRedemptions() {
|
|
2518
2671
|
return this.redemptionApi.getActiveRedemptions();
|
|
@@ -2533,7 +2686,13 @@ class RedemptionService {
|
|
|
2533
2686
|
return this.redemptionApi.redeemRedemption(redemptionId);
|
|
2534
2687
|
}
|
|
2535
2688
|
/**
|
|
2536
|
-
*
|
|
2689
|
+
* UNIFIED: Get redemption redeems with filtering
|
|
2690
|
+
*/
|
|
2691
|
+
async getRedemptionRedeems(filters) {
|
|
2692
|
+
return this.redemptionApi.getRedemptionRedeems(filters);
|
|
2693
|
+
}
|
|
2694
|
+
/**
|
|
2695
|
+
* Convenience: Get user redemptions
|
|
2537
2696
|
*/
|
|
2538
2697
|
async getUserRedeems() {
|
|
2539
2698
|
return this.redemptionApi.getUserRedeems();
|
|
@@ -2542,7 +2701,7 @@ class RedemptionService {
|
|
|
2542
2701
|
// ADMIN OPERATIONS
|
|
2543
2702
|
// ==========================================
|
|
2544
2703
|
/**
|
|
2545
|
-
*
|
|
2704
|
+
* Convenience: Get redemptions as admin
|
|
2546
2705
|
*/
|
|
2547
2706
|
async getRedemptionsAsAdmin(active) {
|
|
2548
2707
|
return this.redemptionApi.getRedemptionsAsAdmin(active);
|
|
@@ -4696,5 +4855,5 @@ function createWeb3SDK(apiClient) {
|
|
|
4696
4855
|
};
|
|
4697
4856
|
}
|
|
4698
4857
|
|
|
4699
|
-
export { AnalyticsApi, AnalyticsService,
|
|
4858
|
+
export { AnalyticsApi, AnalyticsService, AuthApi, AuthService, BaseTokenService, BusinessApi, BusinessService, CampaignApi, CampaignService, ChainTypes, DEFAULT_PERS_CONFIG, DonationApi, DonationService, IPFSInfrastructureApi, PurchaseApi as PaymentApi, PaymentService, PersApiClient, PersApiError, PersSDK, RedemptionApi, RedemptionService, SimpleSdkAuthProvider, TenantApi, TenantService, TokenApi, TokenSDK, TokenService, TransactionAccountType, TransactionApi, TransactionService, UserApi, UserService, UserStatusApi, UserStatusService, Web3ApplicationService, Web3ChainApi, Web3ChainService, Web3InfrastructureApi, Web3ProviderService, buildApiRoot, createAnalyticsSDK, createAuthProvider, createAuthSDK, createBusinessSDK, createCampaignSDK, createDonationSDK, createPaymentSDK, createPersSDK, createRedemptionSDK, createTenantSDK, createTransactionSDK, createUserSDK, createUserStatusSDK, createWeb3ChainSDK, createWeb3SDK, mergeWithDefaults };
|
|
4700
4859
|
//# sourceMappingURL=index.js.map
|