valtech-components 2.0.484 → 2.0.486
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/components/types.mjs +1 -1
- 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/fesm2022/valtech-components.mjs +187 -2
- package/fesm2022/valtech-components.mjs.map +1 -1
- package/lib/components/types.d.ts +12 -0
- 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/package.json +1 -1
|
@@ -140,6 +140,18 @@ export type InputMetadata = {
|
|
|
140
140
|
okText?: string;
|
|
141
141
|
/** Position of label for checkbox ('start' | 'end') */
|
|
142
142
|
labelPlacement?: 'start' | 'end';
|
|
143
|
+
/** Number of digits in PIN (default: 5, only for PIN_CODE type) */
|
|
144
|
+
length?: number;
|
|
145
|
+
/** Size of the input boxes: 'small' | 'medium' | 'large' (default: 'medium', only for PIN_CODE type) */
|
|
146
|
+
size?: 'small' | 'medium' | 'large';
|
|
147
|
+
/** Allow only numbers (default: true, only for PIN_CODE type) */
|
|
148
|
+
allowNumbersOnly?: boolean;
|
|
149
|
+
/** Mask input - show dots instead of characters (only for PIN_CODE type) */
|
|
150
|
+
mask?: boolean;
|
|
151
|
+
/** Auto focus first input (only for PIN_CODE type) */
|
|
152
|
+
autoFocus?: boolean;
|
|
153
|
+
/** Custom input styles (only for PIN_CODE type) */
|
|
154
|
+
inputStyles?: Record<string, string>;
|
|
143
155
|
};
|
|
144
156
|
/**
|
|
145
157
|
* A section in a form, grouping multiple fields.
|
|
@@ -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
|
+
}
|