valtech-components 2.0.834 → 2.0.836
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/organisms/mfa-modal/mfa-modal.component.mjs +465 -0
- package/esm2022/lib/services/auth/auth.service.mjs +27 -17
- package/esm2022/lib/services/auth/oauth-callback.component.mjs +19 -1
- package/esm2022/lib/services/auth/types.mjs +1 -1
- package/esm2022/lib/services/i18n/default-content.mjs +109 -1
- package/esm2022/lib/version.mjs +2 -2
- package/esm2022/public-api.mjs +2 -1
- package/fesm2022/valtech-components.mjs +603 -18
- package/fesm2022/valtech-components.mjs.map +1 -1
- package/lib/components/organisms/mfa-modal/mfa-modal.component.d.ts +129 -0
- package/lib/services/auth/types.d.ts +9 -0
- package/lib/version.d.ts +1 -1
- package/package.json +1 -1
- package/public-api.d.ts +1 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { EventEmitter, OnDestroy } from '@angular/core';
|
|
2
|
+
import { FormControl } from '@angular/forms';
|
|
3
|
+
import { FormMetadata, FormSubmit } from '../../types';
|
|
4
|
+
import { MFAMethod, TOTPSetupResponse } from '../../../services/auth/types';
|
|
5
|
+
import { QrResult } from '../../../services/qr-generator/types';
|
|
6
|
+
import * as i0 from "@angular/core";
|
|
7
|
+
/** Paso del flujo del modal. */
|
|
8
|
+
type MfaStep = 'loading' | 'status' | 'method-select' | 'totp-setup' | 'code-confirm' | 'disable';
|
|
9
|
+
/**
|
|
10
|
+
* `val-mfa-modal` — modal de gestión de autenticación de dos factores (MFA)
|
|
11
|
+
* para un usuario autenticado. Mismo patrón que `val-change-password-modal`.
|
|
12
|
+
*
|
|
13
|
+
* Flujo (máquina de estados interna):
|
|
14
|
+
* - `loading` → `getProfile()` para conocer el estado MFA.
|
|
15
|
+
* - `status` → muestra MFA habilitado/deshabilitado. Si está habilitado:
|
|
16
|
+
* gestión de backup codes (TOTP) + deshabilitar. Si no: botón habilitar.
|
|
17
|
+
* - `method-select` → elegir TOTP / EMAIL / SMS.
|
|
18
|
+
* - `totp-setup` → QR + secreto manual + backup codes → verificar código.
|
|
19
|
+
* - `code-confirm` → (EMAIL/SMS) ingresar código recibido, con reenvío.
|
|
20
|
+
* - `disable` → contraseña para deshabilitar MFA.
|
|
21
|
+
*
|
|
22
|
+
* El QR se genera **client-side** (`QrGeneratorService`) — el secreto TOTP
|
|
23
|
+
* nunca sale del navegador.
|
|
24
|
+
*
|
|
25
|
+
* Self-contained: inyecta `AuthService` y llama los endpoints directo. La app
|
|
26
|
+
* controla `[isOpen]` y reacciona a `(changed)` / `(dismissed)`.
|
|
27
|
+
*
|
|
28
|
+
* i18n: namespace compartido `_auth`.
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```html
|
|
32
|
+
* <val-mfa-modal
|
|
33
|
+
* [isOpen]="isModalOpen()"
|
|
34
|
+
* (dismissed)="isModalOpen.set(false)"
|
|
35
|
+
* />
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export declare class MfaModalComponent implements OnDestroy {
|
|
39
|
+
private _isOpen;
|
|
40
|
+
/** Controla la visibilidad. Cada apertura re-resuelve el estado MFA. */
|
|
41
|
+
set isOpen(value: boolean);
|
|
42
|
+
get isOpen(): boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Código MFA pre-cargado (deep-link desde el email de setup MFA-email). Si
|
|
45
|
+
* está presente al abrir, el modal salta directo al paso de confirmación
|
|
46
|
+
* con el código rellenado.
|
|
47
|
+
*/
|
|
48
|
+
prefillCode?: string;
|
|
49
|
+
/** Emite cuando el estado MFA cambia (habilitado / deshabilitado). */
|
|
50
|
+
changed: EventEmitter<void>;
|
|
51
|
+
/** Emite cuando el user cierra el modal (botón X o backdrop). */
|
|
52
|
+
dismissed: EventEmitter<void>;
|
|
53
|
+
private auth;
|
|
54
|
+
private toast;
|
|
55
|
+
private i18n;
|
|
56
|
+
private i18nHelper;
|
|
57
|
+
private qrGen;
|
|
58
|
+
private readonly _step;
|
|
59
|
+
/** Paso actual del flujo. */
|
|
60
|
+
readonly step: import("@angular/core").Signal<MfaStep>;
|
|
61
|
+
/** `true` mientras una llamada al backend está en curso. */
|
|
62
|
+
readonly working: import("@angular/core").WritableSignal<boolean>;
|
|
63
|
+
readonly mfaEnabled: import("@angular/core").WritableSignal<boolean>;
|
|
64
|
+
readonly mfaMethod: import("@angular/core").WritableSignal<MFAMethod>;
|
|
65
|
+
readonly userPhone: import("@angular/core").WritableSignal<string>;
|
|
66
|
+
readonly backupCodesCount: import("@angular/core").WritableSignal<number>;
|
|
67
|
+
readonly selectedMethod: import("@angular/core").WritableSignal<MFAMethod>;
|
|
68
|
+
readonly totpSetup: import("@angular/core").WritableSignal<TOTPSetupResponse>;
|
|
69
|
+
readonly totpQr: import("@angular/core").WritableSignal<QrResult>;
|
|
70
|
+
/** Códigos de respaldo recién regenerados — se muestran una sola vez. */
|
|
71
|
+
readonly regeneratedCodes: import("@angular/core").WritableSignal<string[]>;
|
|
72
|
+
readonly resendCooldown: import("@angular/core").WritableSignal<number>;
|
|
73
|
+
readonly pinControl: FormControl<string>;
|
|
74
|
+
readonly phoneControl: FormControl<string>;
|
|
75
|
+
readonly pinInputProps: {
|
|
76
|
+
control: FormControl<string>;
|
|
77
|
+
token: string;
|
|
78
|
+
length: number;
|
|
79
|
+
allowNumbersOnly: boolean;
|
|
80
|
+
autoFocus: boolean;
|
|
81
|
+
};
|
|
82
|
+
/** Form de deshabilitación — `val-form` con un campo de contraseña. */
|
|
83
|
+
readonly disableFormProps: import("@angular/core").Signal<FormMetadata>;
|
|
84
|
+
private resendTimer;
|
|
85
|
+
constructor();
|
|
86
|
+
ngOnDestroy(): void;
|
|
87
|
+
/** Traduce una clave del namespace `_auth`. */
|
|
88
|
+
t(key: string): string;
|
|
89
|
+
/** Cierre iniciado por el user (X / backdrop). */
|
|
90
|
+
close(): void;
|
|
91
|
+
/**
|
|
92
|
+
* Punto de entrada al abrir el modal. Con `prefillCode` (deep-link del email
|
|
93
|
+
* de setup MFA-email) salta directo a la confirmación; si no, resuelve el
|
|
94
|
+
* estado MFA actual.
|
|
95
|
+
*/
|
|
96
|
+
private open;
|
|
97
|
+
/** Consulta el perfil para conocer el estado MFA y posicionar el flujo. */
|
|
98
|
+
private resolveStatus;
|
|
99
|
+
private loadBackupCount;
|
|
100
|
+
goToMethodSelect(): void;
|
|
101
|
+
goToDisable(): void;
|
|
102
|
+
backToStatus(): void;
|
|
103
|
+
/** Continúa desde el selector de método al setup correspondiente. */
|
|
104
|
+
proceedWithMethod(): void;
|
|
105
|
+
private setupTotp;
|
|
106
|
+
/** Verifica el código TOTP de la app de autenticación y activa MFA. */
|
|
107
|
+
verifyTotp(): void;
|
|
108
|
+
/** Confirma el código EMAIL/SMS y activa MFA. */
|
|
109
|
+
confirmCode(): void;
|
|
110
|
+
/** Reenvía el código EMAIL/SMS (re-ejecuta el setup). */
|
|
111
|
+
resendCode(): void;
|
|
112
|
+
/** Regenera los códigos de respaldo TOTP y los muestra una vez. */
|
|
113
|
+
regenerateBackupCodes(): void;
|
|
114
|
+
/** Deshabilita MFA — requiere la contraseña de la cuenta. */
|
|
115
|
+
onDisableSubmit(event: FormSubmit): void;
|
|
116
|
+
/** Copia una lista de códigos de respaldo al portapapeles. */
|
|
117
|
+
copyCodes(codes: string[]): Promise<void>;
|
|
118
|
+
/** Etiqueta i18n legible para un método MFA. */
|
|
119
|
+
methodLabel(method: MFAMethod | null): string;
|
|
120
|
+
private resetFlow;
|
|
121
|
+
private startCooldown;
|
|
122
|
+
private stopCooldown;
|
|
123
|
+
/** Mapea los códigos de error MFA del backend a mensajes del namespace `_auth`. */
|
|
124
|
+
private resolveError;
|
|
125
|
+
private showToast;
|
|
126
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<MfaModalComponent, never>;
|
|
127
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<MfaModalComponent, "val-mfa-modal", never, { "isOpen": { "alias": "isOpen"; "required": false; }; "prefillCode": { "alias": "prefillCode"; "required": false; }; }, { "changed": "changed"; "dismissed": "dismissed"; }, never, never, true, never>;
|
|
128
|
+
}
|
|
129
|
+
export {};
|
|
@@ -767,6 +767,15 @@ export interface OAuthResult {
|
|
|
767
767
|
isNewUser?: boolean;
|
|
768
768
|
/** Indica si la cuenta fue vinculada a usuario existente */
|
|
769
769
|
linked?: boolean;
|
|
770
|
+
/**
|
|
771
|
+
* `true` si el backend exige verificación MFA tras el OAuth. En ese caso
|
|
772
|
+
* NO vienen `accessToken`/`refreshToken` — el flujo continúa con `mfaToken`.
|
|
773
|
+
*/
|
|
774
|
+
mfaRequired?: boolean;
|
|
775
|
+
/** Token temporal para el challenge MFA (presente si `mfaRequired`). */
|
|
776
|
+
mfaToken?: string;
|
|
777
|
+
/** Método MFA configurado por el usuario (presente si `mfaRequired`). */
|
|
778
|
+
mfaMethod?: MFAMethod;
|
|
770
779
|
}
|
|
771
780
|
/**
|
|
772
781
|
* Error de OAuth.
|
package/lib/version.d.ts
CHANGED
package/package.json
CHANGED
package/public-api.d.ts
CHANGED
|
@@ -191,6 +191,7 @@ export * from './lib/components/organisms/form/form-footer/form-footer.component
|
|
|
191
191
|
export * from './lib/components/organisms/form/form.component';
|
|
192
192
|
export * from './lib/components/organisms/header/header.component';
|
|
193
193
|
export * from './lib/components/organisms/header/types';
|
|
194
|
+
export * from './lib/components/organisms/mfa-modal/mfa-modal.component';
|
|
194
195
|
export * from './lib/components/organisms/item-list/item-list.component';
|
|
195
196
|
export * from './lib/components/organisms/item-list/types';
|
|
196
197
|
export * from './lib/components/organisms/no-content/no-content.component';
|