@zerosls/clm-sdk 1.1.9 → 1.1.10
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/core/api-client.d.ts +0 -1
- package/dist/core/api-client.js +28 -283
- package/dist/index.d.ts +0 -4
- package/dist/index.js +0 -9
- package/dist/modules/v1/auth/auth-api.d.ts +3 -5
- package/dist/modules/v1/auth/auth-api.js +46 -35
- package/dist/types/sdk.d.ts +0 -1
- package/package.json +1 -1
- package/src/core/api-client.ts +27 -301
- package/src/index.ts +0 -14
- package/src/modules/v1/auth/auth-api.ts +66 -42
- package/src/types/sdk.ts +0 -1
- package/dist/core/legacy-api-client.d.ts +0 -26
- package/dist/core/legacy-api-client.js +0 -35
- package/src/core/legacy-api-client.ts +0 -66
package/dist/core/api-client.js
CHANGED
|
@@ -6,8 +6,6 @@ export class ApiClient {
|
|
|
6
6
|
var _a, _b;
|
|
7
7
|
this.token = null;
|
|
8
8
|
this.baseUrl = config.baseUrl;
|
|
9
|
-
this.fallbackBaseUrl =
|
|
10
|
-
config.fallbackBaseUrl || "http://216.250.117.119/ZeroServicesQA/api/v1";
|
|
11
9
|
this.organization = config.organization;
|
|
12
10
|
this.token = config.token || null;
|
|
13
11
|
this.eventEmitter = eventEmitter;
|
|
@@ -57,223 +55,31 @@ export class ApiClient {
|
|
|
57
55
|
}
|
|
58
56
|
}
|
|
59
57
|
}
|
|
60
|
-
/*private async request<T>(
|
|
61
|
-
method: string,
|
|
62
|
-
endpoint: string,
|
|
63
|
-
data?: any,
|
|
64
|
-
params?: Record<string, any>,
|
|
65
|
-
options: RequestOptions = {}
|
|
66
|
-
): Promise<T> {
|
|
67
|
-
// ✅ Primer intento con baseUrl normal
|
|
68
|
-
const primaryUrl = buildUrl(this.baseUrl, endpoint, params);
|
|
69
|
-
|
|
70
|
-
const base: HeadersInit = buildHeaders(this.token, {
|
|
71
|
-
"X-Organization": this.organization,
|
|
72
|
-
...(options.headers || {}),
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
const headers = new Headers(base);
|
|
76
|
-
|
|
77
|
-
// ✅ Obtener token legacy
|
|
78
|
-
const legacyToken =
|
|
79
|
-
(window as any).__LEGACY_TOKEN__ ||
|
|
80
|
-
sessionStorage.getItem("legacy_token") ||
|
|
81
|
-
null;
|
|
82
|
-
|
|
83
|
-
if (legacyToken) {
|
|
84
|
-
headers.set("Authorization", `Bearer ${legacyToken}`);
|
|
85
|
-
if (this.debug) {
|
|
86
|
-
console.log("🔐 Using legacy token for:", endpoint);
|
|
87
|
-
}
|
|
88
|
-
} else if (this.token) {
|
|
89
|
-
if (this.debug) {
|
|
90
|
-
console.log("🔐 Using v1 token for:", endpoint);
|
|
91
|
-
}
|
|
92
|
-
} else {
|
|
93
|
-
console.warn("⚠️ No token available for endpoint:", endpoint);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
const useCache = this.cacheEnabled && options.useCache !== false;
|
|
97
|
-
if (useCache && method === "GET") {
|
|
98
|
-
const cacheKey = generateCacheKey(method, primaryUrl, data);
|
|
99
|
-
const cachedData = this.cache.get<T>(cacheKey);
|
|
100
|
-
if (cachedData) {
|
|
101
|
-
if (this.debug) {
|
|
102
|
-
console.log(`[SDK-Cache] Hit: ${cacheKey}`);
|
|
103
|
-
}
|
|
104
|
-
return cachedData;
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
this.eventEmitter.emit("beforeRequest", {
|
|
109
|
-
url: primaryUrl,
|
|
110
|
-
method,
|
|
111
|
-
data,
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
try {
|
|
115
|
-
const fetchOptions: RequestInit = {
|
|
116
|
-
method,
|
|
117
|
-
headers,
|
|
118
|
-
credentials: "include",
|
|
119
|
-
};
|
|
120
|
-
|
|
121
|
-
if (data && method !== "GET") {
|
|
122
|
-
fetchOptions.body = JSON.stringify(data);
|
|
123
|
-
if (this.debug) {
|
|
124
|
-
console.log(`📤 ${method} Body:`, data);
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
if (this.debug) {
|
|
129
|
-
console.log(`🌐 ${method} ${primaryUrl}`);
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
// ✅ Primer intento
|
|
133
|
-
const response = await fetch(primaryUrl, fetchOptions);
|
|
134
|
-
|
|
135
|
-
// ✅ Si es 404, intentar con fallback URL
|
|
136
|
-
if (response.status === 404) {
|
|
137
|
-
console.warn(`⚠️ 404 en ${primaryUrl}, intentando con fallback...`);
|
|
138
|
-
|
|
139
|
-
const fallbackUrl = buildUrl(this.fallbackBaseUrl, endpoint, params);
|
|
140
|
-
|
|
141
|
-
if (this.debug) {
|
|
142
|
-
console.log(`🔄 Retry: ${method} ${fallbackUrl}`);
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
// ✅ Segundo intento con fallback
|
|
146
|
-
const fallbackResponse = await fetch(fallbackUrl, fetchOptions);
|
|
147
|
-
|
|
148
|
-
if (!fallbackResponse.ok) {
|
|
149
|
-
let errorData;
|
|
150
|
-
try {
|
|
151
|
-
errorData = await fallbackResponse.json();
|
|
152
|
-
} catch {
|
|
153
|
-
errorData = { message: fallbackResponse.statusText };
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
console.error(`❌ Fallback también falló ${fallbackResponse.status}:`, errorData);
|
|
157
|
-
|
|
158
|
-
if (fallbackResponse.status === 401) {
|
|
159
|
-
this.eventEmitter.emit("authError", {
|
|
160
|
-
statusCode: 401,
|
|
161
|
-
message: errorData.message || "Authentication required",
|
|
162
|
-
});
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
return errorData as T;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
// ✅ Fallback exitoso
|
|
169
|
-
const fallbackData = await parseResponse<T>(fallbackResponse);
|
|
170
|
-
|
|
171
|
-
console.log(`✅ Fallback exitoso para: ${endpoint}`);
|
|
172
|
-
|
|
173
|
-
this.eventEmitter.emit("afterRequest", {
|
|
174
|
-
url: fallbackUrl,
|
|
175
|
-
method,
|
|
176
|
-
response: fallbackData,
|
|
177
|
-
});
|
|
178
|
-
|
|
179
|
-
return fallbackData;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
// ✅ Otros errores (no 404)
|
|
183
|
-
if (!response.ok) {
|
|
184
|
-
let errorData;
|
|
185
|
-
try {
|
|
186
|
-
errorData = await response.json();
|
|
187
|
-
} catch {
|
|
188
|
-
errorData = { message: response.statusText };
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
console.error(`❌ ${method} ${response.status}:`, errorData);
|
|
192
|
-
|
|
193
|
-
if (response.status === 401) {
|
|
194
|
-
this.eventEmitter.emit("authError", {
|
|
195
|
-
statusCode: 401,
|
|
196
|
-
message: errorData.message || "Authentication required",
|
|
197
|
-
});
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
return errorData as T;
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
// ✅ Respuesta exitosa del primer intento
|
|
204
|
-
const responseData = await parseResponse<T>(response);
|
|
205
|
-
|
|
206
|
-
if (useCache && method === "GET") {
|
|
207
|
-
const cacheKey = generateCacheKey(method, primaryUrl, data);
|
|
208
|
-
const cacheTime = options.cacheTime || undefined;
|
|
209
|
-
this.cache.set(cacheKey, responseData, cacheTime);
|
|
210
|
-
|
|
211
|
-
if (this.debug) {
|
|
212
|
-
console.log(`[SDK-Cache] Set: ${cacheKey}`);
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
this.eventEmitter.emit("afterRequest", {
|
|
217
|
-
url: primaryUrl,
|
|
218
|
-
method,
|
|
219
|
-
response: responseData,
|
|
220
|
-
});
|
|
221
|
-
|
|
222
|
-
return responseData;
|
|
223
|
-
} catch (error) {
|
|
224
|
-
this.eventEmitter.emit("requestError", {
|
|
225
|
-
url: primaryUrl,
|
|
226
|
-
method,
|
|
227
|
-
error,
|
|
228
|
-
});
|
|
229
|
-
|
|
230
|
-
if (error instanceof ApiError) {
|
|
231
|
-
throw error;
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
throw new ApiError((error as Error).message || "Network error", 0, {
|
|
235
|
-
originalError: error,
|
|
236
|
-
});
|
|
237
|
-
}
|
|
238
|
-
}*/
|
|
239
58
|
async request(method, endpoint, data, params, options = {}) {
|
|
240
|
-
const
|
|
241
|
-
const
|
|
59
|
+
const url = buildUrl(this.baseUrl, endpoint, params);
|
|
60
|
+
const base = buildHeaders(this.token, {
|
|
242
61
|
"X-Organization": this.organization,
|
|
243
62
|
...(options.headers || {}),
|
|
244
63
|
});
|
|
245
|
-
|
|
246
|
-
const
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
const createHeaders = () => {
|
|
254
|
-
const headers = new Headers(baseHeaders);
|
|
255
|
-
const legacyToken = window.__LEGACY_TOKEN__ ||
|
|
256
|
-
sessionStorage.getItem("legacy_token") ||
|
|
64
|
+
const headers = new Headers(base);
|
|
65
|
+
const legacyPattern = /(^|\/)legacy(\/|$)/i;
|
|
66
|
+
const isLegacyEndpoint = legacyPattern.test(endpoint);
|
|
67
|
+
const isLegacyLogin = /(^|\/)legacy\/login$/i.test(endpoint);
|
|
68
|
+
if (isLegacyEndpoint && !isLegacyLogin) {
|
|
69
|
+
const legacyToken = (typeof window !== "undefined" && window.__LEGACY_TOKEN__) ||
|
|
70
|
+
(typeof sessionStorage !== "undefined" &&
|
|
71
|
+
sessionStorage.getItem("legacy_token")) ||
|
|
257
72
|
null;
|
|
258
73
|
if (legacyToken) {
|
|
259
74
|
headers.set("Authorization", `Bearer ${legacyToken}`);
|
|
260
|
-
if (this.debug) {
|
|
261
|
-
console.log("🔐 Using legacy token for:", endpoint);
|
|
262
|
-
}
|
|
263
75
|
}
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
}
|
|
269
|
-
else {
|
|
270
|
-
console.warn("⚠️ No token available for endpoint:", endpoint);
|
|
271
|
-
}
|
|
272
|
-
return headers;
|
|
273
|
-
};
|
|
76
|
+
}
|
|
77
|
+
if (!isLegacyEndpoint && !this.token) {
|
|
78
|
+
headers.delete("Authorization");
|
|
79
|
+
}
|
|
274
80
|
const useCache = this.cacheEnabled && options.useCache !== false;
|
|
275
81
|
if (useCache && method === "GET") {
|
|
276
|
-
const cacheKey = generateCacheKey(method,
|
|
82
|
+
const cacheKey = generateCacheKey(method, url, data);
|
|
277
83
|
const cachedData = this.cache.get(cacheKey);
|
|
278
84
|
if (cachedData) {
|
|
279
85
|
if (this.debug) {
|
|
@@ -283,89 +89,28 @@ export class ApiClient {
|
|
|
283
89
|
}
|
|
284
90
|
}
|
|
285
91
|
this.eventEmitter.emit("beforeRequest", {
|
|
286
|
-
url
|
|
92
|
+
url,
|
|
287
93
|
method,
|
|
288
94
|
data,
|
|
289
95
|
});
|
|
290
96
|
try {
|
|
291
|
-
|
|
292
|
-
if (data && method !== "GET") {
|
|
293
|
-
body = JSON.stringify(data);
|
|
294
|
-
if (this.debug) {
|
|
295
|
-
console.log(`📤 ${method} Body:`, data);
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
// ✅ Primer intento
|
|
299
|
-
const headers1 = createHeaders();
|
|
300
|
-
const fetchOptions1 = {
|
|
97
|
+
const fetchOptions = {
|
|
301
98
|
method,
|
|
302
|
-
headers
|
|
303
|
-
credentials:
|
|
304
|
-
...(body && { body }),
|
|
99
|
+
headers,
|
|
100
|
+
credentials: this.credentials,
|
|
305
101
|
};
|
|
306
|
-
if (
|
|
307
|
-
|
|
308
|
-
console.log(
|
|
309
|
-
}
|
|
310
|
-
const response = await fetch(primaryUrl, fetchOptions1);
|
|
311
|
-
if (response.status === 404) {
|
|
312
|
-
console.warn(`⚠️ 404 en ${primaryUrl}, intentando con fallback...`);
|
|
313
|
-
const fallbackUrl = buildUrl(this.fallbackBaseUrl, endpoint, params);
|
|
314
|
-
if (this.debug) {
|
|
315
|
-
console.log(`🔄 Retry: ${method} ${fallbackUrl}`);
|
|
316
|
-
}
|
|
317
|
-
// ✅ Segundo intento
|
|
318
|
-
const headers2 = createHeaders();
|
|
319
|
-
const fetchOptions2 = {
|
|
320
|
-
method,
|
|
321
|
-
headers: headers2,
|
|
322
|
-
credentials: "include",
|
|
323
|
-
...(body && { body }),
|
|
324
|
-
};
|
|
325
|
-
if (this.debug) {
|
|
326
|
-
console.log("📋 Fallback Headers:", headersToObject(headers2)); // ✅ CORREGIDO
|
|
327
|
-
}
|
|
328
|
-
const fallbackResponse = await fetch(fallbackUrl, fetchOptions2);
|
|
329
|
-
if (fallbackResponse.status === 204) {
|
|
330
|
-
console.log(`✅ Fallback exitoso (204 No Content): ${endpoint}`);
|
|
331
|
-
return {};
|
|
332
|
-
}
|
|
333
|
-
if (!fallbackResponse.ok) {
|
|
334
|
-
let errorData;
|
|
335
|
-
try {
|
|
336
|
-
errorData = await fallbackResponse.json();
|
|
337
|
-
}
|
|
338
|
-
catch (_a) {
|
|
339
|
-
errorData = { message: fallbackResponse.statusText };
|
|
340
|
-
}
|
|
341
|
-
console.error(`❌ Fallback falló ${fallbackResponse.status}:`, errorData);
|
|
342
|
-
if (fallbackResponse.status === 401) {
|
|
343
|
-
this.eventEmitter.emit("authError", {
|
|
344
|
-
statusCode: 401,
|
|
345
|
-
message: errorData.message || "Authentication required",
|
|
346
|
-
});
|
|
347
|
-
}
|
|
348
|
-
return errorData;
|
|
349
|
-
}
|
|
350
|
-
const fallbackData = await parseResponse(fallbackResponse);
|
|
351
|
-
console.log(`✅ Fallback exitoso: ${endpoint}`);
|
|
352
|
-
this.eventEmitter.emit("afterRequest", {
|
|
353
|
-
url: fallbackUrl,
|
|
354
|
-
method,
|
|
355
|
-
response: fallbackData,
|
|
356
|
-
});
|
|
357
|
-
return fallbackData;
|
|
358
|
-
}
|
|
359
|
-
if (response.status === 204) {
|
|
360
|
-
console.log(`✅ Request exitoso (204 No Content): ${endpoint}`);
|
|
361
|
-
return {};
|
|
102
|
+
if (data && method !== "GET") {
|
|
103
|
+
fetchOptions.body = JSON.stringify(data);
|
|
104
|
+
console.log(`📤 ${method} Body:`, data);
|
|
362
105
|
}
|
|
106
|
+
console.log(`🌐 ${method} ${url}`, fetchOptions);
|
|
107
|
+
const response = await fetch(url, fetchOptions);
|
|
363
108
|
if (!response.ok) {
|
|
364
109
|
let errorData;
|
|
365
110
|
try {
|
|
366
111
|
errorData = await response.json();
|
|
367
112
|
}
|
|
368
|
-
catch (
|
|
113
|
+
catch (_a) {
|
|
369
114
|
errorData = { message: response.statusText };
|
|
370
115
|
}
|
|
371
116
|
console.error(`❌ ${method} ${response.status}:`, errorData);
|
|
@@ -379,7 +124,7 @@ export class ApiClient {
|
|
|
379
124
|
}
|
|
380
125
|
const responseData = await parseResponse(response);
|
|
381
126
|
if (useCache && method === "GET") {
|
|
382
|
-
const cacheKey = generateCacheKey(method,
|
|
127
|
+
const cacheKey = generateCacheKey(method, url, data);
|
|
383
128
|
const cacheTime = options.cacheTime || undefined;
|
|
384
129
|
this.cache.set(cacheKey, responseData, cacheTime);
|
|
385
130
|
if (this.debug) {
|
|
@@ -387,7 +132,7 @@ export class ApiClient {
|
|
|
387
132
|
}
|
|
388
133
|
}
|
|
389
134
|
this.eventEmitter.emit("afterRequest", {
|
|
390
|
-
url
|
|
135
|
+
url,
|
|
391
136
|
method,
|
|
392
137
|
response: responseData,
|
|
393
138
|
});
|
|
@@ -395,7 +140,7 @@ export class ApiClient {
|
|
|
395
140
|
}
|
|
396
141
|
catch (error) {
|
|
397
142
|
this.eventEmitter.emit("requestError", {
|
|
398
|
-
url
|
|
143
|
+
url,
|
|
399
144
|
method,
|
|
400
145
|
error,
|
|
401
146
|
});
|
package/dist/index.d.ts
CHANGED
|
@@ -12,7 +12,6 @@ import { ClassificationTypesApi } from "./modules/legacy/classificationtypes/cla
|
|
|
12
12
|
*/
|
|
13
13
|
export declare class ClmSdk {
|
|
14
14
|
private apiClient;
|
|
15
|
-
private legacyClient;
|
|
16
15
|
private eventEmitter;
|
|
17
16
|
private cacheInstance;
|
|
18
17
|
auth: AuthApi;
|
|
@@ -23,8 +22,6 @@ export declare class ClmSdk {
|
|
|
23
22
|
areas: AreasApi;
|
|
24
23
|
classificationTypes: ClassificationTypesApi;
|
|
25
24
|
constructor(config: Partial<SdkConfig>);
|
|
26
|
-
legacyLogin(userName: string, password: string): Promise<import("./core/legacy-api-client").LegacyLoginResponse>;
|
|
27
|
-
legacyLogout(): void;
|
|
28
25
|
/**
|
|
29
26
|
* Access to events system
|
|
30
27
|
*/
|
|
@@ -43,6 +40,5 @@ export * from "./modules/v1/auth/types";
|
|
|
43
40
|
export * from "./modules/v1/users/types";
|
|
44
41
|
export * from "./modules/v1/notifications/types";
|
|
45
42
|
export * from "./modules/v1/_logs/types";
|
|
46
|
-
export * from "./core/legacy-api-client";
|
|
47
43
|
export * from "./modules/legacy/areas/types";
|
|
48
44
|
export * from "./modules/legacy/classificationtypes/types";
|
package/dist/index.js
CHANGED
|
@@ -11,7 +11,6 @@ import { LogsApi } from "./modules/v1/_logs/logs-api";
|
|
|
11
11
|
// Legacy
|
|
12
12
|
import { AreasApi } from "./modules/legacy/areas/areas-api";
|
|
13
13
|
import { ClassificationTypesApi } from "./modules/legacy/classificationtypes/classificationtypes-api";
|
|
14
|
-
import { LegacyApiClient } from "./core/legacy-api-client";
|
|
15
14
|
/**
|
|
16
15
|
* Main SDK for consuming CLM API
|
|
17
16
|
*/
|
|
@@ -31,7 +30,6 @@ export class ClmSdk {
|
|
|
31
30
|
// Initialize core utilities
|
|
32
31
|
this.cacheInstance = new Cache((_a = fullConfig.cache) === null || _a === void 0 ? void 0 : _a.ttl);
|
|
33
32
|
this.apiClient = new ApiClient(fullConfig, this.eventEmitter);
|
|
34
|
-
this.legacyClient = new LegacyApiClient("http://216.250.117.119/ZeroServicesQA/api/v1");
|
|
35
33
|
// Initialize modules v1
|
|
36
34
|
this.auth = new AuthApi(this.apiClient);
|
|
37
35
|
this.users = new UsersApi(this.apiClient);
|
|
@@ -42,12 +40,6 @@ export class ClmSdk {
|
|
|
42
40
|
this.areas = new AreasApi(this.apiClient);
|
|
43
41
|
this.classificationTypes = new ClassificationTypesApi(this.apiClient);
|
|
44
42
|
}
|
|
45
|
-
async legacyLogin(userName, password) {
|
|
46
|
-
return await this.legacyClient.login(userName, password);
|
|
47
|
-
}
|
|
48
|
-
legacyLogout() {
|
|
49
|
-
this.legacyClient.logout();
|
|
50
|
-
}
|
|
51
43
|
/**
|
|
52
44
|
* Access to events system
|
|
53
45
|
*/
|
|
@@ -63,6 +55,5 @@ export * from "./modules/v1/users/types";
|
|
|
63
55
|
export * from "./modules/v1/notifications/types";
|
|
64
56
|
export * from "./modules/v1/_logs/types";
|
|
65
57
|
// Export legacy types
|
|
66
|
-
export * from "./core/legacy-api-client";
|
|
67
58
|
export * from "./modules/legacy/areas/types";
|
|
68
59
|
export * from "./modules/legacy/classificationtypes/types";
|
|
@@ -1,13 +1,10 @@
|
|
|
1
1
|
import { ApiClient } from "../../../core/api-client";
|
|
2
2
|
import { LoginCredentials, LoginResponse, RefreshTokenRequest } from "./types";
|
|
3
|
+
type LoginMode = "new" | "legacy";
|
|
3
4
|
export declare class AuthApi {
|
|
4
5
|
private apiClient;
|
|
5
6
|
constructor(apiClient: ApiClient);
|
|
6
|
-
|
|
7
|
-
* Login con POST JSON (evita el modal del navegador).
|
|
8
|
-
* El servidor setea cookie HttpOnly (zero_token).
|
|
9
|
-
*/
|
|
10
|
-
login(credentials: LoginCredentials): Promise<{
|
|
7
|
+
login(credentials: LoginCredentials, mode?: LoginMode): Promise<{
|
|
11
8
|
ok: boolean;
|
|
12
9
|
}>;
|
|
13
10
|
refreshToken(request?: RefreshTokenRequest): Promise<LoginResponse>;
|
|
@@ -15,3 +12,4 @@ export declare class AuthApi {
|
|
|
15
12
|
isAuthenticated(): boolean;
|
|
16
13
|
setToken(token: string | null): void;
|
|
17
14
|
}
|
|
15
|
+
export {};
|
|
@@ -2,40 +2,42 @@ export class AuthApi {
|
|
|
2
2
|
constructor(apiClient) {
|
|
3
3
|
this.apiClient = apiClient;
|
|
4
4
|
}
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
5
|
+
async login(credentials, mode = "new") {
|
|
6
|
+
var _a;
|
|
7
|
+
const path = mode === "legacy" ? "/legacy/login" : "/auth/login";
|
|
8
|
+
const response = await fetch(`${this.apiClient["baseUrl"]}${path}`, {
|
|
9
|
+
method: "POST",
|
|
10
|
+
headers: {
|
|
11
|
+
"Content-Type": "application/json",
|
|
12
|
+
"X-Organization": this.apiClient["organization"] || "default-org",
|
|
13
|
+
},
|
|
14
|
+
credentials: "include",
|
|
15
|
+
body: JSON.stringify({
|
|
16
|
+
email: credentials.email,
|
|
17
|
+
password: credentials.password,
|
|
18
|
+
}),
|
|
19
|
+
});
|
|
20
|
+
if (!response.ok) {
|
|
21
|
+
if (response.status === 401)
|
|
22
|
+
throw new Error("Invalid credentials");
|
|
23
|
+
throw new Error(`Login failed: ${response.status}`);
|
|
24
|
+
}
|
|
25
|
+
const data = await response.json().catch(() => null);
|
|
26
|
+
// ✅ Si es legacy, guarda Bearer token para siguientes llamadas legacy
|
|
27
|
+
if (mode === "legacy") {
|
|
28
|
+
const legacyToken = ((_a = data === null || data === void 0 ? void 0 : data.dataResult) === null || _a === void 0 ? void 0 : _a.token) || (data === null || data === void 0 ? void 0 : data.token);
|
|
29
|
+
if (legacyToken) {
|
|
30
|
+
if (typeof sessionStorage !== "undefined") {
|
|
31
|
+
sessionStorage.setItem("legacy_token", legacyToken);
|
|
32
|
+
}
|
|
33
|
+
if (typeof window !== "undefined") {
|
|
34
|
+
window.__LEGACY_TOKEN__ = legacyToken;
|
|
26
35
|
}
|
|
27
|
-
throw new Error(`Login failed: ${response.status}`);
|
|
28
36
|
}
|
|
29
|
-
const data = await response.json();
|
|
30
|
-
// No guardar token en memoria, solo usar cookie
|
|
31
|
-
this.apiClient.setToken(null);
|
|
32
|
-
console.log('✅ Login exitoso, cookie establecida');
|
|
33
|
-
return { ok: true };
|
|
34
|
-
}
|
|
35
|
-
catch (error) {
|
|
36
|
-
console.error('❌ SDK Login error:', error);
|
|
37
|
-
throw error;
|
|
38
37
|
}
|
|
38
|
+
// ✅ Nuevo: cookie HttpOnly, no guardes token en memoria del SDK
|
|
39
|
+
this.apiClient.setToken(null);
|
|
40
|
+
return { ok: true };
|
|
39
41
|
}
|
|
40
42
|
async refreshToken(request) {
|
|
41
43
|
const response = await this.apiClient.post("/auth/refresh", request);
|
|
@@ -47,15 +49,24 @@ export class AuthApi {
|
|
|
47
49
|
try {
|
|
48
50
|
await this.apiClient.post("/auth/logout");
|
|
49
51
|
}
|
|
50
|
-
catch (error) {
|
|
51
|
-
console.error("Error during logout:", error);
|
|
52
|
-
}
|
|
53
52
|
finally {
|
|
53
|
+
// limpia token nuevo
|
|
54
54
|
this.apiClient.setToken(null);
|
|
55
|
+
// limpia legacy token
|
|
56
|
+
if (typeof sessionStorage !== "undefined") {
|
|
57
|
+
sessionStorage.removeItem("legacy_token");
|
|
58
|
+
}
|
|
59
|
+
if (typeof window !== "undefined") {
|
|
60
|
+
delete window.__LEGACY_TOKEN__;
|
|
61
|
+
}
|
|
55
62
|
}
|
|
56
63
|
}
|
|
57
64
|
isAuthenticated() {
|
|
58
|
-
|
|
65
|
+
const hasToken = this.apiClient.getToken() !== null;
|
|
66
|
+
const hasLegacy = (typeof sessionStorage !== "undefined" &&
|
|
67
|
+
!!sessionStorage.getItem("legacy_token")) ||
|
|
68
|
+
(typeof window !== "undefined" && !!window.__LEGACY_TOKEN__);
|
|
69
|
+
return hasToken || hasLegacy;
|
|
59
70
|
}
|
|
60
71
|
setToken(token) {
|
|
61
72
|
this.apiClient.setToken(token);
|
package/dist/types/sdk.d.ts
CHANGED
package/package.json
CHANGED
package/src/core/api-client.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
// core/api-client.ts
|
|
2
1
|
import { SdkConfig, SdkEventType, SdkEvents } from "../types/sdk";
|
|
3
2
|
import { PaginatedResponse, RequestOptions } from "../types/common";
|
|
4
3
|
import { EventEmitter } from "./event-emitter";
|
|
@@ -13,7 +12,6 @@ import {
|
|
|
13
12
|
|
|
14
13
|
export class ApiClient {
|
|
15
14
|
private baseUrl: string;
|
|
16
|
-
private fallbackBaseUrl: string; // ✅ URL de respaldo
|
|
17
15
|
private organization: string;
|
|
18
16
|
private token: string | null = null;
|
|
19
17
|
private eventEmitter: EventEmitter;
|
|
@@ -24,8 +22,6 @@ export class ApiClient {
|
|
|
24
22
|
|
|
25
23
|
constructor(config: SdkConfig, eventEmitter: EventEmitter) {
|
|
26
24
|
this.baseUrl = config.baseUrl;
|
|
27
|
-
this.fallbackBaseUrl =
|
|
28
|
-
config.fallbackBaseUrl || "http://216.250.117.119/ZeroServicesQA/api/v1";
|
|
29
25
|
this.organization = config.organization;
|
|
30
26
|
this.token = config.token || null;
|
|
31
27
|
this.eventEmitter = eventEmitter;
|
|
@@ -126,185 +122,6 @@ export class ApiClient {
|
|
|
126
122
|
}
|
|
127
123
|
}
|
|
128
124
|
|
|
129
|
-
/*private async request<T>(
|
|
130
|
-
method: string,
|
|
131
|
-
endpoint: string,
|
|
132
|
-
data?: any,
|
|
133
|
-
params?: Record<string, any>,
|
|
134
|
-
options: RequestOptions = {}
|
|
135
|
-
): Promise<T> {
|
|
136
|
-
// ✅ Primer intento con baseUrl normal
|
|
137
|
-
const primaryUrl = buildUrl(this.baseUrl, endpoint, params);
|
|
138
|
-
|
|
139
|
-
const base: HeadersInit = buildHeaders(this.token, {
|
|
140
|
-
"X-Organization": this.organization,
|
|
141
|
-
...(options.headers || {}),
|
|
142
|
-
});
|
|
143
|
-
|
|
144
|
-
const headers = new Headers(base);
|
|
145
|
-
|
|
146
|
-
// ✅ Obtener token legacy
|
|
147
|
-
const legacyToken =
|
|
148
|
-
(window as any).__LEGACY_TOKEN__ ||
|
|
149
|
-
sessionStorage.getItem("legacy_token") ||
|
|
150
|
-
null;
|
|
151
|
-
|
|
152
|
-
if (legacyToken) {
|
|
153
|
-
headers.set("Authorization", `Bearer ${legacyToken}`);
|
|
154
|
-
if (this.debug) {
|
|
155
|
-
console.log("🔐 Using legacy token for:", endpoint);
|
|
156
|
-
}
|
|
157
|
-
} else if (this.token) {
|
|
158
|
-
if (this.debug) {
|
|
159
|
-
console.log("🔐 Using v1 token for:", endpoint);
|
|
160
|
-
}
|
|
161
|
-
} else {
|
|
162
|
-
console.warn("⚠️ No token available for endpoint:", endpoint);
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
const useCache = this.cacheEnabled && options.useCache !== false;
|
|
166
|
-
if (useCache && method === "GET") {
|
|
167
|
-
const cacheKey = generateCacheKey(method, primaryUrl, data);
|
|
168
|
-
const cachedData = this.cache.get<T>(cacheKey);
|
|
169
|
-
if (cachedData) {
|
|
170
|
-
if (this.debug) {
|
|
171
|
-
console.log(`[SDK-Cache] Hit: ${cacheKey}`);
|
|
172
|
-
}
|
|
173
|
-
return cachedData;
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
this.eventEmitter.emit("beforeRequest", {
|
|
178
|
-
url: primaryUrl,
|
|
179
|
-
method,
|
|
180
|
-
data,
|
|
181
|
-
});
|
|
182
|
-
|
|
183
|
-
try {
|
|
184
|
-
const fetchOptions: RequestInit = {
|
|
185
|
-
method,
|
|
186
|
-
headers,
|
|
187
|
-
credentials: "include",
|
|
188
|
-
};
|
|
189
|
-
|
|
190
|
-
if (data && method !== "GET") {
|
|
191
|
-
fetchOptions.body = JSON.stringify(data);
|
|
192
|
-
if (this.debug) {
|
|
193
|
-
console.log(`📤 ${method} Body:`, data);
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
if (this.debug) {
|
|
198
|
-
console.log(`🌐 ${method} ${primaryUrl}`);
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
// ✅ Primer intento
|
|
202
|
-
const response = await fetch(primaryUrl, fetchOptions);
|
|
203
|
-
|
|
204
|
-
// ✅ Si es 404, intentar con fallback URL
|
|
205
|
-
if (response.status === 404) {
|
|
206
|
-
console.warn(`⚠️ 404 en ${primaryUrl}, intentando con fallback...`);
|
|
207
|
-
|
|
208
|
-
const fallbackUrl = buildUrl(this.fallbackBaseUrl, endpoint, params);
|
|
209
|
-
|
|
210
|
-
if (this.debug) {
|
|
211
|
-
console.log(`🔄 Retry: ${method} ${fallbackUrl}`);
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
// ✅ Segundo intento con fallback
|
|
215
|
-
const fallbackResponse = await fetch(fallbackUrl, fetchOptions);
|
|
216
|
-
|
|
217
|
-
if (!fallbackResponse.ok) {
|
|
218
|
-
let errorData;
|
|
219
|
-
try {
|
|
220
|
-
errorData = await fallbackResponse.json();
|
|
221
|
-
} catch {
|
|
222
|
-
errorData = { message: fallbackResponse.statusText };
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
console.error(`❌ Fallback también falló ${fallbackResponse.status}:`, errorData);
|
|
226
|
-
|
|
227
|
-
if (fallbackResponse.status === 401) {
|
|
228
|
-
this.eventEmitter.emit("authError", {
|
|
229
|
-
statusCode: 401,
|
|
230
|
-
message: errorData.message || "Authentication required",
|
|
231
|
-
});
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
return errorData as T;
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
// ✅ Fallback exitoso
|
|
238
|
-
const fallbackData = await parseResponse<T>(fallbackResponse);
|
|
239
|
-
|
|
240
|
-
console.log(`✅ Fallback exitoso para: ${endpoint}`);
|
|
241
|
-
|
|
242
|
-
this.eventEmitter.emit("afterRequest", {
|
|
243
|
-
url: fallbackUrl,
|
|
244
|
-
method,
|
|
245
|
-
response: fallbackData,
|
|
246
|
-
});
|
|
247
|
-
|
|
248
|
-
return fallbackData;
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
// ✅ Otros errores (no 404)
|
|
252
|
-
if (!response.ok) {
|
|
253
|
-
let errorData;
|
|
254
|
-
try {
|
|
255
|
-
errorData = await response.json();
|
|
256
|
-
} catch {
|
|
257
|
-
errorData = { message: response.statusText };
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
console.error(`❌ ${method} ${response.status}:`, errorData);
|
|
261
|
-
|
|
262
|
-
if (response.status === 401) {
|
|
263
|
-
this.eventEmitter.emit("authError", {
|
|
264
|
-
statusCode: 401,
|
|
265
|
-
message: errorData.message || "Authentication required",
|
|
266
|
-
});
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
return errorData as T;
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
// ✅ Respuesta exitosa del primer intento
|
|
273
|
-
const responseData = await parseResponse<T>(response);
|
|
274
|
-
|
|
275
|
-
if (useCache && method === "GET") {
|
|
276
|
-
const cacheKey = generateCacheKey(method, primaryUrl, data);
|
|
277
|
-
const cacheTime = options.cacheTime || undefined;
|
|
278
|
-
this.cache.set(cacheKey, responseData, cacheTime);
|
|
279
|
-
|
|
280
|
-
if (this.debug) {
|
|
281
|
-
console.log(`[SDK-Cache] Set: ${cacheKey}`);
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
this.eventEmitter.emit("afterRequest", {
|
|
286
|
-
url: primaryUrl,
|
|
287
|
-
method,
|
|
288
|
-
response: responseData,
|
|
289
|
-
});
|
|
290
|
-
|
|
291
|
-
return responseData;
|
|
292
|
-
} catch (error) {
|
|
293
|
-
this.eventEmitter.emit("requestError", {
|
|
294
|
-
url: primaryUrl,
|
|
295
|
-
method,
|
|
296
|
-
error,
|
|
297
|
-
});
|
|
298
|
-
|
|
299
|
-
if (error instanceof ApiError) {
|
|
300
|
-
throw error;
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
throw new ApiError((error as Error).message || "Network error", 0, {
|
|
304
|
-
originalError: error,
|
|
305
|
-
});
|
|
306
|
-
}
|
|
307
|
-
}*/
|
|
308
125
|
private async request<T>(
|
|
309
126
|
method: string,
|
|
310
127
|
endpoint: string,
|
|
@@ -312,49 +129,38 @@ export class ApiClient {
|
|
|
312
129
|
params?: Record<string, any>,
|
|
313
130
|
options: RequestOptions = {}
|
|
314
131
|
): Promise<T> {
|
|
315
|
-
const
|
|
132
|
+
const url = buildUrl(this.baseUrl, endpoint, params);
|
|
316
133
|
|
|
317
|
-
const
|
|
134
|
+
const base: HeadersInit = buildHeaders(this.token, {
|
|
318
135
|
"X-Organization": this.organization,
|
|
319
136
|
...(options.headers || {}),
|
|
320
137
|
});
|
|
321
138
|
|
|
322
|
-
|
|
323
|
-
const headersToObject = (headers: Headers): Record<string, string> => {
|
|
324
|
-
const obj: Record<string, string> = {};
|
|
325
|
-
headers.forEach((value, key) => {
|
|
326
|
-
obj[key] = value;
|
|
327
|
-
});
|
|
328
|
-
return obj;
|
|
329
|
-
};
|
|
139
|
+
const headers = new Headers(base);
|
|
330
140
|
|
|
331
|
-
const
|
|
332
|
-
|
|
141
|
+
const legacyPattern = /(^|\/)legacy(\/|$)/i;
|
|
142
|
+
const isLegacyEndpoint = legacyPattern.test(endpoint);
|
|
143
|
+
const isLegacyLogin = /(^|\/)legacy\/login$/i.test(endpoint);
|
|
333
144
|
|
|
145
|
+
if (isLegacyEndpoint && !isLegacyLogin) {
|
|
334
146
|
const legacyToken =
|
|
335
|
-
(window as any).__LEGACY_TOKEN__ ||
|
|
336
|
-
sessionStorage
|
|
147
|
+
(typeof window !== "undefined" && (window as any).__LEGACY_TOKEN__) ||
|
|
148
|
+
(typeof sessionStorage !== "undefined" &&
|
|
149
|
+
sessionStorage.getItem("legacy_token")) ||
|
|
337
150
|
null;
|
|
338
151
|
|
|
339
152
|
if (legacyToken) {
|
|
340
153
|
headers.set("Authorization", `Bearer ${legacyToken}`);
|
|
341
|
-
if (this.debug) {
|
|
342
|
-
console.log("🔐 Using legacy token for:", endpoint);
|
|
343
|
-
}
|
|
344
|
-
} else if (this.token) {
|
|
345
|
-
if (this.debug) {
|
|
346
|
-
console.log("🔐 Using v1 token for:", endpoint);
|
|
347
|
-
}
|
|
348
|
-
} else {
|
|
349
|
-
console.warn("⚠️ No token available for endpoint:", endpoint);
|
|
350
154
|
}
|
|
155
|
+
}
|
|
351
156
|
|
|
352
|
-
|
|
353
|
-
|
|
157
|
+
if (!isLegacyEndpoint && !this.token) {
|
|
158
|
+
headers.delete("Authorization");
|
|
159
|
+
}
|
|
354
160
|
|
|
355
161
|
const useCache = this.cacheEnabled && options.useCache !== false;
|
|
356
162
|
if (useCache && method === "GET") {
|
|
357
|
-
const cacheKey = generateCacheKey(method,
|
|
163
|
+
const cacheKey = generateCacheKey(method, url, data);
|
|
358
164
|
const cachedData = this.cache.get<T>(cacheKey);
|
|
359
165
|
if (cachedData) {
|
|
360
166
|
if (this.debug) {
|
|
@@ -365,105 +171,25 @@ export class ApiClient {
|
|
|
365
171
|
}
|
|
366
172
|
|
|
367
173
|
this.eventEmitter.emit("beforeRequest", {
|
|
368
|
-
url
|
|
174
|
+
url,
|
|
369
175
|
method,
|
|
370
176
|
data,
|
|
371
177
|
});
|
|
372
178
|
|
|
373
179
|
try {
|
|
374
|
-
|
|
375
|
-
if (data && method !== "GET") {
|
|
376
|
-
body = JSON.stringify(data);
|
|
377
|
-
if (this.debug) {
|
|
378
|
-
console.log(`📤 ${method} Body:`, data);
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
// ✅ Primer intento
|
|
383
|
-
const headers1 = createHeaders();
|
|
384
|
-
const fetchOptions1: RequestInit = {
|
|
180
|
+
const fetchOptions: RequestInit = {
|
|
385
181
|
method,
|
|
386
|
-
headers
|
|
387
|
-
credentials:
|
|
388
|
-
...(body && { body }),
|
|
182
|
+
headers,
|
|
183
|
+
credentials: this.credentials,
|
|
389
184
|
};
|
|
390
185
|
|
|
391
|
-
if (
|
|
392
|
-
|
|
393
|
-
console.log(
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
const response = await fetch(primaryUrl, fetchOptions1);
|
|
397
|
-
|
|
398
|
-
if (response.status === 404) {
|
|
399
|
-
console.warn(`⚠️ 404 en ${primaryUrl}, intentando con fallback...`);
|
|
400
|
-
|
|
401
|
-
const fallbackUrl = buildUrl(this.fallbackBaseUrl, endpoint, params);
|
|
402
|
-
|
|
403
|
-
if (this.debug) {
|
|
404
|
-
console.log(`🔄 Retry: ${method} ${fallbackUrl}`);
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
// ✅ Segundo intento
|
|
408
|
-
const headers2 = createHeaders();
|
|
409
|
-
const fetchOptions2: RequestInit = {
|
|
410
|
-
method,
|
|
411
|
-
headers: headers2,
|
|
412
|
-
credentials: "include",
|
|
413
|
-
...(body && { body }),
|
|
414
|
-
};
|
|
415
|
-
|
|
416
|
-
if (this.debug) {
|
|
417
|
-
console.log("📋 Fallback Headers:", headersToObject(headers2)); // ✅ CORREGIDO
|
|
418
|
-
}
|
|
419
|
-
|
|
420
|
-
const fallbackResponse = await fetch(fallbackUrl, fetchOptions2);
|
|
421
|
-
|
|
422
|
-
if (fallbackResponse.status === 204) {
|
|
423
|
-
console.log(`✅ Fallback exitoso (204 No Content): ${endpoint}`);
|
|
424
|
-
return {} as T;
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
if (!fallbackResponse.ok) {
|
|
428
|
-
let errorData;
|
|
429
|
-
try {
|
|
430
|
-
errorData = await fallbackResponse.json();
|
|
431
|
-
} catch {
|
|
432
|
-
errorData = { message: fallbackResponse.statusText };
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
console.error(
|
|
436
|
-
`❌ Fallback falló ${fallbackResponse.status}:`,
|
|
437
|
-
errorData
|
|
438
|
-
);
|
|
439
|
-
|
|
440
|
-
if (fallbackResponse.status === 401) {
|
|
441
|
-
this.eventEmitter.emit("authError", {
|
|
442
|
-
statusCode: 401,
|
|
443
|
-
message: errorData.message || "Authentication required",
|
|
444
|
-
});
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
return errorData as T;
|
|
448
|
-
}
|
|
449
|
-
|
|
450
|
-
const fallbackData = await parseResponse<T>(fallbackResponse);
|
|
451
|
-
|
|
452
|
-
console.log(`✅ Fallback exitoso: ${endpoint}`);
|
|
453
|
-
|
|
454
|
-
this.eventEmitter.emit("afterRequest", {
|
|
455
|
-
url: fallbackUrl,
|
|
456
|
-
method,
|
|
457
|
-
response: fallbackData,
|
|
458
|
-
});
|
|
459
|
-
|
|
460
|
-
return fallbackData;
|
|
186
|
+
if (data && method !== "GET") {
|
|
187
|
+
fetchOptions.body = JSON.stringify(data);
|
|
188
|
+
console.log(`📤 ${method} Body:`, data);
|
|
461
189
|
}
|
|
462
190
|
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
return {} as T;
|
|
466
|
-
}
|
|
191
|
+
console.log(`🌐 ${method} ${url}`, fetchOptions);
|
|
192
|
+
const response = await fetch(url, fetchOptions);
|
|
467
193
|
|
|
468
194
|
if (!response.ok) {
|
|
469
195
|
let errorData;
|
|
@@ -488,7 +214,7 @@ export class ApiClient {
|
|
|
488
214
|
const responseData = await parseResponse<T>(response);
|
|
489
215
|
|
|
490
216
|
if (useCache && method === "GET") {
|
|
491
|
-
const cacheKey = generateCacheKey(method,
|
|
217
|
+
const cacheKey = generateCacheKey(method, url, data);
|
|
492
218
|
const cacheTime = options.cacheTime || undefined;
|
|
493
219
|
this.cache.set(cacheKey, responseData, cacheTime);
|
|
494
220
|
|
|
@@ -498,7 +224,7 @@ export class ApiClient {
|
|
|
498
224
|
}
|
|
499
225
|
|
|
500
226
|
this.eventEmitter.emit("afterRequest", {
|
|
501
|
-
url
|
|
227
|
+
url,
|
|
502
228
|
method,
|
|
503
229
|
response: responseData,
|
|
504
230
|
});
|
|
@@ -506,7 +232,7 @@ export class ApiClient {
|
|
|
506
232
|
return responseData;
|
|
507
233
|
} catch (error) {
|
|
508
234
|
this.eventEmitter.emit("requestError", {
|
|
509
|
-
url
|
|
235
|
+
url,
|
|
510
236
|
method,
|
|
511
237
|
error,
|
|
512
238
|
});
|
package/src/index.ts
CHANGED
|
@@ -15,14 +15,12 @@ import { LogsApi } from "./modules/v1/_logs/logs-api";
|
|
|
15
15
|
// Legacy
|
|
16
16
|
import { AreasApi } from "./modules/legacy/areas/areas-api";
|
|
17
17
|
import { ClassificationTypesApi } from "./modules/legacy/classificationtypes/classificationtypes-api";
|
|
18
|
-
import { LegacyApiClient } from "./core/legacy-api-client";
|
|
19
18
|
|
|
20
19
|
/**
|
|
21
20
|
* Main SDK for consuming CLM API
|
|
22
21
|
*/
|
|
23
22
|
export class ClmSdk {
|
|
24
23
|
private apiClient: ApiClient;
|
|
25
|
-
private legacyClient: LegacyApiClient;
|
|
26
24
|
private eventEmitter: EventEmitter;
|
|
27
25
|
private cacheInstance: Cache;
|
|
28
26
|
|
|
@@ -47,10 +45,6 @@ export class ClmSdk {
|
|
|
47
45
|
this.cacheInstance = new Cache(fullConfig.cache?.ttl);
|
|
48
46
|
this.apiClient = new ApiClient(fullConfig, this.eventEmitter);
|
|
49
47
|
|
|
50
|
-
this.legacyClient = new LegacyApiClient(
|
|
51
|
-
"http://216.250.117.119/ZeroServicesQA/api/v1"
|
|
52
|
-
);
|
|
53
|
-
|
|
54
48
|
// Initialize modules v1
|
|
55
49
|
this.auth = new AuthApi(this.apiClient);
|
|
56
50
|
this.users = new UsersApi(this.apiClient);
|
|
@@ -63,13 +57,6 @@ export class ClmSdk {
|
|
|
63
57
|
this.classificationTypes = new ClassificationTypesApi(this.apiClient);
|
|
64
58
|
}
|
|
65
59
|
|
|
66
|
-
async legacyLogin(userName: string, password: string) {
|
|
67
|
-
return await this.legacyClient.login(userName, password);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
legacyLogout(): void {
|
|
71
|
-
this.legacyClient.logout();
|
|
72
|
-
}
|
|
73
60
|
|
|
74
61
|
/**
|
|
75
62
|
* Access to events system
|
|
@@ -100,6 +87,5 @@ export * from "./modules/v1/notifications/types";
|
|
|
100
87
|
export * from "./modules/v1/_logs/types";
|
|
101
88
|
|
|
102
89
|
// Export legacy types
|
|
103
|
-
export * from "./core/legacy-api-client";
|
|
104
90
|
export * from "./modules/legacy/areas/types";
|
|
105
91
|
export * from "./modules/legacy/classificationtypes/types";
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
import { ApiClient } from "../../../core/api-client";
|
|
1
|
+
import { ApiClient } from "../../../core/api-client";
|
|
3
2
|
import { LoginCredentials, LoginResponse, RefreshTokenRequest } from "./types";
|
|
4
3
|
|
|
4
|
+
type LoginMode = "new" | "legacy";
|
|
5
|
+
|
|
5
6
|
export class AuthApi {
|
|
6
7
|
private apiClient: ApiClient;
|
|
7
8
|
|
|
@@ -9,67 +10,90 @@ export class AuthApi {
|
|
|
9
10
|
this.apiClient = apiClient;
|
|
10
11
|
}
|
|
11
12
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
13
|
+
async login(
|
|
14
|
+
credentials: LoginCredentials,
|
|
15
|
+
mode: LoginMode = "new"
|
|
16
|
+
): Promise<{ ok: boolean }> {
|
|
17
|
+
const path = mode === "legacy" ? "/legacy/login" : "/auth/login";
|
|
18
|
+
|
|
19
|
+
const response = await fetch(`${this.apiClient["baseUrl"]}${path}`, {
|
|
20
|
+
method: "POST",
|
|
21
|
+
headers: {
|
|
22
|
+
"Content-Type": "application/json",
|
|
23
|
+
"X-Organization": this.apiClient["organization"] || "default-org",
|
|
24
|
+
},
|
|
25
|
+
credentials: "include",
|
|
26
|
+
body: JSON.stringify({
|
|
27
|
+
email: credentials.email,
|
|
28
|
+
password: credentials.password,
|
|
29
|
+
}),
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
if (!response.ok) {
|
|
33
|
+
if (response.status === 401) throw new Error("Invalid credentials");
|
|
34
|
+
throw new Error(`Login failed: ${response.status}`);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const data: any = await response.json().catch(() => null);
|
|
38
|
+
|
|
39
|
+
// ✅ Si es legacy, guarda Bearer token para siguientes llamadas legacy
|
|
40
|
+
if (mode === "legacy") {
|
|
41
|
+
const legacyToken = data?.dataResult?.token || data?.token;
|
|
42
|
+
|
|
43
|
+
if (legacyToken) {
|
|
44
|
+
if (typeof sessionStorage !== "undefined") {
|
|
45
|
+
sessionStorage.setItem("legacy_token", legacyToken);
|
|
46
|
+
}
|
|
47
|
+
if (typeof window !== "undefined") {
|
|
48
|
+
(window as any).__LEGACY_TOKEN__ = legacyToken;
|
|
34
49
|
}
|
|
35
|
-
throw new Error(`Login failed: ${response.status}`);
|
|
36
50
|
}
|
|
51
|
+
}
|
|
37
52
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
// No guardar token en memoria, solo usar cookie
|
|
41
|
-
this.apiClient.setToken(null);
|
|
42
|
-
|
|
43
|
-
console.log('✅ Login exitoso, cookie establecida');
|
|
44
|
-
return { ok: true };
|
|
53
|
+
// ✅ Nuevo: cookie HttpOnly, no guardes token en memoria del SDK
|
|
54
|
+
this.apiClient.setToken(null);
|
|
45
55
|
|
|
46
|
-
|
|
47
|
-
console.error('❌ SDK Login error:', error);
|
|
48
|
-
throw error;
|
|
49
|
-
}
|
|
56
|
+
return { ok: true };
|
|
50
57
|
}
|
|
51
58
|
|
|
52
59
|
async refreshToken(request?: RefreshTokenRequest): Promise<LoginResponse> {
|
|
53
|
-
const response = await this.apiClient.post<LoginResponse>(
|
|
54
|
-
|
|
60
|
+
const response = await this.apiClient.post<LoginResponse>(
|
|
61
|
+
"/auth/refresh",
|
|
62
|
+
request
|
|
63
|
+
);
|
|
64
|
+
if ((response as any)?.token)
|
|
65
|
+
this.apiClient.setToken((response as any).token);
|
|
55
66
|
return response;
|
|
56
67
|
}
|
|
57
68
|
|
|
58
69
|
async logout(): Promise<void> {
|
|
59
70
|
try {
|
|
60
71
|
await this.apiClient.post<void>("/auth/logout");
|
|
61
|
-
} catch (error) {
|
|
62
|
-
console.error("Error during logout:", error);
|
|
63
72
|
} finally {
|
|
73
|
+
// limpia token nuevo
|
|
64
74
|
this.apiClient.setToken(null);
|
|
75
|
+
|
|
76
|
+
// limpia legacy token
|
|
77
|
+
if (typeof sessionStorage !== "undefined") {
|
|
78
|
+
sessionStorage.removeItem("legacy_token");
|
|
79
|
+
}
|
|
80
|
+
if (typeof window !== "undefined") {
|
|
81
|
+
delete (window as any).__LEGACY_TOKEN__;
|
|
82
|
+
}
|
|
65
83
|
}
|
|
66
84
|
}
|
|
67
85
|
|
|
68
86
|
isAuthenticated(): boolean {
|
|
69
|
-
|
|
87
|
+
const hasToken = this.apiClient.getToken() !== null;
|
|
88
|
+
const hasLegacy =
|
|
89
|
+
(typeof sessionStorage !== "undefined" &&
|
|
90
|
+
!!sessionStorage.getItem("legacy_token")) ||
|
|
91
|
+
(typeof window !== "undefined" && !!(window as any).__LEGACY_TOKEN__);
|
|
92
|
+
|
|
93
|
+
return hasToken || hasLegacy;
|
|
70
94
|
}
|
|
71
95
|
|
|
72
96
|
setToken(token: string | null): void {
|
|
73
97
|
this.apiClient.setToken(token);
|
|
74
98
|
}
|
|
75
|
-
}
|
|
99
|
+
}
|
package/src/types/sdk.ts
CHANGED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
export interface LegacyLoginRequest {
|
|
2
|
-
userName: string;
|
|
3
|
-
password: string;
|
|
4
|
-
}
|
|
5
|
-
export interface LegacyLoginResponse {
|
|
6
|
-
dataResult: {
|
|
7
|
-
token: string;
|
|
8
|
-
userType: string;
|
|
9
|
-
userId: string;
|
|
10
|
-
userName: string;
|
|
11
|
-
area: string;
|
|
12
|
-
id_Area: number;
|
|
13
|
-
id_Role: string;
|
|
14
|
-
};
|
|
15
|
-
statusResponse: {
|
|
16
|
-
code: number;
|
|
17
|
-
success: boolean;
|
|
18
|
-
message: string;
|
|
19
|
-
};
|
|
20
|
-
}
|
|
21
|
-
export declare class LegacyApiClient {
|
|
22
|
-
private baseUrl;
|
|
23
|
-
constructor(baseUrl: string);
|
|
24
|
-
login(userName: string, password: string): Promise<LegacyLoginResponse>;
|
|
25
|
-
logout(): void;
|
|
26
|
-
}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
export class LegacyApiClient {
|
|
2
|
-
constructor(baseUrl) {
|
|
3
|
-
this.baseUrl = baseUrl;
|
|
4
|
-
}
|
|
5
|
-
async login(userName, password) {
|
|
6
|
-
var _a, _b;
|
|
7
|
-
const url = `${this.baseUrl}/auth/login`;
|
|
8
|
-
const response = await fetch(url, {
|
|
9
|
-
method: 'POST',
|
|
10
|
-
headers: { 'Content-Type': 'application/json' },
|
|
11
|
-
credentials: 'include',
|
|
12
|
-
body: JSON.stringify({ userName, password }),
|
|
13
|
-
});
|
|
14
|
-
if (!response.ok) {
|
|
15
|
-
const errorData = await response.json().catch(() => ({
|
|
16
|
-
statusResponse: {
|
|
17
|
-
code: response.status,
|
|
18
|
-
success: false,
|
|
19
|
-
message: response.statusText
|
|
20
|
-
}
|
|
21
|
-
}));
|
|
22
|
-
throw new Error(((_a = errorData.statusResponse) === null || _a === void 0 ? void 0 : _a.message) || 'Legacy login failed');
|
|
23
|
-
}
|
|
24
|
-
const data = await response.json();
|
|
25
|
-
if ((_b = data.dataResult) === null || _b === void 0 ? void 0 : _b.token) {
|
|
26
|
-
sessionStorage.setItem('legacy_token', data.dataResult.token);
|
|
27
|
-
window.__LEGACY_TOKEN__ = data.dataResult.token;
|
|
28
|
-
}
|
|
29
|
-
return data;
|
|
30
|
-
}
|
|
31
|
-
logout() {
|
|
32
|
-
sessionStorage.removeItem('legacy_token');
|
|
33
|
-
delete window.__LEGACY_TOKEN__;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
export interface LegacyLoginRequest {
|
|
2
|
-
userName: string;
|
|
3
|
-
password: string;
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
export interface LegacyLoginResponse {
|
|
7
|
-
dataResult: {
|
|
8
|
-
token: string;
|
|
9
|
-
userType: string;
|
|
10
|
-
userId: string;
|
|
11
|
-
userName: string;
|
|
12
|
-
area: string;
|
|
13
|
-
id_Area: number;
|
|
14
|
-
id_Role: string;
|
|
15
|
-
};
|
|
16
|
-
statusResponse: {
|
|
17
|
-
code: number;
|
|
18
|
-
success: boolean;
|
|
19
|
-
message: string;
|
|
20
|
-
};
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export class LegacyApiClient {
|
|
24
|
-
private baseUrl: string;
|
|
25
|
-
|
|
26
|
-
constructor(baseUrl: string) {
|
|
27
|
-
this.baseUrl = baseUrl;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
async login(userName: string, password: string): Promise<LegacyLoginResponse> {
|
|
31
|
-
const url = `${this.baseUrl}/auth/login`;
|
|
32
|
-
|
|
33
|
-
const response = await fetch(url, {
|
|
34
|
-
method: 'POST',
|
|
35
|
-
headers: { 'Content-Type': 'application/json' },
|
|
36
|
-
credentials: 'include',
|
|
37
|
-
body: JSON.stringify({ userName, password }),
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
if (!response.ok) {
|
|
41
|
-
const errorData = await response.json().catch(() => ({
|
|
42
|
-
statusResponse: {
|
|
43
|
-
code: response.status,
|
|
44
|
-
success: false,
|
|
45
|
-
message: response.statusText
|
|
46
|
-
}
|
|
47
|
-
}));
|
|
48
|
-
|
|
49
|
-
throw new Error(errorData.statusResponse?.message || 'Legacy login failed');
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
const data: LegacyLoginResponse = await response.json();
|
|
53
|
-
|
|
54
|
-
if (data.dataResult?.token) {
|
|
55
|
-
sessionStorage.setItem('legacy_token', data.dataResult.token);
|
|
56
|
-
(window as any).__LEGACY_TOKEN__ = data.dataResult.token;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
return data;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
logout(): void {
|
|
63
|
-
sessionStorage.removeItem('legacy_token');
|
|
64
|
-
delete (window as any).__LEGACY_TOKEN__;
|
|
65
|
-
}
|
|
66
|
-
}
|