@explorins/pers-sdk 1.2.6 → 1.3.1
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/README.md +416 -0
- package/dist/campaign/api/campaign-api.d.ts +19 -65
- package/dist/campaign/api/campaign-api.d.ts.map +1 -1
- package/dist/campaign.cjs +51 -105
- package/dist/campaign.cjs.map +1 -1
- package/dist/campaign.js +49 -103
- package/dist/campaign.js.map +1 -1
- package/dist/chunks/base-token-service-BA81_Ouq.js +532 -0
- package/dist/chunks/base-token-service-BA81_Ouq.js.map +1 -0
- package/dist/chunks/base-token-service-BQ6uFoki.cjs +537 -0
- package/dist/chunks/base-token-service-BQ6uFoki.cjs.map +1 -0
- package/dist/chunks/jwt.function-BYiyl-z_.cjs +25 -0
- package/dist/chunks/jwt.function-BYiyl-z_.cjs.map +1 -0
- package/dist/chunks/jwt.function-d6jPtBqI.js +23 -0
- package/dist/chunks/jwt.function-d6jPtBqI.js.map +1 -0
- package/dist/chunks/pers-sdk-JC-hSYUd.js +1377 -0
- package/dist/chunks/pers-sdk-JC-hSYUd.js.map +1 -0
- package/dist/chunks/pers-sdk-_1sTi9x9.cjs +1384 -0
- package/dist/chunks/pers-sdk-_1sTi9x9.cjs.map +1 -0
- package/dist/core/auth/api/auth-api.d.ts +4 -2
- package/dist/core/auth/api/auth-api.d.ts.map +1 -1
- package/dist/core/auth/auth-constants.d.ts +33 -0
- package/dist/core/auth/auth-constants.d.ts.map +1 -0
- package/dist/core/auth/auth-errors.d.ts +8 -0
- package/dist/core/auth/auth-errors.d.ts.map +1 -0
- package/dist/core/auth/auth-provider.interface.d.ts +49 -3
- package/dist/core/auth/auth-provider.interface.d.ts.map +1 -1
- package/dist/core/auth/create-auth-provider.d.ts.map +1 -1
- package/dist/core/auth/default-auth-provider.d.ts +71 -0
- package/dist/core/auth/default-auth-provider.d.ts.map +1 -0
- package/dist/core/auth/index.d.ts +1 -22
- package/dist/core/auth/index.d.ts.map +1 -1
- package/dist/core/auth/services/auth-service.d.ts.map +1 -1
- package/dist/core/auth/token-refresh.d.ts +91 -0
- package/dist/core/auth/token-refresh.d.ts.map +1 -0
- package/dist/core/auth/token-storage.d.ts +74 -0
- package/dist/core/auth/token-storage.d.ts.map +1 -0
- package/dist/core/errors/index.d.ts +80 -0
- package/dist/core/errors/index.d.ts.map +1 -0
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/pers-api-client.d.ts +155 -17
- package/dist/core/pers-api-client.d.ts.map +1 -1
- package/dist/core/pers-config.d.ts +36 -1
- package/dist/core/pers-config.d.ts.map +1 -1
- package/dist/core/utils/jwt.function.d.ts.map +1 -1
- package/dist/core.cjs +8 -814
- package/dist/core.cjs.map +1 -1
- package/dist/core.js +2 -803
- package/dist/core.js.map +1 -1
- package/dist/index.cjs +77 -4912
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +19 -4857
- package/dist/index.js.map +1 -1
- package/dist/package.json +129 -129
- package/dist/pers-sdk.d.ts +49 -7
- package/dist/pers-sdk.d.ts.map +1 -1
- package/dist/redemption/api/redemption-api.d.ts +12 -13
- package/dist/redemption/api/redemption-api.d.ts.map +1 -1
- package/dist/redemption.cjs +24 -24
- package/dist/redemption.cjs.map +1 -1
- package/dist/redemption.js +24 -24
- package/dist/redemption.js.map +1 -1
- package/dist/shared/interfaces/pers-shared-lib.interfaces.d.ts +1 -0
- package/dist/shared/interfaces/pers-shared-lib.interfaces.d.ts.map +1 -1
- package/dist/tenant/api/tenant-api.d.ts +28 -10
- package/dist/tenant/api/tenant-api.d.ts.map +1 -1
- package/dist/tenant/index.d.ts +4 -4
- package/dist/tenant.cjs +40 -11
- package/dist/tenant.cjs.map +1 -1
- package/dist/tenant.js +40 -11
- package/dist/tenant.js.map +1 -1
- package/dist/token.cjs +7 -534
- package/dist/token.cjs.map +1 -1
- package/dist/token.js +1 -532
- package/dist/token.js.map +1 -1
- package/dist/web3-chain.cjs +7 -148
- package/dist/web3-chain.cjs.map +1 -1
- package/dist/web3-chain.js +6 -147
- package/dist/web3-chain.js.map +1 -1
- package/dist/web3.cjs +8 -538
- package/dist/web3.cjs.map +1 -1
- package/dist/web3.js +6 -536
- package/dist/web3.js.map +1 -1
- package/package.json +129 -129
- package/dist/core/auth/simple-sdk-auth-provider.d.ts +0 -27
- package/dist/core/auth/simple-sdk-auth-provider.d.ts.map +0 -1
package/dist/core.js
CHANGED
|
@@ -1,804 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* PERS SDK Configuration interfaces
|
|
6
|
-
*/
|
|
7
|
-
/**
|
|
8
|
-
* Default configuration values
|
|
9
|
-
*/
|
|
10
|
-
const DEFAULT_PERS_CONFIG = {
|
|
11
|
-
environment: 'production',
|
|
12
|
-
apiVersion: 'v2',
|
|
13
|
-
timeout: 30000,
|
|
14
|
-
retries: 3
|
|
15
|
-
};
|
|
16
|
-
/**
|
|
17
|
-
* Internal function to construct API root from environment
|
|
18
|
-
* Now defaults to production and v2
|
|
19
|
-
*/
|
|
20
|
-
function buildApiRoot(environment = 'production', version = 'v2') {
|
|
21
|
-
const baseUrls = {
|
|
22
|
-
development: 'https://explorins-loyalty.ngrok.io',
|
|
23
|
-
staging: `https://dev.api.pers.ninja/${version}`,
|
|
24
|
-
production: `https://api.pers.ninja/${version}`
|
|
25
|
-
};
|
|
26
|
-
return `${baseUrls[environment]}`;
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* Merge user config with defaults
|
|
30
|
-
*/
|
|
31
|
-
function mergeWithDefaults(config) {
|
|
32
|
-
return {
|
|
33
|
-
...DEFAULT_PERS_CONFIG,
|
|
34
|
-
...config,
|
|
35
|
-
environment: config.environment ?? DEFAULT_PERS_CONFIG.environment,
|
|
36
|
-
apiVersion: config.apiVersion ?? DEFAULT_PERS_CONFIG.apiVersion,
|
|
37
|
-
timeout: config.timeout ?? DEFAULT_PERS_CONFIG.timeout,
|
|
38
|
-
retries: config.retries ?? DEFAULT_PERS_CONFIG.retries
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Platform-Agnostic Auth Admin API Client
|
|
44
|
-
*
|
|
45
|
-
* Handles authentication and authorization admin operations using the PERS backend.
|
|
46
|
-
* Uses @explorins/pers-shared DTOs for consistency with backend.
|
|
47
|
-
*
|
|
48
|
-
* Note: Special header handling (bypass-auth-interceptor) may need to be implemented
|
|
49
|
-
* at the PersApiClient level or through a specialized auth client.
|
|
50
|
-
*/
|
|
51
|
-
class AuthApi {
|
|
52
|
-
constructor(apiClient) {
|
|
53
|
-
this.apiClient = apiClient;
|
|
54
|
-
this.basePath = '/auth';
|
|
55
|
-
}
|
|
56
|
-
// ==========================================
|
|
57
|
-
// ADMIN AUTHENTICATION OPERATIONS
|
|
58
|
-
// ==========================================
|
|
59
|
-
/**
|
|
60
|
-
* ADMIN: Login tenant admin with JWT
|
|
61
|
-
* Note: JWT handling and auth bypass headers may need special implementation
|
|
62
|
-
*/
|
|
63
|
-
async loginTenantAdmin(jwt) {
|
|
64
|
-
const body = {
|
|
65
|
-
authToken: jwt,
|
|
66
|
-
authType: AccountOwnerType.TENANT
|
|
67
|
-
};
|
|
68
|
-
return this.apiClient.post(`${this.basePath}/token`, body);
|
|
69
|
-
}
|
|
70
|
-
async loginUser(jwt) {
|
|
71
|
-
const body = {
|
|
72
|
-
authToken: jwt,
|
|
73
|
-
authType: AccountOwnerType.USER
|
|
74
|
-
};
|
|
75
|
-
return this.apiClient.post(`${this.basePath}/token`, body);
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* ADMIN: Refresh access token
|
|
79
|
-
* Note: Bypass header handling may need special implementation
|
|
80
|
-
*/
|
|
81
|
-
async refreshAccessToken(refreshToken) {
|
|
82
|
-
return this.apiClient.post(`${this.basePath}/refresh`, { refreshToken });
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Platform-Agnostic Auth Admin Service
|
|
88
|
-
*
|
|
89
|
-
* Contains auth admin business logic and operations that work across platforms.
|
|
90
|
-
* No framework dependencies - pure TypeScript business logic.
|
|
91
|
-
*
|
|
92
|
-
* Focuses only on actual backend capabilities.
|
|
93
|
-
*/
|
|
94
|
-
class AuthService {
|
|
95
|
-
constructor(authApi, authProvider) {
|
|
96
|
-
this.authApi = authApi;
|
|
97
|
-
this.authProvider = authProvider;
|
|
98
|
-
}
|
|
99
|
-
// ==========================================
|
|
100
|
-
// ADMIN AUTHENTICATION OPERATIONS
|
|
101
|
-
// ==========================================
|
|
102
|
-
/**
|
|
103
|
-
* ADMIN: Login tenant admin with JWT
|
|
104
|
-
* Automatically stores tokens if auth provider supports token storage
|
|
105
|
-
*/
|
|
106
|
-
async loginTenantAdmin(jwt) {
|
|
107
|
-
const response = await this.authApi.loginTenantAdmin(jwt);
|
|
108
|
-
// Store tokens if auth provider supports it
|
|
109
|
-
if (this.authProvider && response.accessToken) {
|
|
110
|
-
await this.storeTokens(response.accessToken, response.refreshToken);
|
|
111
|
-
}
|
|
112
|
-
return response;
|
|
113
|
-
}
|
|
114
|
-
/**
|
|
115
|
-
* ADMIN: Login user with JWT
|
|
116
|
-
* Automatically stores tokens if auth provider supports token storage
|
|
117
|
-
*/
|
|
118
|
-
async loginUser(jwt) {
|
|
119
|
-
const response = await this.authApi.loginUser(jwt);
|
|
120
|
-
// Store tokens if auth provider supports it
|
|
121
|
-
if (this.authProvider && response.accessToken) {
|
|
122
|
-
await this.storeTokens(response.accessToken, response.refreshToken);
|
|
123
|
-
}
|
|
124
|
-
return response;
|
|
125
|
-
}
|
|
126
|
-
/**
|
|
127
|
-
* ADMIN: Refresh access token
|
|
128
|
-
* Automatically stores new tokens if auth provider supports token storage
|
|
129
|
-
*/
|
|
130
|
-
async refreshAccessToken(refreshToken) {
|
|
131
|
-
// Use provided refresh token or get from auth provider
|
|
132
|
-
const tokenToUse = refreshToken || (this.authProvider?.getRefreshToken ? await this.authProvider.getRefreshToken() : null);
|
|
133
|
-
if (!tokenToUse) {
|
|
134
|
-
throw new Error('No refresh token available for token refresh');
|
|
135
|
-
}
|
|
136
|
-
const response = await this.authApi.refreshAccessToken(tokenToUse);
|
|
137
|
-
// Store new tokens if auth provider supports it
|
|
138
|
-
if (this.authProvider && response.accessToken) {
|
|
139
|
-
await this.storeTokens(response.accessToken, response.refreshToken);
|
|
140
|
-
}
|
|
141
|
-
return response;
|
|
142
|
-
}
|
|
143
|
-
/**
|
|
144
|
-
* Automatic token refresh using stored refresh token
|
|
145
|
-
* Convenience method for 401 error handling
|
|
146
|
-
*/
|
|
147
|
-
async autoRefreshToken() {
|
|
148
|
-
return this.refreshAccessToken(); // Uses stored refresh token
|
|
149
|
-
}
|
|
150
|
-
/**
|
|
151
|
-
* Clear stored tokens if auth provider supports it
|
|
152
|
-
*/
|
|
153
|
-
async clearTokens() {
|
|
154
|
-
if (this.authProvider?.clearTokens) {
|
|
155
|
-
await this.authProvider.clearTokens();
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
/**
|
|
159
|
-
* Check if we have valid tokens for authentication
|
|
160
|
-
*/
|
|
161
|
-
hasValidAuth() {
|
|
162
|
-
return this.authProvider?.hasValidToken?.() ?? false;
|
|
163
|
-
}
|
|
164
|
-
// ==========================================
|
|
165
|
-
// PRIVATE HELPERS
|
|
166
|
-
// ==========================================
|
|
167
|
-
/**
|
|
168
|
-
* Store tokens using auth provider if it supports token storage
|
|
169
|
-
*/
|
|
170
|
-
async storeTokens(accessToken, refreshToken) {
|
|
171
|
-
if (!this.authProvider)
|
|
172
|
-
return;
|
|
173
|
-
try {
|
|
174
|
-
// Store access token
|
|
175
|
-
if (this.authProvider.setAccessToken) {
|
|
176
|
-
await this.authProvider.setAccessToken(accessToken);
|
|
177
|
-
}
|
|
178
|
-
// Store refresh token if provided and supported
|
|
179
|
-
if (refreshToken && this.authProvider.setRefreshToken) {
|
|
180
|
-
await this.authProvider.setRefreshToken(refreshToken);
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
catch (error) {
|
|
184
|
-
console.error('Failed to store tokens in auth provider:', error);
|
|
185
|
-
// Don't throw - token storage failure shouldn't break authentication
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
/**
|
|
191
|
-
* Simple, self-contained authentication provider for SDK
|
|
192
|
-
*
|
|
193
|
-
* Manages tokens internally without external dependencies.
|
|
194
|
-
* Perfect for platform-agnostic usage.
|
|
195
|
-
*/
|
|
196
|
-
class SimpleSdkAuthProvider {
|
|
197
|
-
constructor(projectKey) {
|
|
198
|
-
this.accessToken = null;
|
|
199
|
-
this.refreshToken = null;
|
|
200
|
-
this.projectKey = null;
|
|
201
|
-
this.authType = 'admin';
|
|
202
|
-
this.projectKey = projectKey || null;
|
|
203
|
-
// Try to load tokens from localStorage if available
|
|
204
|
-
this.loadTokensFromStorage();
|
|
205
|
-
}
|
|
206
|
-
async getToken() {
|
|
207
|
-
// Return stored access token
|
|
208
|
-
return this.accessToken;
|
|
209
|
-
}
|
|
210
|
-
async getProjectKey() {
|
|
211
|
-
return this.projectKey;
|
|
212
|
-
}
|
|
213
|
-
async onTokenExpired() {
|
|
214
|
-
console.log('SimpleSdkAuthProvider: Token expired, attempting refresh...');
|
|
215
|
-
if (!this.refreshToken) {
|
|
216
|
-
console.warn('SimpleSdkAuthProvider: No refresh token available');
|
|
217
|
-
throw new Error('No refresh token available for refresh');
|
|
218
|
-
}
|
|
219
|
-
// Note: Actual refresh logic would be handled by the SDK's AuthService
|
|
220
|
-
// This provider just manages token storage
|
|
221
|
-
console.warn('SimpleSdkAuthProvider: Token refresh should be handled by SDK AuthService');
|
|
222
|
-
}
|
|
223
|
-
// Token storage methods
|
|
224
|
-
async setAccessToken(token) {
|
|
225
|
-
this.accessToken = token;
|
|
226
|
-
this.saveTokenToStorage('pers_access_token', token);
|
|
227
|
-
}
|
|
228
|
-
async setRefreshToken(token) {
|
|
229
|
-
this.refreshToken = token;
|
|
230
|
-
this.saveTokenToStorage('pers_refresh_token', token);
|
|
231
|
-
}
|
|
232
|
-
async getRefreshToken() {
|
|
233
|
-
return this.refreshToken;
|
|
234
|
-
}
|
|
235
|
-
async clearTokens() {
|
|
236
|
-
this.accessToken = null;
|
|
237
|
-
this.refreshToken = null;
|
|
238
|
-
// Clear from storage
|
|
239
|
-
this.removeTokenFromStorage('pers_access_token');
|
|
240
|
-
this.removeTokenFromStorage('pers_refresh_token');
|
|
241
|
-
}
|
|
242
|
-
// Internal methods for token persistence
|
|
243
|
-
loadTokensFromStorage() {
|
|
244
|
-
if (typeof localStorage !== 'undefined') {
|
|
245
|
-
try {
|
|
246
|
-
this.accessToken = localStorage.getItem('pers_access_token');
|
|
247
|
-
this.refreshToken = localStorage.getItem('pers_refresh_token');
|
|
248
|
-
}
|
|
249
|
-
catch (error) {
|
|
250
|
-
console.error('Failed to load tokens from localStorage:', error);
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
else {
|
|
254
|
-
console.warn('localStorage is not available for token persistence');
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
saveTokenToStorage(key, value) {
|
|
258
|
-
if (typeof localStorage !== 'undefined') {
|
|
259
|
-
localStorage.setItem(key, value);
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
removeTokenFromStorage(key) {
|
|
263
|
-
if (typeof localStorage !== 'undefined') {
|
|
264
|
-
localStorage.removeItem(key);
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
// Utility methods for external integration
|
|
268
|
-
hasValidToken() {
|
|
269
|
-
const hasToken = !!this.accessToken;
|
|
270
|
-
return hasToken;
|
|
271
|
-
}
|
|
272
|
-
hasRefreshToken() {
|
|
273
|
-
return !!this.refreshToken;
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
// packages/pers-sdk/src/core/pers-api-client.ts
|
|
278
|
-
/**
|
|
279
|
-
* PERS API Client - Core platform-agnostic client for PERS backend
|
|
280
|
-
*/
|
|
281
|
-
class PersApiClient {
|
|
282
|
-
constructor(httpClient, config) {
|
|
283
|
-
this.httpClient = httpClient;
|
|
284
|
-
this.config = config;
|
|
285
|
-
// Merge user config with defaults (production + v2)
|
|
286
|
-
this.mergedConfig = mergeWithDefaults(config);
|
|
287
|
-
// Auto-create auth provider if none provided
|
|
288
|
-
if (!this.mergedConfig.authProvider) {
|
|
289
|
-
this.mergedConfig.authProvider = new SimpleSdkAuthProvider(this.mergedConfig.apiProjectKey);
|
|
290
|
-
}
|
|
291
|
-
// Build API root from merged environment and version
|
|
292
|
-
this.apiRoot = buildApiRoot(this.mergedConfig.environment, this.mergedConfig.apiVersion);
|
|
293
|
-
// Initialize auth services for direct authentication
|
|
294
|
-
this.authApi = new AuthApi(this);
|
|
295
|
-
this.authService = new AuthService(this.authApi, this.mergedConfig.authProvider);
|
|
296
|
-
}
|
|
297
|
-
/**
|
|
298
|
-
* Get request headers including auth token and project key
|
|
299
|
-
*/
|
|
300
|
-
async getHeaders() {
|
|
301
|
-
const headers = {
|
|
302
|
-
'Content-Type': 'application/json',
|
|
303
|
-
};
|
|
304
|
-
// Add authentication token
|
|
305
|
-
if (this.mergedConfig.authProvider) {
|
|
306
|
-
const token = await this.mergedConfig.authProvider.getToken();
|
|
307
|
-
if (token) {
|
|
308
|
-
headers['Authorization'] = `Bearer ${token}`;
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
// Add project key
|
|
312
|
-
if (this.mergedConfig.authProvider) {
|
|
313
|
-
const projectKey = await this.mergedConfig.authProvider.getProjectKey();
|
|
314
|
-
if (projectKey) {
|
|
315
|
-
headers['x-project-key'] = projectKey;
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
else if (this.mergedConfig.apiProjectKey) {
|
|
319
|
-
// Fallback to config project key if no auth provider
|
|
320
|
-
headers['x-project-key'] = this.mergedConfig.apiProjectKey;
|
|
321
|
-
}
|
|
322
|
-
return headers;
|
|
323
|
-
}
|
|
324
|
-
/**
|
|
325
|
-
* Make a request with proper headers, auth, and error handling
|
|
326
|
-
*/
|
|
327
|
-
async request(method, endpoint, body, options) {
|
|
328
|
-
const { retryCount = 0, responseType = 'json' } = options || {};
|
|
329
|
-
const url = `${this.apiRoot}${endpoint}`;
|
|
330
|
-
// ✅ DEBUGGING: Add extensive logging for CSV endpoint
|
|
331
|
-
const isCSVEndpoint = endpoint.includes('/export/csv');
|
|
332
|
-
const requestOptions = {
|
|
333
|
-
headers: await this.getHeaders(),
|
|
334
|
-
timeout: this.mergedConfig.timeout,
|
|
335
|
-
responseType
|
|
336
|
-
};
|
|
337
|
-
try {
|
|
338
|
-
let result;
|
|
339
|
-
switch (method) {
|
|
340
|
-
case 'GET':
|
|
341
|
-
result = await this.httpClient.get(url, requestOptions);
|
|
342
|
-
break;
|
|
343
|
-
case 'POST':
|
|
344
|
-
result = await this.httpClient.post(url, body, requestOptions);
|
|
345
|
-
break;
|
|
346
|
-
case 'PUT':
|
|
347
|
-
result = await this.httpClient.put(url, body, requestOptions);
|
|
348
|
-
break;
|
|
349
|
-
case 'DELETE':
|
|
350
|
-
result = await this.httpClient.delete(url, requestOptions);
|
|
351
|
-
break;
|
|
352
|
-
default:
|
|
353
|
-
throw new Error(`Unsupported HTTP method: ${method}`);
|
|
354
|
-
}
|
|
355
|
-
return result;
|
|
356
|
-
}
|
|
357
|
-
catch (error) {
|
|
358
|
-
if (isCSVEndpoint) {
|
|
359
|
-
console.error('❌ [PERS API CLIENT] CSV Request failed:', error);
|
|
360
|
-
}
|
|
361
|
-
// Handle 401 errors with automatic token refresh
|
|
362
|
-
const apiError = error;
|
|
363
|
-
if (apiError.status === 401 && retryCount === 0 && this.mergedConfig.authProvider?.onTokenExpired) {
|
|
364
|
-
try {
|
|
365
|
-
await this.mergedConfig.authProvider.onTokenExpired();
|
|
366
|
-
// Retry once with refreshed token
|
|
367
|
-
return this.request(method, endpoint, body, { ...options, retryCount: 1 });
|
|
368
|
-
}
|
|
369
|
-
catch (refreshError) {
|
|
370
|
-
throw new PersApiError(`Authentication refresh failed: ${refreshError}`, endpoint, method, 401);
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
throw new PersApiError(`PERS API request failed: ${apiError.message || error}`, endpoint, method, apiError.status);
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
/**
|
|
377
|
-
* Generic GET request
|
|
378
|
-
*/
|
|
379
|
-
async get(endpoint, responseType) {
|
|
380
|
-
return this.request('GET', endpoint, undefined, { responseType });
|
|
381
|
-
}
|
|
382
|
-
/**
|
|
383
|
-
* Generic POST request
|
|
384
|
-
*/
|
|
385
|
-
async post(endpoint, body) {
|
|
386
|
-
return this.request('POST', endpoint, body);
|
|
387
|
-
}
|
|
388
|
-
/**
|
|
389
|
-
* Generic PUT request
|
|
390
|
-
*/
|
|
391
|
-
async put(endpoint, body) {
|
|
392
|
-
return this.request('PUT', endpoint, body);
|
|
393
|
-
}
|
|
394
|
-
/**
|
|
395
|
-
* Generic DELETE request
|
|
396
|
-
*/
|
|
397
|
-
async delete(endpoint) {
|
|
398
|
-
return this.request('DELETE', endpoint);
|
|
399
|
-
}
|
|
400
|
-
// ==========================================
|
|
401
|
-
// AUTHENTICATION METHODS
|
|
402
|
-
// ==========================================
|
|
403
|
-
/**
|
|
404
|
-
* Login admin user with external JWT (e.g., Firebase)
|
|
405
|
-
* Automatically stores tokens in auth provider if available
|
|
406
|
-
*/
|
|
407
|
-
async loginAdmin(externalJwt) {
|
|
408
|
-
return this.authService.loginTenantAdmin(externalJwt);
|
|
409
|
-
}
|
|
410
|
-
/**
|
|
411
|
-
* Login regular user with external JWT
|
|
412
|
-
* Automatically stores tokens in auth provider if available
|
|
413
|
-
*/
|
|
414
|
-
async loginUser(externalJwt) {
|
|
415
|
-
return this.authService.loginUser(externalJwt);
|
|
416
|
-
}
|
|
417
|
-
/**
|
|
418
|
-
* Refresh access token using stored refresh token
|
|
419
|
-
*/
|
|
420
|
-
async refreshToken() {
|
|
421
|
-
const refreshToken = await this.mergedConfig.authProvider?.getRefreshToken?.();
|
|
422
|
-
if (!refreshToken) {
|
|
423
|
-
throw new Error('No refresh token available');
|
|
424
|
-
}
|
|
425
|
-
return this.authService.refreshAccessToken(refreshToken);
|
|
426
|
-
}
|
|
427
|
-
/**
|
|
428
|
-
* Clear all stored authentication tokens
|
|
429
|
-
*/
|
|
430
|
-
async clearAuth() {
|
|
431
|
-
return this.authService.clearTokens();
|
|
432
|
-
}
|
|
433
|
-
/**
|
|
434
|
-
* Check if user has valid authentication token
|
|
435
|
-
*/
|
|
436
|
-
hasValidAuth() {
|
|
437
|
-
return this.mergedConfig.authProvider?.hasValidToken?.() || false;
|
|
438
|
-
}
|
|
439
|
-
/**
|
|
440
|
-
* Get current configuration (returns merged config)
|
|
441
|
-
*/
|
|
442
|
-
getConfig() {
|
|
443
|
-
return this.mergedConfig;
|
|
444
|
-
}
|
|
445
|
-
/**
|
|
446
|
-
* Get original user configuration
|
|
447
|
-
*/
|
|
448
|
-
getOriginalConfig() {
|
|
449
|
-
return this.config;
|
|
450
|
-
}
|
|
451
|
-
}
|
|
452
|
-
class PersApiError extends Error {
|
|
453
|
-
constructor(message, endpoint, method, statusCode) {
|
|
454
|
-
super(message);
|
|
455
|
-
this.endpoint = endpoint;
|
|
456
|
-
this.method = method;
|
|
457
|
-
this.statusCode = statusCode;
|
|
458
|
-
this.name = 'PersApiError';
|
|
459
|
-
}
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
/**
|
|
463
|
-
* Memory-based token storage (default)
|
|
464
|
-
*/
|
|
465
|
-
class MemoryTokenStorage {
|
|
466
|
-
constructor() {
|
|
467
|
-
this.storage = new Map();
|
|
468
|
-
}
|
|
469
|
-
async setItem(key, value) {
|
|
470
|
-
this.storage.set(key, value);
|
|
471
|
-
}
|
|
472
|
-
async getItem(key) {
|
|
473
|
-
return this.storage.get(key) || null;
|
|
474
|
-
}
|
|
475
|
-
async removeItem(key) {
|
|
476
|
-
this.storage.delete(key);
|
|
477
|
-
}
|
|
478
|
-
}
|
|
479
|
-
/**
|
|
480
|
-
* localStorage-based token storage (browser only)
|
|
481
|
-
*/
|
|
482
|
-
class LocalStorageTokenStorage {
|
|
483
|
-
async setItem(key, value) {
|
|
484
|
-
if (typeof localStorage !== 'undefined') {
|
|
485
|
-
localStorage.setItem(key, value);
|
|
486
|
-
}
|
|
487
|
-
else {
|
|
488
|
-
throw new Error('localStorage is not available in this environment');
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
|
-
async getItem(key) {
|
|
492
|
-
if (typeof localStorage !== 'undefined') {
|
|
493
|
-
return localStorage.getItem(key);
|
|
494
|
-
}
|
|
495
|
-
return null;
|
|
496
|
-
}
|
|
497
|
-
async removeItem(key) {
|
|
498
|
-
if (typeof localStorage !== 'undefined') {
|
|
499
|
-
localStorage.removeItem(key);
|
|
500
|
-
}
|
|
501
|
-
}
|
|
502
|
-
}
|
|
503
|
-
/**
|
|
504
|
-
* Creates a platform-agnostic AuthProvider from simple configuration
|
|
505
|
-
*
|
|
506
|
-
* This factory function is completely platform-agnostic and can be used
|
|
507
|
-
* across Angular, React, Vue, Node.js, or any other JavaScript environment.
|
|
508
|
-
*
|
|
509
|
-
* Features:
|
|
510
|
-
* - Token caching with refresh support
|
|
511
|
-
* - Automatic token refresh on expiration
|
|
512
|
-
* - Configurable token providers
|
|
513
|
-
* - Token storage (memory, localStorage, custom)
|
|
514
|
-
* - Platform-independent
|
|
515
|
-
*
|
|
516
|
-
* @param config - Simple auth configuration
|
|
517
|
-
* @returns AuthProvider implementation
|
|
518
|
-
*/
|
|
519
|
-
function createAuthProvider(config) {
|
|
520
|
-
// Initialize token storage
|
|
521
|
-
let tokenStorage;
|
|
522
|
-
switch (config.tokenStorage) {
|
|
523
|
-
case 'localStorage':
|
|
524
|
-
tokenStorage = new LocalStorageTokenStorage();
|
|
525
|
-
break;
|
|
526
|
-
case 'custom':
|
|
527
|
-
if (!config.customTokenStorage) {
|
|
528
|
-
throw new Error('Custom token storage configuration is required when tokenStorage is "custom"');
|
|
529
|
-
}
|
|
530
|
-
tokenStorage = config.customTokenStorage;
|
|
531
|
-
break;
|
|
532
|
-
case 'memory':
|
|
533
|
-
default:
|
|
534
|
-
tokenStorage = new MemoryTokenStorage();
|
|
535
|
-
break;
|
|
536
|
-
}
|
|
537
|
-
// Token storage keys
|
|
538
|
-
const ACCESS_TOKEN_KEY = `pers_access_token_${config.authType || 'user'}`;
|
|
539
|
-
const REFRESH_TOKEN_KEY = `pers_refresh_token_${config.authType || 'user'}`;
|
|
540
|
-
// Store current token for refresh scenarios and caching
|
|
541
|
-
let currentToken = config.token || null;
|
|
542
|
-
let isRefreshing = false; // Prevent concurrent refresh attempts
|
|
543
|
-
let refreshPromise = null;
|
|
544
|
-
return {
|
|
545
|
-
authType: config.authType || 'user',
|
|
546
|
-
async getToken() {
|
|
547
|
-
// If currently refreshing, wait for it to complete
|
|
548
|
-
if (isRefreshing && refreshPromise) {
|
|
549
|
-
await refreshPromise;
|
|
550
|
-
return currentToken;
|
|
551
|
-
}
|
|
552
|
-
// Use cached current token (updated after refresh)
|
|
553
|
-
if (currentToken) {
|
|
554
|
-
return currentToken;
|
|
555
|
-
}
|
|
556
|
-
// Try to get token from storage
|
|
557
|
-
try {
|
|
558
|
-
const storedToken = await tokenStorage.getItem(ACCESS_TOKEN_KEY);
|
|
559
|
-
if (storedToken) {
|
|
560
|
-
currentToken = storedToken;
|
|
561
|
-
return storedToken;
|
|
562
|
-
}
|
|
563
|
-
}
|
|
564
|
-
catch (error) {
|
|
565
|
-
console.warn('Failed to retrieve token from storage:', error);
|
|
566
|
-
}
|
|
567
|
-
// Custom token provider function (always fresh)
|
|
568
|
-
if (config.tokenProvider) {
|
|
569
|
-
const token = await config.tokenProvider();
|
|
570
|
-
currentToken = token; // Cache for future calls
|
|
571
|
-
return token;
|
|
572
|
-
}
|
|
573
|
-
// No token available
|
|
574
|
-
return null;
|
|
575
|
-
},
|
|
576
|
-
async getProjectKey() {
|
|
577
|
-
return config.projectKey || null;
|
|
578
|
-
},
|
|
579
|
-
// Token storage methods
|
|
580
|
-
async setAccessToken(token) {
|
|
581
|
-
currentToken = token;
|
|
582
|
-
try {
|
|
583
|
-
await tokenStorage.setItem(ACCESS_TOKEN_KEY, token);
|
|
584
|
-
}
|
|
585
|
-
catch (error) {
|
|
586
|
-
console.error('Failed to store access token:', error);
|
|
587
|
-
throw error;
|
|
588
|
-
}
|
|
589
|
-
},
|
|
590
|
-
async setRefreshToken(token) {
|
|
591
|
-
try {
|
|
592
|
-
await tokenStorage.setItem(REFRESH_TOKEN_KEY, token);
|
|
593
|
-
}
|
|
594
|
-
catch (error) {
|
|
595
|
-
console.error('Failed to store refresh token:', error);
|
|
596
|
-
throw error;
|
|
597
|
-
}
|
|
598
|
-
},
|
|
599
|
-
async getRefreshToken() {
|
|
600
|
-
try {
|
|
601
|
-
return await tokenStorage.getItem(REFRESH_TOKEN_KEY);
|
|
602
|
-
}
|
|
603
|
-
catch (error) {
|
|
604
|
-
console.warn('Failed to retrieve refresh token from storage:', error);
|
|
605
|
-
return null;
|
|
606
|
-
}
|
|
607
|
-
},
|
|
608
|
-
async clearTokens() {
|
|
609
|
-
currentToken = null;
|
|
610
|
-
try {
|
|
611
|
-
await Promise.all([
|
|
612
|
-
tokenStorage.removeItem(ACCESS_TOKEN_KEY),
|
|
613
|
-
tokenStorage.removeItem(REFRESH_TOKEN_KEY)
|
|
614
|
-
]);
|
|
615
|
-
}
|
|
616
|
-
catch (error) {
|
|
617
|
-
console.error('Failed to clear tokens from storage:', error);
|
|
618
|
-
throw error;
|
|
619
|
-
}
|
|
620
|
-
},
|
|
621
|
-
async onTokenExpired() {
|
|
622
|
-
// Prevent concurrent refresh attempts
|
|
623
|
-
if (isRefreshing) {
|
|
624
|
-
if (refreshPromise) {
|
|
625
|
-
await refreshPromise;
|
|
626
|
-
}
|
|
627
|
-
return;
|
|
628
|
-
}
|
|
629
|
-
// No refresh logic provided
|
|
630
|
-
if (!config.onTokenExpired) {
|
|
631
|
-
console.warn('Token expired but no refresh logic provided');
|
|
632
|
-
currentToken = null;
|
|
633
|
-
try {
|
|
634
|
-
await tokenStorage.removeItem(ACCESS_TOKEN_KEY);
|
|
635
|
-
}
|
|
636
|
-
catch (error) {
|
|
637
|
-
console.warn('Failed to clear expired token from storage:', error);
|
|
638
|
-
}
|
|
639
|
-
return;
|
|
640
|
-
}
|
|
641
|
-
// Start refresh process
|
|
642
|
-
isRefreshing = true;
|
|
643
|
-
refreshPromise = (async () => {
|
|
644
|
-
try {
|
|
645
|
-
// Execute refresh logic (should update token source)
|
|
646
|
-
await config.onTokenExpired();
|
|
647
|
-
// After refresh, get the new token
|
|
648
|
-
if (config.tokenProvider) {
|
|
649
|
-
const newToken = await config.tokenProvider();
|
|
650
|
-
if (newToken && newToken !== currentToken) {
|
|
651
|
-
currentToken = newToken;
|
|
652
|
-
// Store the new token
|
|
653
|
-
try {
|
|
654
|
-
await tokenStorage.setItem(ACCESS_TOKEN_KEY, newToken);
|
|
655
|
-
}
|
|
656
|
-
catch (error) {
|
|
657
|
-
console.warn('Failed to store refreshed token:', error);
|
|
658
|
-
}
|
|
659
|
-
// Notify about successful token refresh
|
|
660
|
-
if (config.onTokenRefreshed) {
|
|
661
|
-
config.onTokenRefreshed(newToken);
|
|
662
|
-
}
|
|
663
|
-
}
|
|
664
|
-
else {
|
|
665
|
-
console.warn('Token refresh completed but no new token received');
|
|
666
|
-
currentToken = null;
|
|
667
|
-
try {
|
|
668
|
-
await tokenStorage.removeItem(ACCESS_TOKEN_KEY);
|
|
669
|
-
}
|
|
670
|
-
catch (error) {
|
|
671
|
-
console.warn('Failed to clear token after failed refresh:', error);
|
|
672
|
-
}
|
|
673
|
-
}
|
|
674
|
-
}
|
|
675
|
-
else {
|
|
676
|
-
// For static token configs, clear the token since we can't refresh
|
|
677
|
-
console.warn('Token expired for static token config - clearing token');
|
|
678
|
-
currentToken = null;
|
|
679
|
-
try {
|
|
680
|
-
await tokenStorage.removeItem(ACCESS_TOKEN_KEY);
|
|
681
|
-
}
|
|
682
|
-
catch (error) {
|
|
683
|
-
console.warn('Failed to clear expired static token:', error);
|
|
684
|
-
}
|
|
685
|
-
}
|
|
686
|
-
}
|
|
687
|
-
catch (error) {
|
|
688
|
-
console.error('Token refresh failed:', error);
|
|
689
|
-
currentToken = null; // Clear token on refresh failure
|
|
690
|
-
try {
|
|
691
|
-
await tokenStorage.removeItem(ACCESS_TOKEN_KEY);
|
|
692
|
-
}
|
|
693
|
-
catch (storageError) {
|
|
694
|
-
console.warn('Failed to clear token after refresh failure:', storageError);
|
|
695
|
-
}
|
|
696
|
-
throw error; // Re-throw to let SDK handle the error
|
|
697
|
-
}
|
|
698
|
-
finally {
|
|
699
|
-
isRefreshing = false;
|
|
700
|
-
refreshPromise = null;
|
|
701
|
-
}
|
|
702
|
-
})();
|
|
703
|
-
await refreshPromise;
|
|
704
|
-
}
|
|
705
|
-
};
|
|
706
|
-
}
|
|
707
|
-
/**
|
|
708
|
-
* Platform-specific localStorage token provider for browsers
|
|
709
|
-
* This is a convenience function for browser environments
|
|
710
|
-
*/
|
|
711
|
-
/* export function createBrowserTokenProvider(tokenKey: string = 'userJwt'): () => Promise<string | null> {
|
|
712
|
-
return async () => {
|
|
713
|
-
if (typeof localStorage !== 'undefined') {
|
|
714
|
-
return localStorage.getItem(tokenKey);
|
|
715
|
-
}
|
|
716
|
-
return null;
|
|
717
|
-
};
|
|
718
|
-
} */
|
|
719
|
-
/**
|
|
720
|
-
* Platform-specific environment variable token provider for Node.js
|
|
721
|
-
* This is a convenience function for Node.js environments
|
|
722
|
-
*/
|
|
723
|
-
/* export function createNodeTokenProvider(envVar: string = 'JWT_TOKEN'): () => Promise<string | null> {
|
|
724
|
-
return async () => {
|
|
725
|
-
if (typeof process !== 'undefined' && process.env) {
|
|
726
|
-
return process.env[envVar] || null;
|
|
727
|
-
}
|
|
728
|
-
return null;
|
|
729
|
-
};
|
|
730
|
-
} */
|
|
731
|
-
|
|
732
|
-
/**
|
|
733
|
-
* @explorins/pers-sdk/core/auth - Consolidated Auth Module
|
|
734
|
-
*
|
|
735
|
-
* All authentication functionality in one place:
|
|
736
|
-
* - Auth provider interfaces and implementations
|
|
737
|
-
* - Auth API and service logic
|
|
738
|
-
* - Token management
|
|
739
|
-
*/
|
|
740
|
-
// Auth provider interfaces and implementations
|
|
741
|
-
/**
|
|
742
|
-
* Create a complete Auth SDK instance (for backward compatibility)
|
|
743
|
-
* Note: This is now handled directly by PersApiClient
|
|
744
|
-
*
|
|
745
|
-
* @param apiClient - Configured PERS API client
|
|
746
|
-
* @param authProvider - Optional auth provider. If not provided, uses SimpleSdkAuthProvider
|
|
747
|
-
* @returns Auth SDK with flattened structure for better DX
|
|
748
|
-
*/
|
|
749
|
-
function createAuthSDK(apiClient, authProvider) {
|
|
750
|
-
// Use simple internal auth provider if none provided
|
|
751
|
-
const provider = authProvider || new SimpleSdkAuthProvider();
|
|
752
|
-
const authApi = new AuthApi(apiClient);
|
|
753
|
-
const authService = new AuthService(authApi, provider);
|
|
754
|
-
return {
|
|
755
|
-
// Direct access to service methods (primary interface)
|
|
756
|
-
// Admin authentication methods
|
|
757
|
-
loginTenantAdmin: (jwt) => authService.loginTenantAdmin(jwt),
|
|
758
|
-
loginUser: (jwt) => authService.loginUser(jwt),
|
|
759
|
-
refreshAccessToken: (refreshToken) => authService.refreshAccessToken(refreshToken),
|
|
760
|
-
clearTokens: () => authService.clearTokens(),
|
|
761
|
-
// Auth provider access for external integration
|
|
762
|
-
getAuthProvider: () => provider,
|
|
763
|
-
hasValidToken: () => provider.hasValidToken?.() || false,
|
|
764
|
-
// Advanced access for edge cases
|
|
765
|
-
api: authApi,
|
|
766
|
-
service: authService
|
|
767
|
-
};
|
|
768
|
-
}
|
|
769
|
-
|
|
770
|
-
/**
|
|
771
|
-
* PERS SDK - Minimal platform-agnostic client with built-in authentication
|
|
772
|
-
* Authentication is now handled at the SDK core level for better scalability
|
|
773
|
-
*/
|
|
774
|
-
/**
|
|
775
|
-
* Minimal PERS SDK - API client with authentication built-in
|
|
776
|
-
* Platform adapters provide auth providers and HTTP clients
|
|
777
|
-
*/
|
|
778
|
-
class PersSDK {
|
|
779
|
-
constructor(httpClient, config) {
|
|
780
|
-
this.apiClient = new PersApiClient(httpClient, config);
|
|
781
|
-
}
|
|
782
|
-
/**
|
|
783
|
-
* Get the API client for direct PERS API calls
|
|
784
|
-
* This is the main interface - keep it simple!
|
|
785
|
-
*/
|
|
786
|
-
api() {
|
|
787
|
-
return this.apiClient;
|
|
788
|
-
}
|
|
789
|
-
/**
|
|
790
|
-
* Quick config check
|
|
791
|
-
*/
|
|
792
|
-
isProduction() {
|
|
793
|
-
return this.apiClient.getConfig().environment === 'production';
|
|
794
|
-
}
|
|
795
|
-
}
|
|
796
|
-
/**
|
|
797
|
-
* Simple factory function
|
|
798
|
-
*/
|
|
799
|
-
function createPersSDK(httpClient, config) {
|
|
800
|
-
return new PersSDK(httpClient, config);
|
|
801
|
-
}
|
|
802
|
-
|
|
803
|
-
export { AuthApi, AuthService, DEFAULT_PERS_CONFIG, PersApiClient, PersApiError, PersSDK, SimpleSdkAuthProvider, buildApiRoot, createAuthProvider, createAuthSDK, createPersSDK, mergeWithDefaults };
|
|
1
|
+
export { D as DEFAULT_PERS_CONFIG, a as PersApiClient, P as PersSDK, b as buildApiRoot, c as createPersSDK, m as mergeWithDefaults } from './chunks/pers-sdk-JC-hSYUd.js';
|
|
2
|
+
import '@explorins/pers-shared';
|
|
804
3
|
//# sourceMappingURL=core.js.map
|