@explorins/pers-sdk 1.2.4 → 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 -7
- 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 -346
- 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 -345
- 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 -26
- package/dist/auth-admin/index.d.ts.map +0 -1
- package/dist/auth-admin/services/auth-admin-service.d.ts +0 -23
- package/dist/auth-admin/services/auth-admin-service.d.ts.map +0 -1
- package/dist/auth-admin.cjs +0 -101
- package/dist/auth-admin.cjs.map +0 -1
- package/dist/auth-admin.js +0 -97
- 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,99 +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
|
-
/**
|
|
1297
|
-
* ADMIN: Refresh access token
|
|
1298
|
-
* Note: Bypass header handling may need special implementation
|
|
1299
|
-
*/
|
|
1300
|
-
async refreshAccessToken(refreshToken) {
|
|
1301
|
-
return this.apiClient.post(`${this.basePath}/refresh`, { refreshToken });
|
|
1302
|
-
}
|
|
1303
|
-
}
|
|
1304
|
-
|
|
1305
|
-
/**
|
|
1306
|
-
* Platform-Agnostic Auth Admin Service
|
|
1307
|
-
*
|
|
1308
|
-
* Contains auth admin business logic and operations that work across platforms.
|
|
1309
|
-
* No framework dependencies - pure TypeScript business logic.
|
|
1310
|
-
*
|
|
1311
|
-
* Focuses only on actual backend capabilities.
|
|
1312
|
-
*/
|
|
1313
|
-
class AuthAdminService {
|
|
1314
|
-
constructor(authAdminApi) {
|
|
1315
|
-
this.authAdminApi = authAdminApi;
|
|
1316
|
-
}
|
|
1317
|
-
// ==========================================
|
|
1318
|
-
// ADMIN AUTHENTICATION OPERATIONS
|
|
1319
|
-
// ==========================================
|
|
1320
|
-
/**
|
|
1321
|
-
* ADMIN: Login tenant admin with JWT
|
|
1322
|
-
*/
|
|
1323
|
-
async loginTenantAdmin(jwt) {
|
|
1324
|
-
return this.authAdminApi.loginTenantAdmin(jwt);
|
|
1325
|
-
}
|
|
1326
|
-
/**
|
|
1327
|
-
* ADMIN: Refresh access token
|
|
1328
|
-
*/
|
|
1329
|
-
async refreshAccessToken(refreshToken) {
|
|
1330
|
-
return this.authAdminApi.refreshAccessToken(refreshToken);
|
|
1331
|
-
}
|
|
1332
|
-
}
|
|
1333
|
-
|
|
1334
|
-
/**
|
|
1335
|
-
* @explorins/pers-sdk-auth-admin
|
|
1336
|
-
*
|
|
1337
|
-
* Platform-agnostic Auth Admin Domain SDK for PERS ecosystem
|
|
1338
|
-
* Handles authentication and authorization admin operations
|
|
1339
|
-
*/
|
|
1340
|
-
// API Layer
|
|
1341
|
-
/**
|
|
1342
|
-
* Create a complete Auth Admin SDK instance
|
|
1343
|
-
*
|
|
1344
|
-
* @param apiClient - Configured PERS API client
|
|
1345
|
-
* @returns Auth Admin SDK with flattened structure for better DX
|
|
1346
|
-
*/
|
|
1347
|
-
function createAuthAdminSDK(apiClient) {
|
|
1348
|
-
const authAdminApi = new AuthAdminApi(apiClient);
|
|
1349
|
-
const authAdminService = new AuthAdminService(authAdminApi);
|
|
1350
|
-
return {
|
|
1351
|
-
// Direct access to service methods (primary interface)
|
|
1352
|
-
// Admin authentication methods
|
|
1353
|
-
loginTenantAdmin: (jwt) => authAdminService.loginTenantAdmin(jwt),
|
|
1354
|
-
refreshAccessToken: (refreshToken) => authAdminService.refreshAccessToken(refreshToken),
|
|
1355
|
-
// Advanced access for edge cases
|
|
1356
|
-
api: authAdminApi,
|
|
1357
|
-
service: authAdminService
|
|
1358
|
-
};
|
|
1359
|
-
}
|
|
1360
|
-
|
|
1361
1572
|
/**
|
|
1362
1573
|
* Platform-Agnostic Campaign API Client (NEW - RESTful Design)
|
|
1363
1574
|
*
|
|
@@ -2226,29 +2437,22 @@ class RedemptionApi {
|
|
|
2226
2437
|
// PUBLIC OPERATIONS (Project Key)
|
|
2227
2438
|
// ==========================================
|
|
2228
2439
|
/**
|
|
2229
|
-
*
|
|
2440
|
+
* UNIFIED: Get redemptions with intelligent access control
|
|
2230
2441
|
*
|
|
2231
|
-
*
|
|
2442
|
+
* Intelligent endpoint that adapts based on authentication:
|
|
2232
2443
|
* - Public users: Get active redemptions only
|
|
2233
2444
|
* - Admin users: Get all redemptions with optional filtering
|
|
2234
2445
|
*
|
|
2235
|
-
*
|
|
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)
|
|
2236
2448
|
*/
|
|
2237
|
-
async getRedemptions(
|
|
2449
|
+
async getRedemptions(options) {
|
|
2238
2450
|
let url = `${this.basePath}`;
|
|
2239
|
-
if (active !== undefined) {
|
|
2240
|
-
url += `?active=${active}`;
|
|
2451
|
+
if (options?.active !== undefined) {
|
|
2452
|
+
url += `?active=${options.active}`;
|
|
2241
2453
|
}
|
|
2242
2454
|
return this.apiClient.get(url);
|
|
2243
2455
|
}
|
|
2244
|
-
/**
|
|
2245
|
-
* PUBLIC: Get active redemptions
|
|
2246
|
-
*
|
|
2247
|
-
* Updated: Now uses unified endpoint (backward compatibility)
|
|
2248
|
-
*/
|
|
2249
|
-
async getActiveRedemptions() {
|
|
2250
|
-
return this.getRedemptions(); // Will return active only for public access
|
|
2251
|
-
}
|
|
2252
2456
|
/**
|
|
2253
2457
|
* PUBLIC: Get redemption types
|
|
2254
2458
|
*
|
|
@@ -2294,12 +2498,27 @@ class RedemptionApi {
|
|
|
2294
2498
|
// REDEMPTION REDEEMS QUERIES (NEW ENDPOINTS)
|
|
2295
2499
|
// ==========================================
|
|
2296
2500
|
/**
|
|
2297
|
-
* Get redemption redeems with filtering
|
|
2501
|
+
* UNIFIED: Get redemption redeems with filtering and intelligent access
|
|
2502
|
+
*
|
|
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
|
|
2298
2506
|
*
|
|
2299
|
-
*
|
|
2300
|
-
*
|
|
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)
|
|
2301
2511
|
*/
|
|
2302
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
|
|
2303
2522
|
let url = this.redeemsPath;
|
|
2304
2523
|
const params = new URLSearchParams();
|
|
2305
2524
|
if (filters?.redemptionId)
|
|
@@ -2315,67 +2534,22 @@ class RedemptionApi {
|
|
|
2315
2534
|
return this.apiClient.get(url);
|
|
2316
2535
|
}
|
|
2317
2536
|
/**
|
|
2318
|
-
* Get specific redemption redeem by ID
|
|
2319
|
-
*
|
|
2320
|
-
* NEW: GET /redemption-redeems/:id
|
|
2537
|
+
* UNIFIED: Get specific redemption redeem by ID
|
|
2321
2538
|
*/
|
|
2322
2539
|
async getRedemptionRedeemById(id) {
|
|
2323
2540
|
return this.apiClient.get(`${this.redeemsPath}/${id}`);
|
|
2324
2541
|
}
|
|
2325
|
-
/**
|
|
2326
|
-
* USER: Get my redemption redeems (convenience endpoint)
|
|
2327
|
-
*
|
|
2328
|
-
* NEW: GET /redemption-redeems/me with optional filtering
|
|
2329
|
-
*/
|
|
2330
|
-
async getMyRedemptionRedeems(redemptionId) {
|
|
2331
|
-
let url = `${this.redeemsPath}/me`;
|
|
2332
|
-
if (redemptionId) {
|
|
2333
|
-
url += `?redemptionId=${redemptionId}`;
|
|
2334
|
-
}
|
|
2335
|
-
return this.apiClient.get(url);
|
|
2336
|
-
}
|
|
2337
|
-
/**
|
|
2338
|
-
* ADMIN: Get redemption redeems by user ID
|
|
2339
|
-
*
|
|
2340
|
-
* NEW: GET /redemption-redeems?userId=X
|
|
2341
|
-
*/
|
|
2342
|
-
async getRedemptionRedeemsByUserId(userId, redemptionId) {
|
|
2343
|
-
return this.getRedemptionRedeems({ userId, redemptionId });
|
|
2344
|
-
}
|
|
2345
|
-
/**
|
|
2346
|
-
* ADMIN: Get redemption redeems by business ID
|
|
2347
|
-
*
|
|
2348
|
-
* NEW: GET /redemption-redeems?businessId=X
|
|
2349
|
-
*/
|
|
2350
|
-
async getRedemptionRedeemsByBusinessId(businessId, redemptionId) {
|
|
2351
|
-
return this.getRedemptionRedeems({ businessId, redemptionId });
|
|
2352
|
-
}
|
|
2353
|
-
/**
|
|
2354
|
-
* ADMIN: Get redemption redeems by redemption ID
|
|
2355
|
-
*
|
|
2356
|
-
* NEW: GET /redemption-redeems?redemptionId=X
|
|
2357
|
-
*/
|
|
2358
|
-
async getRedemptionRedeemsByRedemptionId(redemptionId) {
|
|
2359
|
-
return this.getRedemptionRedeems({ redemptionId });
|
|
2360
|
-
}
|
|
2361
2542
|
// ==========================================
|
|
2362
2543
|
// USER OPERATIONS (JWT + Project Key)
|
|
2363
2544
|
// ==========================================
|
|
2364
2545
|
/**
|
|
2365
|
-
*
|
|
2546
|
+
* UNIFIED: Get user redemption history
|
|
2366
2547
|
*
|
|
2367
|
-
*
|
|
2548
|
+
* Uses convenience endpoint /redemption-redeems/me with optional filtering
|
|
2549
|
+
* @param redemptionId - Optional filter by specific redemption
|
|
2368
2550
|
*/
|
|
2369
|
-
async
|
|
2370
|
-
return this.
|
|
2371
|
-
}
|
|
2372
|
-
/**
|
|
2373
|
-
* USER: Get user redemptions (backward compatibility)
|
|
2374
|
-
*
|
|
2375
|
-
* Deprecated: Use getUserRedemptionHistory() instead
|
|
2376
|
-
*/
|
|
2377
|
-
async getUserRedeems() {
|
|
2378
|
-
return this.getUserRedemptionHistory();
|
|
2551
|
+
async getUserRedeems(redemptionId) {
|
|
2552
|
+
return this.getRedemptionRedeems({ myRedeems: true, redemptionId });
|
|
2379
2553
|
}
|
|
2380
2554
|
// ==========================================
|
|
2381
2555
|
// ADMIN OPERATIONS (Tenant Admin JWT)
|
|
@@ -2387,7 +2561,7 @@ class RedemptionApi {
|
|
|
2387
2561
|
* The unified endpoint will detect admin privileges and allow filtering
|
|
2388
2562
|
*/
|
|
2389
2563
|
async getRedemptionsAsAdmin(active) {
|
|
2390
|
-
return this.getRedemptions(active
|
|
2564
|
+
return this.getRedemptions({ active, adminAccess: true });
|
|
2391
2565
|
}
|
|
2392
2566
|
/**
|
|
2393
2567
|
* ADMIN: Create redemption
|
|
@@ -2406,21 +2580,13 @@ class RedemptionApi {
|
|
|
2406
2580
|
return this.apiClient.put(`${this.basePath}/${id}`, redemptionCreateRequest);
|
|
2407
2581
|
}
|
|
2408
2582
|
/**
|
|
2409
|
-
*
|
|
2583
|
+
* UNIFIED: Toggle redemption active status
|
|
2410
2584
|
*
|
|
2411
2585
|
* Updated: /redemption/admin/:id/toggle-active → /redemptions/:id/status
|
|
2412
2586
|
* Following standard /status pattern used across domains
|
|
2413
2587
|
*/
|
|
2414
|
-
async toggleRedemptionStatus(redemptionId) {
|
|
2415
|
-
return this.apiClient.put(`${this.basePath}/${redemptionId}/status`, {});
|
|
2416
|
-
}
|
|
2417
|
-
/**
|
|
2418
|
-
* ADMIN: Toggle redemption active (backward compatibility)
|
|
2419
|
-
*
|
|
2420
|
-
* Deprecated: Use toggleRedemptionStatus() instead
|
|
2421
|
-
*/
|
|
2422
2588
|
async toggleRedemptionActive(redemptionId) {
|
|
2423
|
-
return this.
|
|
2589
|
+
return this.apiClient.put(`${this.basePath}/${redemptionId}/status`, {});
|
|
2424
2590
|
}
|
|
2425
2591
|
/**
|
|
2426
2592
|
* ADMIN: Delete redemption
|
|
@@ -2466,21 +2632,13 @@ class RedemptionApi {
|
|
|
2466
2632
|
return this.apiClient.delete(`${this.basePath}/${redemptionId}/token-units/${redemptionTokenUnitId}`);
|
|
2467
2633
|
}
|
|
2468
2634
|
// ==========================================
|
|
2469
|
-
//
|
|
2635
|
+
// CONVENIENCE METHODS (Legacy Support)
|
|
2470
2636
|
// ==========================================
|
|
2471
2637
|
/**
|
|
2472
|
-
*
|
|
2473
|
-
* Backward compatibility for old admin endpoint
|
|
2638
|
+
* Convenience: Get active redemptions (public access)
|
|
2474
2639
|
*/
|
|
2475
|
-
async
|
|
2476
|
-
return this.
|
|
2477
|
-
}
|
|
2478
|
-
/**
|
|
2479
|
-
* @deprecated Use redeemRedemption() instead
|
|
2480
|
-
* Backward compatibility for old redeem method
|
|
2481
|
-
*/
|
|
2482
|
-
async redeem(redemptionId) {
|
|
2483
|
-
return this.redeemRedemption(redemptionId);
|
|
2640
|
+
async getActiveRedemptions() {
|
|
2641
|
+
return this.getRedemptions({ active: true });
|
|
2484
2642
|
}
|
|
2485
2643
|
}
|
|
2486
2644
|
|
|
@@ -2500,7 +2658,15 @@ class RedemptionService {
|
|
|
2500
2658
|
// PUBLIC OPERATIONS
|
|
2501
2659
|
// ==========================================
|
|
2502
2660
|
/**
|
|
2503
|
-
*
|
|
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)
|
|
2504
2670
|
*/
|
|
2505
2671
|
async getActiveRedemptions() {
|
|
2506
2672
|
return this.redemptionApi.getActiveRedemptions();
|
|
@@ -2521,7 +2687,13 @@ class RedemptionService {
|
|
|
2521
2687
|
return this.redemptionApi.redeemRedemption(redemptionId);
|
|
2522
2688
|
}
|
|
2523
2689
|
/**
|
|
2524
|
-
*
|
|
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
|
|
2525
2697
|
*/
|
|
2526
2698
|
async getUserRedeems() {
|
|
2527
2699
|
return this.redemptionApi.getUserRedeems();
|
|
@@ -2530,7 +2702,7 @@ class RedemptionService {
|
|
|
2530
2702
|
// ADMIN OPERATIONS
|
|
2531
2703
|
// ==========================================
|
|
2532
2704
|
/**
|
|
2533
|
-
*
|
|
2705
|
+
* Convenience: Get redemptions as admin
|
|
2534
2706
|
*/
|
|
2535
2707
|
async getRedemptionsAsAdmin(active) {
|
|
2536
2708
|
return this.redemptionApi.getRedemptionsAsAdmin(active);
|
|
@@ -4684,10 +4856,14 @@ function createWeb3SDK(apiClient) {
|
|
|
4684
4856
|
};
|
|
4685
4857
|
}
|
|
4686
4858
|
|
|
4859
|
+
Object.defineProperty(exports, "AccountOwnerType", {
|
|
4860
|
+
enumerable: true,
|
|
4861
|
+
get: function () { return persShared.AccountOwnerType; }
|
|
4862
|
+
});
|
|
4687
4863
|
exports.AnalyticsApi = AnalyticsApi;
|
|
4688
4864
|
exports.AnalyticsService = AnalyticsService;
|
|
4689
|
-
exports.
|
|
4690
|
-
exports.
|
|
4865
|
+
exports.AuthApi = AuthApi;
|
|
4866
|
+
exports.AuthService = AuthService;
|
|
4691
4867
|
exports.BaseTokenService = BaseTokenService;
|
|
4692
4868
|
exports.BusinessApi = BusinessApi;
|
|
4693
4869
|
exports.BusinessService = BusinessService;
|
|
@@ -4705,6 +4881,7 @@ exports.PersApiError = PersApiError;
|
|
|
4705
4881
|
exports.PersSDK = PersSDK;
|
|
4706
4882
|
exports.RedemptionApi = RedemptionApi;
|
|
4707
4883
|
exports.RedemptionService = RedemptionService;
|
|
4884
|
+
exports.SimpleSdkAuthProvider = SimpleSdkAuthProvider;
|
|
4708
4885
|
exports.TenantApi = TenantApi;
|
|
4709
4886
|
exports.TenantService = TenantService;
|
|
4710
4887
|
exports.TokenApi = TokenApi;
|
|
@@ -4723,8 +4900,8 @@ exports.Web3InfrastructureApi = Web3InfrastructureApi;
|
|
|
4723
4900
|
exports.Web3ProviderService = Web3ProviderService;
|
|
4724
4901
|
exports.buildApiRoot = buildApiRoot;
|
|
4725
4902
|
exports.createAnalyticsSDK = createAnalyticsSDK;
|
|
4726
|
-
exports.createAuthAdminSDK = createAuthAdminSDK;
|
|
4727
4903
|
exports.createAuthProvider = createAuthProvider;
|
|
4904
|
+
exports.createAuthSDK = createAuthSDK;
|
|
4728
4905
|
exports.createBusinessSDK = createBusinessSDK;
|
|
4729
4906
|
exports.createCampaignSDK = createCampaignSDK;
|
|
4730
4907
|
exports.createDonationSDK = createDonationSDK;
|