@zerosls/clm-sdk 2.1.0 → 2.1.2
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.js +159 -37
- package/dist/modules/v1/auth/auth-api.d.ts +0 -1
- package/dist/modules/v1/auth/auth-api.js +99 -11
- package/package.json +1 -1
- package/src/core/api-client.ts +144 -22
- package/src/modules/v1/auth/auth-api.ts +97 -10
package/dist/core/api-client.js
CHANGED
|
@@ -55,27 +55,168 @@ export class ApiClient {
|
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
|
+
/*private async request<T>(
|
|
59
|
+
method: string,
|
|
60
|
+
endpoint: string,
|
|
61
|
+
data?: any,
|
|
62
|
+
params?: Record<string, any>,
|
|
63
|
+
options: RequestOptions = {}
|
|
64
|
+
): Promise<T> {
|
|
65
|
+
const url = buildUrl(this.baseUrl, endpoint, params);
|
|
66
|
+
|
|
67
|
+
const base: HeadersInit = buildHeaders(this.token, {
|
|
68
|
+
"X-Organization": this.organization,
|
|
69
|
+
...(options.headers || {}),
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
const headers = new Headers(base);
|
|
73
|
+
|
|
74
|
+
const legacyPattern = /(^|\/)legacy(\/|$)/i;
|
|
75
|
+
const isLegacyEndpoint = legacyPattern.test(endpoint);
|
|
76
|
+
const isLegacyLogin = /(^|\/)legacy\/login$/i.test(endpoint);
|
|
77
|
+
|
|
78
|
+
if (isLegacyEndpoint && !isLegacyLogin) {
|
|
79
|
+
const legacyToken =
|
|
80
|
+
(typeof window !== "undefined" && (window as any).__LEGACY_TOKEN__) ||
|
|
81
|
+
(typeof sessionStorage !== "undefined" &&
|
|
82
|
+
sessionStorage.getItem("legacy_token")) ||
|
|
83
|
+
null;
|
|
84
|
+
|
|
85
|
+
if (legacyToken) {
|
|
86
|
+
headers.set("Authorization", `Bearer ${legacyToken}`);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (!isLegacyEndpoint && !this.token) {
|
|
91
|
+
headers.delete("Authorization");
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const useCache = this.cacheEnabled && options.useCache !== false;
|
|
95
|
+
if (useCache && method === "GET") {
|
|
96
|
+
const cacheKey = generateCacheKey(method, url, data);
|
|
97
|
+
const cachedData = this.cache.get<T>(cacheKey);
|
|
98
|
+
if (cachedData) {
|
|
99
|
+
if (this.debug) {
|
|
100
|
+
console.log(`[SDK-Cache] Hit: ${cacheKey}`);
|
|
101
|
+
}
|
|
102
|
+
return cachedData;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
this.eventEmitter.emit("beforeRequest", {
|
|
107
|
+
url,
|
|
108
|
+
method,
|
|
109
|
+
data,
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
try {
|
|
113
|
+
const fetchOptions: RequestInit = {
|
|
114
|
+
method,
|
|
115
|
+
headers,
|
|
116
|
+
credentials: this.credentials,
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
if (data && method !== "GET") {
|
|
120
|
+
fetchOptions.body = JSON.stringify(data);
|
|
121
|
+
console.log(`📤 ${method} Body:`, data);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
console.log(`🌐 ${method} ${url}`, fetchOptions);
|
|
125
|
+
|
|
126
|
+
const response = await fetch(url, fetchOptions);
|
|
127
|
+
|
|
128
|
+
if (!response.ok) {
|
|
129
|
+
let errorData;
|
|
130
|
+
try {
|
|
131
|
+
errorData = await response.json();
|
|
132
|
+
} catch {
|
|
133
|
+
errorData = { message: response.statusText };
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
console.error(`❌ ${method} ${response.status}:`, errorData);
|
|
137
|
+
|
|
138
|
+
if (response.status === 401) {
|
|
139
|
+
this.eventEmitter.emit("authError", {
|
|
140
|
+
statusCode: 401,
|
|
141
|
+
message: errorData.message || "Authentication required",
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return errorData as T;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const responseData = await parseResponse<T>(response);
|
|
149
|
+
|
|
150
|
+
if (useCache && method === "GET") {
|
|
151
|
+
const cacheKey = generateCacheKey(method, url, data);
|
|
152
|
+
const cacheTime = options.cacheTime || undefined;
|
|
153
|
+
this.cache.set(cacheKey, responseData, cacheTime);
|
|
154
|
+
|
|
155
|
+
if (this.debug) {
|
|
156
|
+
console.log(`[SDK-Cache] Set: ${cacheKey}`);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
this.eventEmitter.emit("afterRequest", {
|
|
161
|
+
url,
|
|
162
|
+
method,
|
|
163
|
+
response: responseData,
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
return responseData;
|
|
167
|
+
} catch (error) {
|
|
168
|
+
this.eventEmitter.emit("requestError", {
|
|
169
|
+
url,
|
|
170
|
+
method,
|
|
171
|
+
error,
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
if (error instanceof ApiError) {
|
|
175
|
+
throw error;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
throw new ApiError((error as Error).message || "Network error", 0, {
|
|
179
|
+
originalError: error,
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
}*/
|
|
58
183
|
async request(method, endpoint, data, params, options = {}) {
|
|
59
184
|
const url = buildUrl(this.baseUrl, endpoint, params);
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
const legacyPattern = /(^|\/)legacy(\/|$)/i;
|
|
66
|
-
const isLegacyEndpoint = legacyPattern.test(endpoint);
|
|
67
|
-
const isLegacyLogin = /(^|\/)legacy\/login$/i.test(endpoint);
|
|
185
|
+
// ✅ Detecta si es legacy
|
|
186
|
+
const isLegacyEndpoint = endpoint.includes("/legacy/");
|
|
187
|
+
const isLegacyLogin = endpoint.endsWith("/legacy/login");
|
|
188
|
+
// ✅ Elige el token correcto según el endpoint
|
|
189
|
+
let token = null;
|
|
68
190
|
if (isLegacyEndpoint && !isLegacyLogin) {
|
|
69
|
-
|
|
191
|
+
// Usa token legacy para endpoints legacy
|
|
192
|
+
token =
|
|
70
193
|
(typeof sessionStorage !== "undefined" &&
|
|
71
194
|
sessionStorage.getItem("legacy_token")) ||
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
headers.set("Authorization", `Bearer ${legacyToken}`);
|
|
75
|
-
}
|
|
195
|
+
(typeof window !== "undefined" && window.__LEGACY_TOKEN__) ||
|
|
196
|
+
null;
|
|
76
197
|
}
|
|
77
|
-
if (!isLegacyEndpoint
|
|
78
|
-
|
|
198
|
+
else if (!isLegacyEndpoint) {
|
|
199
|
+
// Usa token nuevo para endpoints modernos
|
|
200
|
+
token =
|
|
201
|
+
(typeof sessionStorage !== "undefined" &&
|
|
202
|
+
sessionStorage.getItem("auth_token")) ||
|
|
203
|
+
(typeof window !== "undefined" && window.__AUTH_TOKEN__) ||
|
|
204
|
+
null;
|
|
205
|
+
}
|
|
206
|
+
// ✅ Construye headers con el token correcto
|
|
207
|
+
const base = buildHeaders(token, {
|
|
208
|
+
"X-Organization": this.organization,
|
|
209
|
+
...(options.headers || {}),
|
|
210
|
+
});
|
|
211
|
+
const headers = new Headers(base);
|
|
212
|
+
// ✅ Log para debug
|
|
213
|
+
if (this.debug) {
|
|
214
|
+
console.log("🔍 Request:", {
|
|
215
|
+
endpoint,
|
|
216
|
+
isLegacy: isLegacyEndpoint,
|
|
217
|
+
hasToken: !!token,
|
|
218
|
+
tokenType: isLegacyEndpoint ? "legacy" : "new",
|
|
219
|
+
});
|
|
79
220
|
}
|
|
80
221
|
const useCache = this.cacheEnabled && options.useCache !== false;
|
|
81
222
|
if (useCache && method === "GET") {
|
|
@@ -93,14 +234,6 @@ export class ApiClient {
|
|
|
93
234
|
method,
|
|
94
235
|
data,
|
|
95
236
|
});
|
|
96
|
-
// Colocado
|
|
97
|
-
if (this.debug) {
|
|
98
|
-
console.log("🍪 Cookies Debug:", {
|
|
99
|
-
credentials: this.credentials,
|
|
100
|
-
documentCookie: typeof document !== "undefined" ? document.cookie : "N/A",
|
|
101
|
-
url: url,
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
237
|
try {
|
|
105
238
|
const fetchOptions = {
|
|
106
239
|
method,
|
|
@@ -109,21 +242,9 @@ export class ApiClient {
|
|
|
109
242
|
};
|
|
110
243
|
if (data && method !== "GET") {
|
|
111
244
|
fetchOptions.body = JSON.stringify(data);
|
|
112
|
-
console.log(`📤 ${method} Body:`, data);
|
|
113
245
|
}
|
|
114
|
-
console.log(`🌐 ${method} ${url}
|
|
115
|
-
// Colocado
|
|
116
|
-
console.log(`🌐 ${method} ${url}`, {
|
|
117
|
-
...fetchOptions,
|
|
118
|
-
cookieHeader: headers.get("Cookie"),
|
|
119
|
-
});
|
|
246
|
+
console.log(`🌐 ${method} ${url}`);
|
|
120
247
|
const response = await fetch(url, fetchOptions);
|
|
121
|
-
// Colocado
|
|
122
|
-
if (this.debug) {
|
|
123
|
-
console.log("📥 Response Headers:", {
|
|
124
|
-
setCookie: response.headers.get("Set-Cookie"),
|
|
125
|
-
});
|
|
126
|
-
}
|
|
127
248
|
if (!response.ok) {
|
|
128
249
|
let errorData;
|
|
129
250
|
try {
|
|
@@ -139,7 +260,7 @@ export class ApiClient {
|
|
|
139
260
|
message: errorData.message || "Authentication required",
|
|
140
261
|
});
|
|
141
262
|
}
|
|
142
|
-
|
|
263
|
+
throw new ApiError(errorData.message || response.statusText, response.status, errorData);
|
|
143
264
|
}
|
|
144
265
|
const responseData = await parseResponse(response);
|
|
145
266
|
if (useCache && method === "GET") {
|
|
@@ -158,6 +279,7 @@ export class ApiClient {
|
|
|
158
279
|
return responseData;
|
|
159
280
|
}
|
|
160
281
|
catch (error) {
|
|
282
|
+
console.error(`💥 Request failed:`, { method, url, error });
|
|
161
283
|
this.eventEmitter.emit("requestError", {
|
|
162
284
|
url,
|
|
163
285
|
method,
|
|
@@ -2,9 +2,55 @@ export class AuthApi {
|
|
|
2
2
|
constructor(apiClient) {
|
|
3
3
|
this.apiClient = apiClient;
|
|
4
4
|
}
|
|
5
|
+
/*async login(
|
|
6
|
+
credentials: LoginCredentials,
|
|
7
|
+
mode: LoginMode = "new"
|
|
8
|
+
): Promise<{ ok: boolean }> {
|
|
9
|
+
const path = mode === "legacy" ? "/legacy/login" : "/auth/login";
|
|
10
|
+
|
|
11
|
+
const response = await fetch(`${this.apiClient["baseUrl"]}${path}`, {
|
|
12
|
+
method: "POST",
|
|
13
|
+
headers: {
|
|
14
|
+
"Content-Type": "application/json",
|
|
15
|
+
"X-Organization": this.apiClient["organization"] || "default-org",
|
|
16
|
+
},
|
|
17
|
+
credentials: "include",
|
|
18
|
+
body: JSON.stringify({
|
|
19
|
+
email: credentials.email,
|
|
20
|
+
password: credentials.password,
|
|
21
|
+
}),
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
if (!response.ok) {
|
|
25
|
+
if (response.status === 401) throw new Error("Invalid credentials");
|
|
26
|
+
throw new Error(`Login failed: ${response.status}`);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const data: any = await response.json().catch(() => null);
|
|
30
|
+
|
|
31
|
+
// ✅ Si es legacy, guarda Bearer token para siguientes llamadas legacy
|
|
32
|
+
if (mode === "legacy") {
|
|
33
|
+
const legacyToken = data?.dataResult?.token || data?.token;
|
|
34
|
+
|
|
35
|
+
if (legacyToken) {
|
|
36
|
+
if (typeof sessionStorage !== "undefined") {
|
|
37
|
+
sessionStorage.setItem("legacy_token", legacyToken);
|
|
38
|
+
}
|
|
39
|
+
if (typeof window !== "undefined") {
|
|
40
|
+
(window as any).__LEGACY_TOKEN__ = legacyToken;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// ✅ Nuevo: cookie HttpOnly, no guardes token en memoria del SDK
|
|
46
|
+
this.apiClient.setToken(null);
|
|
47
|
+
|
|
48
|
+
return { ok: true };
|
|
49
|
+
}*/
|
|
5
50
|
async login(credentials, mode = "new") {
|
|
6
51
|
var _a;
|
|
7
52
|
const path = mode === "legacy" ? "/legacy/login" : "/auth/login";
|
|
53
|
+
console.log(`🔐 Login attempt (${mode}):`, credentials.email);
|
|
8
54
|
const response = await fetch(`${this.apiClient["baseUrl"]}${path}`, {
|
|
9
55
|
method: "POST",
|
|
10
56
|
headers: {
|
|
@@ -23,8 +69,8 @@ export class AuthApi {
|
|
|
23
69
|
throw new Error(`Login failed: ${response.status}`);
|
|
24
70
|
}
|
|
25
71
|
const data = await response.json().catch(() => null);
|
|
26
|
-
// ✅ Si es legacy, guarda Bearer token para siguientes llamadas legacy
|
|
27
72
|
if (mode === "legacy") {
|
|
73
|
+
// ✅ Token LEGACY (del sistema viejo)
|
|
28
74
|
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
75
|
if (legacyToken) {
|
|
30
76
|
if (typeof sessionStorage !== "undefined") {
|
|
@@ -33,9 +79,28 @@ export class AuthApi {
|
|
|
33
79
|
if (typeof window !== "undefined") {
|
|
34
80
|
window.__LEGACY_TOKEN__ = legacyToken;
|
|
35
81
|
}
|
|
82
|
+
console.log("✅ Legacy token saved");
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
console.warn("⚠️ No legacy token received");
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
// ✅ Token NUEVO (del sistema moderno)
|
|
90
|
+
const newToken = data === null || data === void 0 ? void 0 : data.token;
|
|
91
|
+
if (newToken) {
|
|
92
|
+
if (typeof sessionStorage !== "undefined") {
|
|
93
|
+
sessionStorage.setItem("auth_token", newToken);
|
|
94
|
+
}
|
|
95
|
+
if (typeof window !== "undefined") {
|
|
96
|
+
window.__AUTH_TOKEN__ = newToken;
|
|
97
|
+
}
|
|
98
|
+
console.log("✅ Auth token saved");
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
console.warn("⚠️ No auth token received");
|
|
36
102
|
}
|
|
37
103
|
}
|
|
38
|
-
// ✅ Nuevo: cookie HttpOnly, no guardes token en memoria del SDK
|
|
39
104
|
this.apiClient.setToken(null);
|
|
40
105
|
return { ok: true };
|
|
41
106
|
}
|
|
@@ -45,29 +110,52 @@ export class AuthApi {
|
|
|
45
110
|
this.apiClient.setToken(response.token);
|
|
46
111
|
return response;
|
|
47
112
|
}
|
|
113
|
+
/*async logout(): Promise<void> {
|
|
114
|
+
try {
|
|
115
|
+
await this.apiClient.post<void>("/auth/logout");
|
|
116
|
+
} finally {
|
|
117
|
+
// limpia token nuevo
|
|
118
|
+
this.apiClient.setToken(null);
|
|
119
|
+
|
|
120
|
+
// limpia legacy token
|
|
121
|
+
if (typeof sessionStorage !== "undefined") {
|
|
122
|
+
sessionStorage.removeItem("legacy_token");
|
|
123
|
+
}
|
|
124
|
+
if (typeof window !== "undefined") {
|
|
125
|
+
delete (window as any).__LEGACY_TOKEN__;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}*/
|
|
48
129
|
async logout() {
|
|
49
130
|
try {
|
|
50
131
|
await this.apiClient.post("/auth/logout");
|
|
132
|
+
console.log("✅ Logout successful");
|
|
133
|
+
}
|
|
134
|
+
catch (error) {
|
|
135
|
+
console.error("❌ Logout error:", error);
|
|
51
136
|
}
|
|
52
137
|
finally {
|
|
53
|
-
//
|
|
138
|
+
// ✅ Limpia AMBOS tokens (nuevo y legacy)
|
|
54
139
|
this.apiClient.setToken(null);
|
|
55
|
-
// limpia legacy token
|
|
56
140
|
if (typeof sessionStorage !== "undefined") {
|
|
141
|
+
sessionStorage.removeItem("auth_token"); // ✅ Agrega esto
|
|
57
142
|
sessionStorage.removeItem("legacy_token");
|
|
58
143
|
}
|
|
59
144
|
if (typeof window !== "undefined") {
|
|
145
|
+
delete window.__AUTH_TOKEN__; // ✅ Agrega esto
|
|
60
146
|
delete window.__LEGACY_TOKEN__;
|
|
61
147
|
}
|
|
62
148
|
}
|
|
63
149
|
}
|
|
64
|
-
isAuthenticated() {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
150
|
+
//isAuthenticated(): boolean {
|
|
151
|
+
// const hasToken = this.apiClient.getToken() !== null;
|
|
152
|
+
// const hasLegacy =
|
|
153
|
+
// (typeof sessionStorage !== "undefined" &&
|
|
154
|
+
// !!sessionStorage.getItem("legacy_token")) ||
|
|
155
|
+
// (typeof window !== "undefined" && !!(window as any).__LEGACY_TOKEN__);
|
|
156
|
+
//
|
|
157
|
+
// return hasToken || hasLegacy;
|
|
158
|
+
//}
|
|
71
159
|
setToken(token) {
|
|
72
160
|
this.apiClient.setToken(token);
|
|
73
161
|
}
|
package/package.json
CHANGED
package/src/core/api-client.ts
CHANGED
|
@@ -122,7 +122,7 @@ export class ApiClient {
|
|
|
122
122
|
}
|
|
123
123
|
}
|
|
124
124
|
|
|
125
|
-
private async request<T>(
|
|
125
|
+
/*private async request<T>(
|
|
126
126
|
method: string,
|
|
127
127
|
endpoint: string,
|
|
128
128
|
data?: any,
|
|
@@ -176,16 +176,6 @@ export class ApiClient {
|
|
|
176
176
|
data,
|
|
177
177
|
});
|
|
178
178
|
|
|
179
|
-
// Colocado
|
|
180
|
-
if (this.debug) {
|
|
181
|
-
console.log("🍪 Cookies Debug:", {
|
|
182
|
-
credentials: this.credentials,
|
|
183
|
-
documentCookie:
|
|
184
|
-
typeof document !== "undefined" ? document.cookie : "N/A",
|
|
185
|
-
url: url,
|
|
186
|
-
});
|
|
187
|
-
}
|
|
188
|
-
|
|
189
179
|
try {
|
|
190
180
|
const fetchOptions: RequestInit = {
|
|
191
181
|
method,
|
|
@@ -200,20 +190,146 @@ export class ApiClient {
|
|
|
200
190
|
|
|
201
191
|
console.log(`🌐 ${method} ${url}`, fetchOptions);
|
|
202
192
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
193
|
+
const response = await fetch(url, fetchOptions);
|
|
194
|
+
|
|
195
|
+
if (!response.ok) {
|
|
196
|
+
let errorData;
|
|
197
|
+
try {
|
|
198
|
+
errorData = await response.json();
|
|
199
|
+
} catch {
|
|
200
|
+
errorData = { message: response.statusText };
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
console.error(`❌ ${method} ${response.status}:`, errorData);
|
|
204
|
+
|
|
205
|
+
if (response.status === 401) {
|
|
206
|
+
this.eventEmitter.emit("authError", {
|
|
207
|
+
statusCode: 401,
|
|
208
|
+
message: errorData.message || "Authentication required",
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
return errorData as T;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
const responseData = await parseResponse<T>(response);
|
|
216
|
+
|
|
217
|
+
if (useCache && method === "GET") {
|
|
218
|
+
const cacheKey = generateCacheKey(method, url, data);
|
|
219
|
+
const cacheTime = options.cacheTime || undefined;
|
|
220
|
+
this.cache.set(cacheKey, responseData, cacheTime);
|
|
221
|
+
|
|
222
|
+
if (this.debug) {
|
|
223
|
+
console.log(`[SDK-Cache] Set: ${cacheKey}`);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
this.eventEmitter.emit("afterRequest", {
|
|
228
|
+
url,
|
|
229
|
+
method,
|
|
230
|
+
response: responseData,
|
|
207
231
|
});
|
|
208
232
|
|
|
209
|
-
|
|
233
|
+
return responseData;
|
|
234
|
+
} catch (error) {
|
|
235
|
+
this.eventEmitter.emit("requestError", {
|
|
236
|
+
url,
|
|
237
|
+
method,
|
|
238
|
+
error,
|
|
239
|
+
});
|
|
210
240
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
241
|
+
if (error instanceof ApiError) {
|
|
242
|
+
throw error;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
throw new ApiError((error as Error).message || "Network error", 0, {
|
|
246
|
+
originalError: error,
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
}*/
|
|
250
|
+
|
|
251
|
+
private async request<T>(
|
|
252
|
+
method: string,
|
|
253
|
+
endpoint: string,
|
|
254
|
+
data?: any,
|
|
255
|
+
params?: Record<string, any>,
|
|
256
|
+
options: RequestOptions = {}
|
|
257
|
+
): Promise<T> {
|
|
258
|
+
const url = buildUrl(this.baseUrl, endpoint, params);
|
|
259
|
+
|
|
260
|
+
// ✅ Detecta si es legacy
|
|
261
|
+
const isLegacyEndpoint = endpoint.includes("/legacy/");
|
|
262
|
+
const isLegacyLogin = endpoint.endsWith("/legacy/login");
|
|
263
|
+
|
|
264
|
+
// ✅ Elige el token correcto según el endpoint
|
|
265
|
+
let token: string | null = null;
|
|
266
|
+
|
|
267
|
+
if (isLegacyEndpoint && !isLegacyLogin) {
|
|
268
|
+
// Usa token legacy para endpoints legacy
|
|
269
|
+
token =
|
|
270
|
+
(typeof sessionStorage !== "undefined" &&
|
|
271
|
+
sessionStorage.getItem("legacy_token")) ||
|
|
272
|
+
(typeof window !== "undefined" && (window as any).__LEGACY_TOKEN__) ||
|
|
273
|
+
null;
|
|
274
|
+
} else if (!isLegacyEndpoint) {
|
|
275
|
+
// Usa token nuevo para endpoints modernos
|
|
276
|
+
token =
|
|
277
|
+
(typeof sessionStorage !== "undefined" &&
|
|
278
|
+
sessionStorage.getItem("auth_token")) ||
|
|
279
|
+
(typeof window !== "undefined" && (window as any).__AUTH_TOKEN__) ||
|
|
280
|
+
null;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
// ✅ Construye headers con el token correcto
|
|
284
|
+
const base: HeadersInit = buildHeaders(token, {
|
|
285
|
+
"X-Organization": this.organization,
|
|
286
|
+
...(options.headers || {}),
|
|
287
|
+
});
|
|
288
|
+
|
|
289
|
+
const headers = new Headers(base);
|
|
290
|
+
|
|
291
|
+
// ✅ Log para debug
|
|
292
|
+
if (this.debug) {
|
|
293
|
+
console.log("🔍 Request:", {
|
|
294
|
+
endpoint,
|
|
295
|
+
isLegacy: isLegacyEndpoint,
|
|
296
|
+
hasToken: !!token,
|
|
297
|
+
tokenType: isLegacyEndpoint ? "legacy" : "new",
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
const useCache = this.cacheEnabled && options.useCache !== false;
|
|
302
|
+
if (useCache && method === "GET") {
|
|
303
|
+
const cacheKey = generateCacheKey(method, url, data);
|
|
304
|
+
const cachedData = this.cache.get<T>(cacheKey);
|
|
305
|
+
if (cachedData) {
|
|
306
|
+
if (this.debug) {
|
|
307
|
+
console.log(`[SDK-Cache] Hit: ${cacheKey}`);
|
|
308
|
+
}
|
|
309
|
+
return cachedData;
|
|
216
310
|
}
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
this.eventEmitter.emit("beforeRequest", {
|
|
314
|
+
url,
|
|
315
|
+
method,
|
|
316
|
+
data,
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
try {
|
|
320
|
+
const fetchOptions: RequestInit = {
|
|
321
|
+
method,
|
|
322
|
+
headers,
|
|
323
|
+
credentials: this.credentials,
|
|
324
|
+
};
|
|
325
|
+
|
|
326
|
+
if (data && method !== "GET") {
|
|
327
|
+
fetchOptions.body = JSON.stringify(data);
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
console.log(`🌐 ${method} ${url}`);
|
|
331
|
+
|
|
332
|
+
const response = await fetch(url, fetchOptions);
|
|
217
333
|
|
|
218
334
|
if (!response.ok) {
|
|
219
335
|
let errorData;
|
|
@@ -232,7 +348,11 @@ export class ApiClient {
|
|
|
232
348
|
});
|
|
233
349
|
}
|
|
234
350
|
|
|
235
|
-
|
|
351
|
+
throw new ApiError(
|
|
352
|
+
errorData.message || response.statusText,
|
|
353
|
+
response.status,
|
|
354
|
+
errorData
|
|
355
|
+
);
|
|
236
356
|
}
|
|
237
357
|
|
|
238
358
|
const responseData = await parseResponse<T>(response);
|
|
@@ -255,6 +375,8 @@ export class ApiClient {
|
|
|
255
375
|
|
|
256
376
|
return responseData;
|
|
257
377
|
} catch (error) {
|
|
378
|
+
console.error(`💥 Request failed:`, { method, url, error });
|
|
379
|
+
|
|
258
380
|
this.eventEmitter.emit("requestError", {
|
|
259
381
|
url,
|
|
260
382
|
method,
|
|
@@ -10,7 +10,7 @@ export class AuthApi {
|
|
|
10
10
|
this.apiClient = apiClient;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
async login(
|
|
13
|
+
/*async login(
|
|
14
14
|
credentials: LoginCredentials,
|
|
15
15
|
mode: LoginMode = "new"
|
|
16
16
|
): Promise<{ ok: boolean }> {
|
|
@@ -53,6 +53,71 @@ export class AuthApi {
|
|
|
53
53
|
// ✅ Nuevo: cookie HttpOnly, no guardes token en memoria del SDK
|
|
54
54
|
this.apiClient.setToken(null);
|
|
55
55
|
|
|
56
|
+
return { ok: true };
|
|
57
|
+
}*/
|
|
58
|
+
|
|
59
|
+
async login(
|
|
60
|
+
credentials: LoginCredentials,
|
|
61
|
+
mode: LoginMode = "new"
|
|
62
|
+
): Promise<{ ok: boolean }> {
|
|
63
|
+
const path = mode === "legacy" ? "/legacy/login" : "/auth/login";
|
|
64
|
+
|
|
65
|
+
console.log(`🔐 Login attempt (${mode}):`, credentials.email);
|
|
66
|
+
|
|
67
|
+
const response = await fetch(`${this.apiClient["baseUrl"]}${path}`, {
|
|
68
|
+
method: "POST",
|
|
69
|
+
headers: {
|
|
70
|
+
"Content-Type": "application/json",
|
|
71
|
+
"X-Organization": this.apiClient["organization"] || "default-org",
|
|
72
|
+
},
|
|
73
|
+
credentials: "include",
|
|
74
|
+
body: JSON.stringify({
|
|
75
|
+
email: credentials.email,
|
|
76
|
+
password: credentials.password,
|
|
77
|
+
}),
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
if (!response.ok) {
|
|
81
|
+
if (response.status === 401) throw new Error("Invalid credentials");
|
|
82
|
+
throw new Error(`Login failed: ${response.status}`);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const data: any = await response.json().catch(() => null);
|
|
86
|
+
|
|
87
|
+
if (mode === "legacy") {
|
|
88
|
+
// ✅ Token LEGACY (del sistema viejo)
|
|
89
|
+
const legacyToken = data?.dataResult?.token || data?.token;
|
|
90
|
+
|
|
91
|
+
if (legacyToken) {
|
|
92
|
+
if (typeof sessionStorage !== "undefined") {
|
|
93
|
+
sessionStorage.setItem("legacy_token", legacyToken);
|
|
94
|
+
}
|
|
95
|
+
if (typeof window !== "undefined") {
|
|
96
|
+
(window as any).__LEGACY_TOKEN__ = legacyToken;
|
|
97
|
+
}
|
|
98
|
+
console.log("✅ Legacy token saved");
|
|
99
|
+
} else {
|
|
100
|
+
console.warn("⚠️ No legacy token received");
|
|
101
|
+
}
|
|
102
|
+
} else {
|
|
103
|
+
// ✅ Token NUEVO (del sistema moderno)
|
|
104
|
+
const newToken = data?.token;
|
|
105
|
+
|
|
106
|
+
if (newToken) {
|
|
107
|
+
if (typeof sessionStorage !== "undefined") {
|
|
108
|
+
sessionStorage.setItem("auth_token", newToken);
|
|
109
|
+
}
|
|
110
|
+
if (typeof window !== "undefined") {
|
|
111
|
+
(window as any).__AUTH_TOKEN__ = newToken;
|
|
112
|
+
}
|
|
113
|
+
console.log("✅ Auth token saved");
|
|
114
|
+
} else {
|
|
115
|
+
console.warn("⚠️ No auth token received");
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
this.apiClient.setToken(null);
|
|
120
|
+
|
|
56
121
|
return { ok: true };
|
|
57
122
|
}
|
|
58
123
|
|
|
@@ -66,7 +131,7 @@ export class AuthApi {
|
|
|
66
131
|
return response;
|
|
67
132
|
}
|
|
68
133
|
|
|
69
|
-
async logout(): Promise<void> {
|
|
134
|
+
/*async logout(): Promise<void> {
|
|
70
135
|
try {
|
|
71
136
|
await this.apiClient.post<void>("/auth/logout");
|
|
72
137
|
} finally {
|
|
@@ -81,18 +146,40 @@ export class AuthApi {
|
|
|
81
146
|
delete (window as any).__LEGACY_TOKEN__;
|
|
82
147
|
}
|
|
83
148
|
}
|
|
84
|
-
}
|
|
149
|
+
}*/
|
|
150
|
+
|
|
151
|
+
async logout(): Promise<void> {
|
|
152
|
+
try {
|
|
153
|
+
await this.apiClient.post<void>("/auth/logout");
|
|
154
|
+
console.log("✅ Logout successful");
|
|
155
|
+
} catch (error) {
|
|
156
|
+
console.error("❌ Logout error:", error);
|
|
157
|
+
} finally {
|
|
158
|
+
// ✅ Limpia AMBOS tokens (nuevo y legacy)
|
|
159
|
+
this.apiClient.setToken(null);
|
|
85
160
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
!!sessionStorage.getItem("legacy_token")) ||
|
|
91
|
-
(typeof window !== "undefined" && !!(window as any).__LEGACY_TOKEN__);
|
|
161
|
+
if (typeof sessionStorage !== "undefined") {
|
|
162
|
+
sessionStorage.removeItem("auth_token"); // ✅ Agrega esto
|
|
163
|
+
sessionStorage.removeItem("legacy_token");
|
|
164
|
+
}
|
|
92
165
|
|
|
93
|
-
|
|
166
|
+
if (typeof window !== "undefined") {
|
|
167
|
+
delete (window as any).__AUTH_TOKEN__; // ✅ Agrega esto
|
|
168
|
+
delete (window as any).__LEGACY_TOKEN__;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
94
171
|
}
|
|
95
172
|
|
|
173
|
+
//isAuthenticated(): boolean {
|
|
174
|
+
// const hasToken = this.apiClient.getToken() !== null;
|
|
175
|
+
// const hasLegacy =
|
|
176
|
+
// (typeof sessionStorage !== "undefined" &&
|
|
177
|
+
// !!sessionStorage.getItem("legacy_token")) ||
|
|
178
|
+
// (typeof window !== "undefined" && !!(window as any).__LEGACY_TOKEN__);
|
|
179
|
+
//
|
|
180
|
+
// return hasToken || hasLegacy;
|
|
181
|
+
//}
|
|
182
|
+
|
|
96
183
|
setToken(token: string | null): void {
|
|
97
184
|
this.apiClient.setToken(token);
|
|
98
185
|
}
|