falconhub-apilibrary 1.1.0
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/LICENSE +15 -0
- package/README.md +22 -0
- package/dist/index.d.mts +357 -0
- package/dist/index.d.ts +357 -0
- package/dist/index.js +867 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +825 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +61 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
ISC License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Blink Solutions SA de CV
|
|
4
|
+
|
|
5
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
6
|
+
purpose with or without fee is hereby granted, provided that the above
|
|
7
|
+
copyright notice and this permission notice appear in all copies.
|
|
8
|
+
|
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
10
|
+
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
11
|
+
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
12
|
+
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
13
|
+
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
14
|
+
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
15
|
+
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# FalconHUB SDK
|
|
2
|
+
|
|
3
|
+
Librería cliente desarrollada en Typescript dedicada a faciliar el consumo del API de FalconHUB, manejo interno de procesos generales, tokens, sliding window session y firma de solicitudes mediante X-Signature.
|
|
4
|
+
|
|
5
|
+
## Caracterísiticas
|
|
6
|
+
|
|
7
|
+
**Gestión de tokens** - Al realizar el inicio de sesión mediate el módulo de auth, la librería se encargará de gestionar las sesiones mediante funciones callback.
|
|
8
|
+
**Slinding window** - Cuando se desee mantener la sesión activa la librería gestionará las renovaciones de tokens mediante Sliding Window.
|
|
9
|
+
**Firmas de seguridad autogestionadas** - Dentro del entorno existen rutas protegidas (de tipo POST) protegidas mediante firmas Signature, la librería se encarga de realizar estas firmas y procesarlas.
|
|
10
|
+
**Callbacks** - Se introducen funciones que sincronizan información entre la librería y el proyecto que la consuma.
|
|
11
|
+
|
|
12
|
+
## Instalación
|
|
13
|
+
|
|
14
|
+
Ejecuta:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
> **Nota:**
|
|
21
|
+
> - **Producción (main)**: `falconhub-apilibrary-X.X.X.tgz` - Versión estable
|
|
22
|
+
> - **Desarrollo (development)**: `falconhub-apilibrary-X.X.X-dev.tgz` - Última versión en desarrollo
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
declare class ErrorResponse extends Error {
|
|
2
|
+
statusCode?: number | undefined;
|
|
3
|
+
responseData?: any | undefined;
|
|
4
|
+
constructor(message: string, statusCode?: number | undefined, responseData?: any | undefined);
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
interface TokenData {
|
|
8
|
+
accessToken: string;
|
|
9
|
+
refreshToken: string;
|
|
10
|
+
expiresAt: Date;
|
|
11
|
+
rememberMe: boolean;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
interface ServiceProperties {
|
|
15
|
+
url: string;
|
|
16
|
+
originRequest: string;
|
|
17
|
+
domain: string;
|
|
18
|
+
device: string;
|
|
19
|
+
source: string;
|
|
20
|
+
autoRefresh?: boolean | {
|
|
21
|
+
enabled: boolean;
|
|
22
|
+
thresholdMinutes: number;
|
|
23
|
+
};
|
|
24
|
+
onTokensUpdated?: (tokens: TokenData | null) => void;
|
|
25
|
+
onTokensRefreshed?: (tokens: {
|
|
26
|
+
accessToken: string | null;
|
|
27
|
+
refreshToken: string | null;
|
|
28
|
+
}) => void;
|
|
29
|
+
onSessionExpiring?: (remainingMinutes: number) => void;
|
|
30
|
+
onSessionExpired?: () => Promise<void>;
|
|
31
|
+
onAuthError?: (error: ErrorResponse) => void;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
declare class CryptoService {
|
|
35
|
+
/**
|
|
36
|
+
* Encripta el texto plano utilizando AES con una clave derivada del secretWord y el timestamp
|
|
37
|
+
*
|
|
38
|
+
* @param plaintText -- Texto plano a encriptar
|
|
39
|
+
* @param secretWord - Palabra secreta utilizada para derivar la clave
|
|
40
|
+
* @param timestamp - Timestamp actual
|
|
41
|
+
* @returns Texto encriptado en formato Base64
|
|
42
|
+
*/
|
|
43
|
+
encrypt(plaintText: string, secretWord: string, timestamp: string): string;
|
|
44
|
+
/**
|
|
45
|
+
* Genera la firma Signature para las operaciones de tipo POST
|
|
46
|
+
*
|
|
47
|
+
* @param body - Cuerpo de la solicitud
|
|
48
|
+
* @param timestamp - Timestamp actual
|
|
49
|
+
* @param refreshToken - Refresh token del usuario
|
|
50
|
+
* @returns Firma signature en formato Base64
|
|
51
|
+
*/
|
|
52
|
+
genSignature(body: string, timestamp: string, refreshToken: string): string;
|
|
53
|
+
/**
|
|
54
|
+
* Desencripta texto usando AES-256-CBC
|
|
55
|
+
*
|
|
56
|
+
* @param encryptedBase64 - Texto encriptado en base64
|
|
57
|
+
* @param secret - Clave secreta
|
|
58
|
+
* @param timestamp - Timestamp usado en la encriptación
|
|
59
|
+
* @returns Texto desencriptado
|
|
60
|
+
*/
|
|
61
|
+
decrypt(encryptedText: string, secretWord: string, timestamp: string): string;
|
|
62
|
+
/**
|
|
63
|
+
* Verifica una firma HMAC-SHA256 (útil para testing o validación)
|
|
64
|
+
*
|
|
65
|
+
* @param body - Cuerpo original
|
|
66
|
+
* @param timestamp - Timestamp original
|
|
67
|
+
* @param refreshToken - Token usado como clave
|
|
68
|
+
* @param signature - Firma a verificar
|
|
69
|
+
* @returns true si la firma es válida
|
|
70
|
+
*/
|
|
71
|
+
verifySignature(body: string, timestamp: string, refreshToken: string, signature: string): boolean;
|
|
72
|
+
/**
|
|
73
|
+
* Genera un hash SHA256 de un texto (útil para fingerprints)
|
|
74
|
+
*
|
|
75
|
+
* @param text - Texto a hashear
|
|
76
|
+
* @returns Hash en formato hexadecimal
|
|
77
|
+
*/
|
|
78
|
+
sha256(text: string): string;
|
|
79
|
+
/**
|
|
80
|
+
* Genera un identificador único basado en timestamp y random
|
|
81
|
+
* (útil para request IDs)
|
|
82
|
+
*
|
|
83
|
+
* @returns ID único
|
|
84
|
+
*/
|
|
85
|
+
generateUniqueId(): string;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
type MethodTypes = "GET" | "POST" | "PATCH" | "DELETE" | "PUT";
|
|
89
|
+
interface RequestOptions {
|
|
90
|
+
endpoint: string;
|
|
91
|
+
method: MethodTypes;
|
|
92
|
+
body?: any;
|
|
93
|
+
requiresSignature: boolean;
|
|
94
|
+
requiresAuth: boolean;
|
|
95
|
+
timeStamp?: string;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
interface AuthInterceptorConfig {
|
|
99
|
+
enabled?: boolean;
|
|
100
|
+
thresholdMinutes?: number;
|
|
101
|
+
isTokenExpiringSoon: () => boolean;
|
|
102
|
+
hasValidTokens: () => boolean;
|
|
103
|
+
shouldAutoRefresh: () => boolean;
|
|
104
|
+
refreshSession: () => Promise<void>;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
interface InterceptorContext {
|
|
108
|
+
requestId: string;
|
|
109
|
+
startTime: number;
|
|
110
|
+
retryCount: number;
|
|
111
|
+
metadata?: Record<string, any>;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
interface RequestConfig {
|
|
115
|
+
url: string;
|
|
116
|
+
method: string;
|
|
117
|
+
headers: Record<string, string>;
|
|
118
|
+
body?: any;
|
|
119
|
+
requiresAuth: boolean;
|
|
120
|
+
requiresSignature: boolean;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Interceptor de request
|
|
125
|
+
*/
|
|
126
|
+
interface RequestInterceptor {
|
|
127
|
+
name: string;
|
|
128
|
+
/**
|
|
129
|
+
* Procesa el request antes de enviarlo
|
|
130
|
+
*
|
|
131
|
+
* @param config - Configuración del request
|
|
132
|
+
* @param context - Contexto compartido
|
|
133
|
+
* @returns Configuración modificada o Promise que resuelve a la configuración
|
|
134
|
+
*/
|
|
135
|
+
onRequest(config: RequestConfig, context: InterceptorContext): Promise<RequestConfig> | RequestConfig;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
declare class AuthInterceptor implements RequestInterceptor {
|
|
139
|
+
readonly name = "AuthInterceptor";
|
|
140
|
+
private config;
|
|
141
|
+
private refreshPromise;
|
|
142
|
+
private isRefreshing;
|
|
143
|
+
constructor(config: AuthInterceptorConfig);
|
|
144
|
+
onRequest(config: RequestConfig, context: InterceptorContext): Promise<RequestConfig>;
|
|
145
|
+
updateConfig(config: Partial<AuthInterceptorConfig>): void;
|
|
146
|
+
reset(): void;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Clase base para la ejecución de request HTTP al API
|
|
151
|
+
*/
|
|
152
|
+
declare class API {
|
|
153
|
+
private properties;
|
|
154
|
+
private cryptoService;
|
|
155
|
+
private authInterceptor;
|
|
156
|
+
private getAccessToken;
|
|
157
|
+
private getRefreshToken;
|
|
158
|
+
constructor(properties: ServiceProperties, cryptoService: CryptoService, authInterceptor: AuthInterceptor | null, getAccessToken: () => string | null, getRefreshToken: () => string | null);
|
|
159
|
+
/**
|
|
160
|
+
* Ejecuta una request HTTP al API
|
|
161
|
+
*
|
|
162
|
+
* @param options - Opciones de la request
|
|
163
|
+
* @returns Respuesta parseada del tipo esperado
|
|
164
|
+
*/
|
|
165
|
+
private apiExecute;
|
|
166
|
+
/**
|
|
167
|
+
* Maneja errores HTTP y lanza excepciones apropiadas
|
|
168
|
+
*/
|
|
169
|
+
private handleErrorResponse;
|
|
170
|
+
executeGET<T>(endpoint: string, requiresAuth?: boolean): Promise<T | undefined>;
|
|
171
|
+
executePOST<T>(endpoint: string, body?: any, requiresAuth?: boolean, requiresSignature?: boolean): Promise<T | undefined>;
|
|
172
|
+
executePATCH<T>(endpoint: string, body?: any, requiresAuth?: boolean, requiresSignature?: boolean): Promise<T | undefined>;
|
|
173
|
+
executeDELETE<T>(endpoint: string, body?: any, requiresAuth?: boolean, requiresSignature?: boolean): Promise<T | undefined>;
|
|
174
|
+
executePUT<T>(endpoint: string, body?: any, requiresAuth?: boolean, requiresSignature?: boolean): Promise<T | undefined>;
|
|
175
|
+
executePublicRequest<T>(endpoint: string, method: MethodTypes, body?: any, timestamp?: string): Promise<T | undefined>;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Manages authentication tokens.
|
|
180
|
+
*/
|
|
181
|
+
declare class TokenManager {
|
|
182
|
+
private tokens;
|
|
183
|
+
private onTokensChanged?;
|
|
184
|
+
private sessionCheckInterval;
|
|
185
|
+
private onSessionExpiring?;
|
|
186
|
+
private onSessionExpired?;
|
|
187
|
+
private hasNotifiedExpiring;
|
|
188
|
+
constructor(onTokensChanged?: (tokens: TokenData | null) => void, onSessionExpiring?: (remainingMinutes: number) => void, onSessionExpired?: () => Promise<void>);
|
|
189
|
+
/**
|
|
190
|
+
* Guarda los tokens de autenticación y dispara el callback onTokensChanged.
|
|
191
|
+
*/
|
|
192
|
+
setTokens(tokens: TokenData): void;
|
|
193
|
+
/**
|
|
194
|
+
* Obtiene los tokens de autenticación almacenados.
|
|
195
|
+
*/
|
|
196
|
+
getTokens(): TokenData | null;
|
|
197
|
+
/**
|
|
198
|
+
* Limpia los tokens de autenticación almacenados y dispara el callback onTokensChanged.
|
|
199
|
+
*/
|
|
200
|
+
clearTokens(): void;
|
|
201
|
+
/**
|
|
202
|
+
* Valida si existen tokens y si el access token no ha expirado.
|
|
203
|
+
*/
|
|
204
|
+
hasValidTokens(): boolean;
|
|
205
|
+
/**
|
|
206
|
+
* Valida si el access token expirará dentro del umbral especificado (en minutos).
|
|
207
|
+
*/
|
|
208
|
+
isTokenExpiringSoon(thresholdMinutes: number): boolean;
|
|
209
|
+
/**
|
|
210
|
+
* Obtiene el tiempo restante hasta la expiración del access token en milisegundos.
|
|
211
|
+
*/
|
|
212
|
+
getTimeUntilExpiry(): number | null;
|
|
213
|
+
/**
|
|
214
|
+
* Obtiene el access token almacenado.
|
|
215
|
+
*/
|
|
216
|
+
getAccessToken(): string | null;
|
|
217
|
+
/**
|
|
218
|
+
* Obtiene el refresh token almacenado.
|
|
219
|
+
*/
|
|
220
|
+
getRefreshToken(): string | null;
|
|
221
|
+
/**
|
|
222
|
+
* Verifica si el auto-refresh debe ejecutarse
|
|
223
|
+
* Solo si el usuario activó "rememberMe" durante el login
|
|
224
|
+
*/
|
|
225
|
+
shouldAutoRefresh(): boolean;
|
|
226
|
+
/**
|
|
227
|
+
* Inicia el monitoreo de expiración para sesiones sin rememberMe
|
|
228
|
+
* - Notifica cuando quedan 5 minutos (onSessionExpiring)
|
|
229
|
+
* - Ejecuta logout cuando queda 1 minuto (onSessionExpired)
|
|
230
|
+
*/
|
|
231
|
+
private startExpirationCheck;
|
|
232
|
+
/**
|
|
233
|
+
* Detiene el monitoreo de expiración
|
|
234
|
+
*/
|
|
235
|
+
private stopExpirationCheck;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
interface LoginRequest {
|
|
239
|
+
email: string;
|
|
240
|
+
password: string;
|
|
241
|
+
rememberMe: boolean;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
interface LoginResponse {
|
|
245
|
+
accessToken: string;
|
|
246
|
+
refreshToken: string;
|
|
247
|
+
expiresIn: string;
|
|
248
|
+
message: string;
|
|
249
|
+
type: string;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
interface RefreshTokenResponse {
|
|
253
|
+
accessToken: string;
|
|
254
|
+
refreshToken: string;
|
|
255
|
+
expiresIn: string;
|
|
256
|
+
message: string;
|
|
257
|
+
type: string;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
interface ValidateSessionRenewedResponse {
|
|
261
|
+
accessToken: string;
|
|
262
|
+
refreshToken: string;
|
|
263
|
+
expiresIn: string;
|
|
264
|
+
remainingMinutes: number;
|
|
265
|
+
isRemembered: boolean;
|
|
266
|
+
}
|
|
267
|
+
interface ValidateSessionResponse {
|
|
268
|
+
expiresAt: Date;
|
|
269
|
+
remainingMinutes: number;
|
|
270
|
+
isRemembered: boolean;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
interface ResponseModel<T = any> {
|
|
274
|
+
success: boolean;
|
|
275
|
+
message: string;
|
|
276
|
+
totalItems?: number;
|
|
277
|
+
data: T | null;
|
|
278
|
+
responseTime: string | null;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
declare class AuthService {
|
|
282
|
+
private api;
|
|
283
|
+
private crytpoService;
|
|
284
|
+
private tokenManager;
|
|
285
|
+
private serviceProperties;
|
|
286
|
+
constructor(serviceProperties: ServiceProperties, tokenManager: TokenManager, cryptoService: CryptoService, api: API);
|
|
287
|
+
/**
|
|
288
|
+
* Login con las credenciales proporcionadas
|
|
289
|
+
* @param credentials - Objeto con email, password y rememberMe
|
|
290
|
+
* @returns Retorna el cuerpo de respuesta del login.
|
|
291
|
+
*/
|
|
292
|
+
login(credentials: LoginRequest): Promise<ResponseModel<LoginResponse>>;
|
|
293
|
+
/**
|
|
294
|
+
* Valida la sesión actual y retorna información de expiración
|
|
295
|
+
*
|
|
296
|
+
* El servidor puede responder de 2 formas:
|
|
297
|
+
* 1. Sesión renovada (sliding window): retorna nuevos tokens
|
|
298
|
+
* 2. Sesión válida: retorna info de expiración sin renovar
|
|
299
|
+
*/
|
|
300
|
+
validateSession(): Promise<ResponseModel<ValidateSessionRenewedResponse | ValidateSessionResponse>>;
|
|
301
|
+
/**
|
|
302
|
+
* Refresca los tokens usando el refresh token
|
|
303
|
+
*/
|
|
304
|
+
refreshTokens(rememberMe?: boolean): Promise<ResponseModel<RefreshTokenResponse>>;
|
|
305
|
+
/**
|
|
306
|
+
* Cierra sesión: notifica al servidor y limpia tokens
|
|
307
|
+
*/
|
|
308
|
+
logout(): Promise<void>;
|
|
309
|
+
/**
|
|
310
|
+
* Verifica si el usuario está autenticado
|
|
311
|
+
*/
|
|
312
|
+
isAuthenticated(): boolean;
|
|
313
|
+
/**
|
|
314
|
+
* Obtiene los tokens actuales
|
|
315
|
+
*/
|
|
316
|
+
getTokens(): TokenData | null;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* SDK principal de FalconHUB
|
|
321
|
+
*/
|
|
322
|
+
declare class FalconHUBSDK {
|
|
323
|
+
auth: AuthService;
|
|
324
|
+
private serviceProperties;
|
|
325
|
+
private cryptoService;
|
|
326
|
+
private tokenManager;
|
|
327
|
+
private authInterceptor;
|
|
328
|
+
private api;
|
|
329
|
+
constructor(serviceProperties: ServiceProperties);
|
|
330
|
+
private normalizeAutoRefreshConfig;
|
|
331
|
+
/**
|
|
332
|
+
* Inyecta tokens desde storage externo (cookies/localStorage/etc)
|
|
333
|
+
*/
|
|
334
|
+
setTokensFromExternal(accessToken: string, refreshToken: string, expiresAt: Date, rememberMe?: boolean): void;
|
|
335
|
+
/**
|
|
336
|
+
* Obtiene los tokens actuales
|
|
337
|
+
*/
|
|
338
|
+
getTokens(): TokenData | null;
|
|
339
|
+
/**
|
|
340
|
+
* Verifica si el usuario está autenticado
|
|
341
|
+
*/
|
|
342
|
+
isAuthenticated(): boolean;
|
|
343
|
+
/**
|
|
344
|
+
* Verifica si la sesión está por expirar
|
|
345
|
+
*/
|
|
346
|
+
isSessionExpiringSoon(thresholdMinutes?: number): boolean;
|
|
347
|
+
/**
|
|
348
|
+
* Obtiene el tiempo restante hasta la expiración en milisegundos
|
|
349
|
+
*/
|
|
350
|
+
getTimeUntilExpiry(): number | null;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
interface RefreshTokenRequest {
|
|
354
|
+
rememberMe: boolean;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
export { API, AuthInterceptor, type AuthInterceptorConfig, AuthService, CryptoService, ErrorResponse, FalconHUBSDK, type InterceptorContext, type LoginRequest, type LoginResponse, type MethodTypes, type RefreshTokenRequest, type RefreshTokenResponse, type RequestConfig, type RequestInterceptor, type RequestOptions, type ResponseModel, type ServiceProperties, type TokenData, TokenManager, type ValidateSessionRenewedResponse, type ValidateSessionResponse };
|