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