@pagamio/frontend-commons-lib 0.8.189 → 0.8.191

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/lib/api/client.js CHANGED
@@ -11,6 +11,7 @@ export class ApiClient {
11
11
  defaultHeaders: {
12
12
  'Content-Type': 'application/json',
13
13
  },
14
+ credentials: 'include',
14
15
  ...config,
15
16
  };
16
17
  }
@@ -214,7 +215,7 @@ export class ApiClient {
214
215
  * Makes the actual HTTP request.
215
216
  */
216
217
  async makeRequest(endpoint, method, config) {
217
- const { params, timeout, skipAuth, skipRefresh, requestConfig, overrideDefaultHeaders, signal } = config;
218
+ const { params, timeout, skipAuth, skipRefresh, requestConfig, overrideDefaultHeaders, signal, overrideDefaultCredentials, } = config;
218
219
  const url = this.createUrl(endpoint, params);
219
220
  // Use provided signal, or create a new AbortController for this request
220
221
  let requestSignal;
@@ -227,7 +228,7 @@ export class ApiClient {
227
228
  this.activeControllers.add(controller);
228
229
  requestSignal = controller.signal;
229
230
  }
230
- let finalConfig = this.buildRequestConfig(requestConfig, method, overrideDefaultHeaders, requestSignal);
231
+ let finalConfig = this.buildRequestConfig(requestConfig, method, overrideDefaultHeaders, overrideDefaultCredentials, requestSignal);
231
232
  finalConfig = await this.injectAuthHeader(finalConfig, skipAuth);
232
233
  finalConfig = await this.applyOnRequestHook(finalConfig);
233
234
  let response;
@@ -243,7 +244,7 @@ export class ApiClient {
243
244
  }
244
245
  return response;
245
246
  }
246
- buildRequestConfig(requestConfig, method, overrideDefaultHeaders, signal) {
247
+ buildRequestConfig(requestConfig, method, overrideDefaultHeaders, overrideDefaultCredentials, signal) {
247
248
  return {
248
249
  ...requestConfig,
249
250
  method,
@@ -252,6 +253,7 @@ export class ApiClient {
252
253
  ...requestConfig.headers,
253
254
  },
254
255
  signal,
256
+ credentials: requestConfig.credentials ?? overrideDefaultCredentials ?? this.config.credentials ?? 'same-origin',
255
257
  };
256
258
  }
257
259
  async injectAuthHeader(finalConfig, skipAuth) {
@@ -102,11 +102,12 @@ export declare function useApi<T extends CustomAuthConfig>(): ApiClient<T>;
102
102
  * });
103
103
  * ```
104
104
  */
105
- export declare function createApiClient<T extends CustomAuthConfig>({ baseURL, tokenManager, defaultHeaders, timeout, retries, }: {
105
+ export declare function createApiClient<T extends CustomAuthConfig>({ baseURL, tokenManager, defaultHeaders, timeout, retries, credentials, }: {
106
106
  baseURL: string;
107
107
  tokenManager: TokenManager<T>;
108
108
  defaultHeaders?: HeadersInit;
109
109
  timeout?: number;
110
110
  retries?: number;
111
+ credentials?: RequestCredentials;
111
112
  }): ApiClient<T>;
112
113
  export {};
@@ -94,12 +94,13 @@ export function useApi() {
94
94
  * });
95
95
  * ```
96
96
  */
97
- export function createApiClient({ baseURL, tokenManager, defaultHeaders = {}, timeout = 30000, retries = 1, }) {
97
+ export function createApiClient({ baseURL, tokenManager, defaultHeaders = {}, timeout = 30000, retries = 1, credentials, }) {
98
98
  return new ApiClient({
99
99
  baseURL,
100
100
  tokenManager,
101
101
  defaultHeaders,
102
102
  timeout,
103
103
  retries,
104
+ credentials,
104
105
  });
105
106
  }
@@ -22,6 +22,7 @@ export interface ApiClientConfig<T extends CustomAuthConfig> {
22
22
  onResponse?: <T>(response: Response, data: T) => Promise<T> | T;
23
23
  onError?: (error: ApiError) => Promise<void> | void;
24
24
  onUnauthorized?: () => Promise<void> | void;
25
+ credentials?: RequestCredentials;
25
26
  }
26
27
  export interface RequestConfig extends RequestInit {
27
28
  params?: Record<string, string>;
@@ -231,4 +231,52 @@ export interface VasAppAuthConfig extends CustomAuthConfig {
231
231
  password: string;
232
232
  };
233
233
  }
234
+ /**
235
+ * Authentication configuration for the Commerce application.
236
+ * Defines the structure of user information, token data, and login credentials
237
+ * specific to the Commerce app authentication flow.
238
+ *
239
+ * @example
240
+ * ```typescript
241
+ * const authService = createAuthService<CommerceAppAuthConfig>({
242
+ * baseUrl: 'https://api.commerce.example.com',
243
+ * endpoints: {
244
+ * login: '/auth/login',
245
+ * register: '/auth/register',
246
+ * }
247
+ * });
248
+ * ```
249
+ */
250
+ export interface CommerceAppAuthConfig extends CustomAuthConfig {
251
+ /** User information structure for Commerce app */
252
+ UserInfo: {
253
+ /** Unique identifier for the user */
254
+ id: string;
255
+ /** Username used for authentication */
256
+ userName: string;
257
+ /** Current onboarding step */
258
+ onboardingStep?: string | null;
259
+ /** Secondary user identifier */
260
+ userId: string;
261
+ /** User type (e.g., customer, merchant, admin) */
262
+ userType: string;
263
+ /** User type identifier */
264
+ userTypeId: string;
265
+ };
266
+ /** Token information structure */
267
+ TokenInfo: {
268
+ /** JWT or other authentication token */
269
+ token: string;
270
+ /** Token expiration time in seconds */
271
+ expiresIn: number;
272
+ };
273
+ /** Login credentials structure */
274
+ Credentials: {
275
+ /** Username or email for authentication */
276
+ username?: string;
277
+ email?: string;
278
+ /** User's password */
279
+ password: string;
280
+ };
281
+ }
234
282
  export {};
@@ -1,4 +1,4 @@
1
- import type { ApiResponseTransformer, AuthResponse, EventsAppAuthConfig, VasAppAuthConfig } from '../types';
1
+ import type { ApiResponseTransformer, AuthResponse, CommerceAppAuthConfig, EventsAppAuthConfig, VasAppAuthConfig } from '../types';
2
2
  /**
3
3
  * Transforms authentication responses from the Events App API format into a standardized AuthResponse.
4
4
  * This transformer handles responses that include a single token and role-based user information.
@@ -115,6 +115,44 @@ export declare class VasAppResponseTransformer implements ApiResponseTransformer
115
115
  */
116
116
  transform(response: any, remember?: boolean): AuthResponse<VasAppAuthConfig>;
117
117
  }
118
+ /**
119
+ * Transforms authentication responses from the Commerce App API format into a standardized AuthResponse.
120
+ * This transformer handles responses wrapped in a success/data structure.
121
+ *
122
+ * Expected API response format:
123
+ * ```typescript
124
+ * {
125
+ * success: boolean;
126
+ * data: {
127
+ * user: {...};
128
+ * accessToken: string;
129
+ * refreshToken: string;
130
+ * };
131
+ * }
132
+ * ```
133
+ *
134
+ * @implements {ApiResponseTransformer<CommerceAppAuthConfig>}
135
+ */
136
+ export declare class CommerceAppResponseTransformer implements ApiResponseTransformer<CommerceAppAuthConfig> {
137
+ /**
138
+ * Checks if the given response matches the Commerce App API format.
139
+ * Verifies the presence of required fields specific to Commerce App responses.
140
+ *
141
+ * @param response - The raw API response to check
142
+ * @returns True if the response contains 'success' and 'data' fields with user and tokens
143
+ */
144
+ canHandle(response: any): boolean;
145
+ /**
146
+ * Transforms a Commerce App API response into the standardized AuthResponse format.
147
+ * Maps API-specific fields to the common auth response structure.
148
+ *
149
+ * @param response - The raw API response to transform
150
+ * @param remember - Whether to use extended token expiration
151
+ * @returns Standardized auth response with user and token information
152
+ * @throws Error if required fields are missing from the response
153
+ */
154
+ transform(response: any, remember?: boolean): AuthResponse<CommerceAppAuthConfig>;
155
+ }
118
156
  /**
119
157
  * Factory class for creating and managing response transformers.
120
158
  * Implements the Factory pattern to dynamically select the appropriate transformer
@@ -211,6 +211,106 @@ export class VasAppResponseTransformer {
211
211
  };
212
212
  }
213
213
  }
214
+ /**
215
+ * Transforms authentication responses from the Commerce App API format into a standardized AuthResponse.
216
+ * This transformer handles responses wrapped in a success/data structure.
217
+ *
218
+ * Expected API response format:
219
+ * ```typescript
220
+ * {
221
+ * success: boolean;
222
+ * data: {
223
+ * user: {...};
224
+ * accessToken: string;
225
+ * refreshToken: string;
226
+ * };
227
+ * }
228
+ * ```
229
+ *
230
+ * @implements {ApiResponseTransformer<CommerceAppAuthConfig>}
231
+ */
232
+ export class CommerceAppResponseTransformer {
233
+ /**
234
+ * Checks if the given response matches the Commerce App API format.
235
+ * Verifies the presence of required fields specific to Commerce App responses.
236
+ *
237
+ * @param response - The raw API response to check
238
+ * @returns True if the response contains 'success' and 'data' fields with user and tokens
239
+ */
240
+ canHandle(response) {
241
+ return (response.hasOwnProperty('success') &&
242
+ response.hasOwnProperty('data') &&
243
+ response.data?.hasOwnProperty('user') &&
244
+ response.data?.hasOwnProperty('accessToken'));
245
+ }
246
+ /**
247
+ * Transforms a Commerce App API response into the standardized AuthResponse format.
248
+ * Maps API-specific fields to the common auth response structure.
249
+ *
250
+ * @param response - The raw API response to transform
251
+ * @param remember - Whether to use extended token expiration
252
+ * @returns Standardized auth response with user and token information
253
+ * @throws Error if required fields are missing from the response
254
+ */
255
+ transform(response, remember) {
256
+ const { data } = response;
257
+ // Decode access token to get expiration
258
+ let decodedAccessToken;
259
+ try {
260
+ decodedAccessToken = jwtDecode(data.accessToken);
261
+ }
262
+ catch (error) {
263
+ console.error('Error decoding JWT access token:', error);
264
+ throw new Error('Failed to decode JWT access token. Please check the token format.');
265
+ }
266
+ if (!decodedAccessToken.exp) {
267
+ throw new Error('Access token does not contain an expiry time (exp claim)');
268
+ }
269
+ // Calculate access token expiration in seconds from now
270
+ const currentTime = Math.floor(Date.now() / 1000);
271
+ const accessExpiresIn = decodedAccessToken.exp - currentTime;
272
+ if (accessExpiresIn <= 0) {
273
+ throw new Error('Access token has already expired');
274
+ }
275
+ // Decode refresh token to get expiration (if present)
276
+ let refreshExpiresIn;
277
+ if (data.refreshToken) {
278
+ try {
279
+ const decodedRefreshToken = jwtDecode(data.refreshToken);
280
+ if (decodedRefreshToken.exp) {
281
+ refreshExpiresIn = decodedRefreshToken.exp - currentTime;
282
+ }
283
+ }
284
+ catch (error) {
285
+ console.error('Error decoding JWT refresh token:', error);
286
+ // Use fallback if refresh token can't be decoded
287
+ refreshExpiresIn = remember ? 30 * 24 * 60 * 60 : 7 * 24 * 60 * 60; // 30 days or 7 days
288
+ }
289
+ }
290
+ return {
291
+ user: {
292
+ id: data.user.id,
293
+ userName: data.user.userName,
294
+ onboardingStep: data.user.onboardingStep,
295
+ userId: data.user.id,
296
+ userType: data.user.userType || 'customer',
297
+ userTypeId: data.user.userTypeId || data.user.employeeId || data.user.id,
298
+ },
299
+ auth: {
300
+ accessToken: {
301
+ token: data.accessToken,
302
+ expiresIn: accessExpiresIn,
303
+ },
304
+ refreshToken: data.refreshToken && refreshExpiresIn
305
+ ? {
306
+ token: data.refreshToken,
307
+ expiresIn: refreshExpiresIn,
308
+ }
309
+ : undefined,
310
+ },
311
+ };
312
+ }
313
+ }
214
314
  /**
215
315
  * Factory class for creating and managing response transformers.
216
316
  * Implements the Factory pattern to dynamically select the appropriate transformer
@@ -232,6 +332,7 @@ export class ResponseTransformerFactory {
232
332
  * @static
233
333
  */
234
334
  static transformers = [
335
+ new CommerceAppResponseTransformer(),
235
336
  new EventsAppResponseTransformer(),
236
337
  new VasAppResponseTransformer(),
237
338
  ];
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@pagamio/frontend-commons-lib",
3
3
  "description": "Pagamio library for Frontend reusable components like the form engine and table container",
4
- "version": "0.8.189",
4
+ "version": "0.8.191",
5
5
  "publishConfig": {
6
6
  "access": "public",
7
7
  "provenance": false