valtech-components 2.0.485 → 2.0.487
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/esm2022/lib/services/auth/auth.service.mjs +15 -2
- package/esm2022/lib/services/auth/device.service.mjs +104 -0
- package/esm2022/lib/services/auth/index.mjs +4 -1
- package/esm2022/lib/services/auth/session.service.mjs +78 -0
- package/esm2022/lib/services/auth/types.mjs +1 -1
- package/esm2022/lib/services/firebase/notifications.service.mjs +7 -15
- package/fesm2022/valtech-components.mjs +192 -14
- package/fesm2022/valtech-components.mjs.map +1 -1
- package/lib/services/auth/auth.service.d.ts +1 -0
- package/lib/services/auth/device.service.d.ts +80 -0
- package/lib/services/auth/index.d.ts +2 -0
- package/lib/services/auth/session.service.d.ts +60 -0
- package/lib/services/auth/types.d.ts +121 -0
- package/lib/services/firebase/notifications.service.d.ts +3 -4
- package/package.json +1 -1
|
@@ -72,6 +72,7 @@ export declare class AuthService implements OnDestroy {
|
|
|
72
72
|
ngOnDestroy(): void;
|
|
73
73
|
/**
|
|
74
74
|
* Inicia sesión con email y contraseña.
|
|
75
|
+
* Detecta automáticamente la plataforma para identificar dispositivos nuevos.
|
|
75
76
|
*/
|
|
76
77
|
signin(request: SigninRequest): Observable<SigninResponse>;
|
|
77
78
|
/**
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { HttpClient } from '@angular/common/http';
|
|
2
|
+
import { Observable } from 'rxjs';
|
|
3
|
+
import { ValtechAuthConfig, DeviceInfo, DeviceActionResult, DeviceActionResponse } from './types';
|
|
4
|
+
import * as i0 from "@angular/core";
|
|
5
|
+
/**
|
|
6
|
+
* Servicio para gestión de dispositivos del usuario.
|
|
7
|
+
* Permite listar, aprobar, bloquear y eliminar dispositivos registrados.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* import { DeviceService } from 'valtech-components';
|
|
12
|
+
*
|
|
13
|
+
* @Component({...})
|
|
14
|
+
* export class DevicesPage {
|
|
15
|
+
* private deviceService = inject(DeviceService);
|
|
16
|
+
*
|
|
17
|
+
* devices = signal<DeviceInfo[]>([]);
|
|
18
|
+
*
|
|
19
|
+
* async ngOnInit() {
|
|
20
|
+
* const devices = await firstValueFrom(this.deviceService.listDevices());
|
|
21
|
+
* this.devices.set(devices);
|
|
22
|
+
* }
|
|
23
|
+
*
|
|
24
|
+
* async blockDevice(deviceId: string) {
|
|
25
|
+
* await firstValueFrom(this.deviceService.blockDevice(deviceId));
|
|
26
|
+
* // Recargar lista
|
|
27
|
+
* }
|
|
28
|
+
* }
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
export declare class DeviceService {
|
|
32
|
+
private config;
|
|
33
|
+
private http;
|
|
34
|
+
constructor(config: ValtechAuthConfig, http: HttpClient);
|
|
35
|
+
private get baseUrl();
|
|
36
|
+
/**
|
|
37
|
+
* Lista todos los dispositivos registrados del usuario.
|
|
38
|
+
*/
|
|
39
|
+
listDevices(): Observable<DeviceInfo[]>;
|
|
40
|
+
/**
|
|
41
|
+
* Obtiene información de un dispositivo específico.
|
|
42
|
+
*/
|
|
43
|
+
getDevice(deviceId: string): Observable<DeviceInfo>;
|
|
44
|
+
/**
|
|
45
|
+
* Bloquea un dispositivo.
|
|
46
|
+
* Revoca todas las sesiones activas de ese dispositivo.
|
|
47
|
+
*/
|
|
48
|
+
blockDevice(deviceId: string): Observable<DeviceActionResult>;
|
|
49
|
+
/**
|
|
50
|
+
* Aprueba un dispositivo pendiente.
|
|
51
|
+
* Cambia el estado de pending_approval a active.
|
|
52
|
+
*/
|
|
53
|
+
approveDevice(deviceId: string): Observable<DeviceActionResult>;
|
|
54
|
+
/**
|
|
55
|
+
* Elimina un dispositivo registrado.
|
|
56
|
+
*/
|
|
57
|
+
deleteDevice(deviceId: string): Observable<DeviceActionResult>;
|
|
58
|
+
/**
|
|
59
|
+
* Ejecuta una acción de dispositivo desde un token de email.
|
|
60
|
+
* Este endpoint NO requiere autenticación.
|
|
61
|
+
* El token viene en la URL del email de alerta de nuevo inicio de sesión.
|
|
62
|
+
*
|
|
63
|
+
* @param token Token JWT de acción (24h, un solo uso)
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* ```typescript
|
|
67
|
+
* // En la página de dispositivos, al detectar ?token=xxx en la URL:
|
|
68
|
+
* const token = this.route.snapshot.queryParams['token'];
|
|
69
|
+
* if (token) {
|
|
70
|
+
* const result = await firstValueFrom(this.deviceService.executeAction(token));
|
|
71
|
+
* if (result.success) {
|
|
72
|
+
* console.log(`Dispositivo bloqueado, ${result.sessionsRevoked} sesiones cerradas`);
|
|
73
|
+
* }
|
|
74
|
+
* }
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
77
|
+
executeAction(token: string): Observable<DeviceActionResponse>;
|
|
78
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<DeviceService, never>;
|
|
79
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<DeviceService>;
|
|
80
|
+
}
|
|
@@ -77,3 +77,5 @@ export { AuthStateService } from './auth-state.service';
|
|
|
77
77
|
export { TokenService } from './token.service';
|
|
78
78
|
export { AuthStorageService } from './storage.service';
|
|
79
79
|
export { AuthSyncService } from './sync.service';
|
|
80
|
+
export { DeviceService } from './device.service';
|
|
81
|
+
export { SessionService } from './session.service';
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { HttpClient } from '@angular/common/http';
|
|
2
|
+
import { Observable } from 'rxjs';
|
|
3
|
+
import { ValtechAuthConfig, SessionInfo, RevokeSessionsResponse } from './types';
|
|
4
|
+
import * as i0 from "@angular/core";
|
|
5
|
+
/**
|
|
6
|
+
* Servicio para gestión de sesiones activas del usuario.
|
|
7
|
+
* Permite listar y revocar sesiones.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* import { SessionService } from 'valtech-components';
|
|
12
|
+
*
|
|
13
|
+
* @Component({...})
|
|
14
|
+
* export class SessionsPage {
|
|
15
|
+
* private sessionService = inject(SessionService);
|
|
16
|
+
*
|
|
17
|
+
* sessions = signal<SessionInfo[]>([]);
|
|
18
|
+
*
|
|
19
|
+
* async ngOnInit() {
|
|
20
|
+
* const sessions = await firstValueFrom(this.sessionService.listSessions());
|
|
21
|
+
* this.sessions.set(sessions);
|
|
22
|
+
* }
|
|
23
|
+
*
|
|
24
|
+
* async revokeSession(sessionId: string) {
|
|
25
|
+
* await firstValueFrom(this.sessionService.revokeSession(sessionId));
|
|
26
|
+
* // Recargar lista
|
|
27
|
+
* }
|
|
28
|
+
*
|
|
29
|
+
* async revokeAllOthers() {
|
|
30
|
+
* const result = await firstValueFrom(this.sessionService.revokeAllSessions());
|
|
31
|
+
* console.log(`${result.sessionsRevoked} sesiones cerradas`);
|
|
32
|
+
* }
|
|
33
|
+
* }
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export declare class SessionService {
|
|
37
|
+
private config;
|
|
38
|
+
private http;
|
|
39
|
+
constructor(config: ValtechAuthConfig, http: HttpClient);
|
|
40
|
+
private get baseUrl();
|
|
41
|
+
/**
|
|
42
|
+
* Lista todas las sesiones activas del usuario.
|
|
43
|
+
* La sesión actual está marcada con isCurrent=true.
|
|
44
|
+
*/
|
|
45
|
+
listSessions(): Observable<SessionInfo[]>;
|
|
46
|
+
/**
|
|
47
|
+
* Revoca una sesión específica.
|
|
48
|
+
* Fuerza el cierre de sesión en ese dispositivo/navegador.
|
|
49
|
+
*/
|
|
50
|
+
revokeSession(sessionId: string): Observable<RevokeSessionsResponse>;
|
|
51
|
+
/**
|
|
52
|
+
* Revoca todas las sesiones excepto la actual.
|
|
53
|
+
* Útil para "cerrar sesión en todos los dispositivos".
|
|
54
|
+
*
|
|
55
|
+
* @returns Número de sesiones revocadas
|
|
56
|
+
*/
|
|
57
|
+
revokeAllSessions(): Observable<RevokeSessionsResponse>;
|
|
58
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<SessionService, never>;
|
|
59
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<SessionService>;
|
|
60
|
+
}
|
|
@@ -221,6 +221,14 @@ export interface ResendCodeResponse {
|
|
|
221
221
|
export interface SigninRequest {
|
|
222
222
|
email: string;
|
|
223
223
|
password: string;
|
|
224
|
+
/** Plataforma del dispositivo (para detección de nuevo dispositivo) */
|
|
225
|
+
platform?: DevicePlatform;
|
|
226
|
+
/** Navegador (solo web) */
|
|
227
|
+
browser?: string;
|
|
228
|
+
/** Sistema operativo */
|
|
229
|
+
os?: string;
|
|
230
|
+
/** Nombre amigable del dispositivo */
|
|
231
|
+
deviceName?: string;
|
|
224
232
|
}
|
|
225
233
|
/**
|
|
226
234
|
* Response de signin.
|
|
@@ -237,6 +245,10 @@ export interface SigninResponse {
|
|
|
237
245
|
mfaMethod?: MFAMethod;
|
|
238
246
|
roles?: string[];
|
|
239
247
|
permissions?: string[];
|
|
248
|
+
/** Indica si el login fue desde un dispositivo nuevo/no reconocido */
|
|
249
|
+
isNewDevice?: boolean;
|
|
250
|
+
/** ID del dispositivo usado para el login */
|
|
251
|
+
deviceId?: string;
|
|
240
252
|
}
|
|
241
253
|
/**
|
|
242
254
|
* Request para verificar MFA.
|
|
@@ -522,3 +534,112 @@ export interface RegisterDeviceResult {
|
|
|
522
534
|
/** Mensaje de error (solo si registered=false) */
|
|
523
535
|
error?: string;
|
|
524
536
|
}
|
|
537
|
+
/**
|
|
538
|
+
* Estados posibles de un dispositivo.
|
|
539
|
+
*/
|
|
540
|
+
export type DeviceStatus = 'active' | 'pending_approval' | 'blocked';
|
|
541
|
+
/**
|
|
542
|
+
* Información completa de un dispositivo registrado.
|
|
543
|
+
*/
|
|
544
|
+
export interface DeviceInfo {
|
|
545
|
+
/** ID único del dispositivo */
|
|
546
|
+
deviceId: string;
|
|
547
|
+
/** Plataforma del dispositivo */
|
|
548
|
+
platform: DevicePlatform;
|
|
549
|
+
/** Navegador (solo web) */
|
|
550
|
+
browser?: string;
|
|
551
|
+
/** Sistema operativo */
|
|
552
|
+
os?: string;
|
|
553
|
+
/** Nombre amigable del dispositivo */
|
|
554
|
+
name?: string;
|
|
555
|
+
/** Estado actual del dispositivo */
|
|
556
|
+
status: DeviceStatus;
|
|
557
|
+
/** Dirección IP del último acceso */
|
|
558
|
+
ipAddress?: string;
|
|
559
|
+
/** Ubicación geográfica aproximada */
|
|
560
|
+
location?: string;
|
|
561
|
+
/** Última actividad */
|
|
562
|
+
lastActive: string;
|
|
563
|
+
/** Fecha de creación/registro */
|
|
564
|
+
createdAt: string;
|
|
565
|
+
/** Fecha de aprobación (si aplica) */
|
|
566
|
+
approvedAt?: string;
|
|
567
|
+
/** Fecha de bloqueo (si aplica) */
|
|
568
|
+
blockedAt?: string;
|
|
569
|
+
}
|
|
570
|
+
/**
|
|
571
|
+
* Response de listar dispositivos del usuario.
|
|
572
|
+
*/
|
|
573
|
+
export interface ListDevicesResponse {
|
|
574
|
+
operationId: string;
|
|
575
|
+
devices: DeviceInfo[];
|
|
576
|
+
}
|
|
577
|
+
/**
|
|
578
|
+
* Response de acción sobre dispositivo (block/approve/delete).
|
|
579
|
+
*/
|
|
580
|
+
export interface DeviceActionResult {
|
|
581
|
+
operationId: string;
|
|
582
|
+
success: boolean;
|
|
583
|
+
message: string;
|
|
584
|
+
}
|
|
585
|
+
/**
|
|
586
|
+
* Información de una sesión activa.
|
|
587
|
+
*/
|
|
588
|
+
export interface SessionInfo {
|
|
589
|
+
/** ID único de la sesión */
|
|
590
|
+
sessionId: string;
|
|
591
|
+
/** ID del dispositivo asociado (si existe) */
|
|
592
|
+
deviceId?: string;
|
|
593
|
+
/** Información del dispositivo (User-Agent) */
|
|
594
|
+
deviceInfo?: string;
|
|
595
|
+
/** Dirección IP de la sesión */
|
|
596
|
+
ip?: string;
|
|
597
|
+
/** Ubicación geográfica aproximada */
|
|
598
|
+
location?: string;
|
|
599
|
+
/** Fecha de creación de la sesión */
|
|
600
|
+
createdAt: string;
|
|
601
|
+
/** Fecha de expiración de la sesión */
|
|
602
|
+
expiresAt: string;
|
|
603
|
+
/** Indica si es la sesión actual del usuario */
|
|
604
|
+
isCurrent: boolean;
|
|
605
|
+
}
|
|
606
|
+
/**
|
|
607
|
+
* Response de listar sesiones activas.
|
|
608
|
+
*/
|
|
609
|
+
export interface ListSessionsResponse {
|
|
610
|
+
operationId: string;
|
|
611
|
+
sessions: SessionInfo[];
|
|
612
|
+
}
|
|
613
|
+
/**
|
|
614
|
+
* Response de revocar sesión(es).
|
|
615
|
+
*/
|
|
616
|
+
export interface RevokeSessionsResponse {
|
|
617
|
+
operationId: string;
|
|
618
|
+
success: boolean;
|
|
619
|
+
/** Número de sesiones revocadas */
|
|
620
|
+
sessionsRevoked: number;
|
|
621
|
+
}
|
|
622
|
+
/**
|
|
623
|
+
* Request para ejecutar acción de dispositivo desde email.
|
|
624
|
+
* El token viene en la URL del email de alerta.
|
|
625
|
+
*/
|
|
626
|
+
export interface DeviceActionRequest {
|
|
627
|
+
/** Token JWT de acción (24h, un solo uso) */
|
|
628
|
+
token: string;
|
|
629
|
+
}
|
|
630
|
+
/**
|
|
631
|
+
* Response de ejecutar acción de dispositivo.
|
|
632
|
+
*/
|
|
633
|
+
export interface DeviceActionResponse {
|
|
634
|
+
operationId: string;
|
|
635
|
+
/** Si la acción fue ejecutada exitosamente */
|
|
636
|
+
success: boolean;
|
|
637
|
+
/** Acción ejecutada (refuse, approve, block) */
|
|
638
|
+
action: string;
|
|
639
|
+
/** ID del dispositivo afectado */
|
|
640
|
+
deviceId: string;
|
|
641
|
+
/** Número de sesiones revocadas (si action=refuse/block) */
|
|
642
|
+
sessionsRevoked?: number;
|
|
643
|
+
/** Mensaje descriptivo */
|
|
644
|
+
message: string;
|
|
645
|
+
}
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
import { Injector } from '@angular/core';
|
|
11
11
|
import { Observable } from 'rxjs';
|
|
12
12
|
import { FirestoreCollectionFactory } from './firestore-collection';
|
|
13
|
-
import { FirestoreDocument
|
|
13
|
+
import { FirestoreDocument } from './types';
|
|
14
14
|
import * as i0 from "@angular/core";
|
|
15
15
|
/**
|
|
16
16
|
* Documento de notificación en Firestore.
|
|
@@ -52,11 +52,10 @@ export interface NotificationDocument extends FirestoreDocument {
|
|
|
52
52
|
export declare class NotificationsService {
|
|
53
53
|
private injector;
|
|
54
54
|
private collectionFactory;
|
|
55
|
-
private config;
|
|
56
55
|
private collection;
|
|
57
56
|
private currentUserId;
|
|
58
57
|
private authService;
|
|
59
|
-
constructor(injector: Injector, collectionFactory: FirestoreCollectionFactory
|
|
58
|
+
constructor(injector: Injector, collectionFactory: FirestoreCollectionFactory);
|
|
60
59
|
/**
|
|
61
60
|
* Configura auto-inicialización observando el estado de AuthService.
|
|
62
61
|
* Se ejecuta en el contexto del injector para poder usar effect().
|
|
@@ -117,6 +116,6 @@ export declare class NotificationsService {
|
|
|
117
116
|
* Útil para logout.
|
|
118
117
|
*/
|
|
119
118
|
reset(): void;
|
|
120
|
-
static ɵfac: i0.ɵɵFactoryDeclaration<NotificationsService, [null, { optional: true; }
|
|
119
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<NotificationsService, [null, { optional: true; }]>;
|
|
121
120
|
static ɵprov: i0.ɵɵInjectableDeclaration<NotificationsService>;
|
|
122
121
|
}
|