login-tsi 0.0.9 → 0.0.10
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/fesm2022/login-tsi.mjs
CHANGED
|
@@ -183,6 +183,7 @@ class MdVerificarMfaComponent {
|
|
|
183
183
|
estadoPush = signal('idle');
|
|
184
184
|
isPushEnCurso = computed(() => this.estadoPush() == 'enviando' || this.estadoPush() == 'esperando');
|
|
185
185
|
pushError = signal('');
|
|
186
|
+
numberMatching = signal(null);
|
|
186
187
|
inputCodigo = viewChild('inputCodigo');
|
|
187
188
|
pushCtrl;
|
|
188
189
|
constructor() {
|
|
@@ -256,11 +257,13 @@ class MdVerificarMfaComponent {
|
|
|
256
257
|
this.pushCtrl = ctrl;
|
|
257
258
|
this.pushError.set('');
|
|
258
259
|
this.estadoPush.set('enviando');
|
|
260
|
+
this.numberMatching.set(null);
|
|
259
261
|
const preauthToken = this.challenge().preauthToken;
|
|
260
262
|
try {
|
|
261
|
-
const solicitudId = await this.api.enviarPush(preauthToken);
|
|
263
|
+
const { solicitudId, numberMatching } = await this.api.enviarPush(preauthToken);
|
|
262
264
|
if (ctrl.signal.aborted)
|
|
263
265
|
return;
|
|
266
|
+
this.numberMatching.set(numberMatching ?? null);
|
|
264
267
|
this.estadoPush.set('esperando');
|
|
265
268
|
const limite = Date.now() + MAXIMO_ESPERA_MS;
|
|
266
269
|
while (Date.now() < limite) {
|
|
@@ -275,6 +278,7 @@ class MdVerificarMfaComponent {
|
|
|
275
278
|
if (ctrl.signal.aborted)
|
|
276
279
|
return;
|
|
277
280
|
}
|
|
281
|
+
this.numberMatching.set(null);
|
|
278
282
|
this.estadoPush.set('expirado');
|
|
279
283
|
this.pushError.set('No respondiste a tiempo la notificación. Vuelve a enviarla.');
|
|
280
284
|
}
|
|
@@ -290,6 +294,7 @@ class MdVerificarMfaComponent {
|
|
|
290
294
|
this.cancelado.emit();
|
|
291
295
|
}
|
|
292
296
|
resolverPush(estado) {
|
|
297
|
+
this.numberMatching.set(null);
|
|
293
298
|
if (estado == 'aprobado') {
|
|
294
299
|
this.estadoPush.set('idle');
|
|
295
300
|
this.verificado.emit();
|
|
@@ -306,15 +311,16 @@ class MdVerificarMfaComponent {
|
|
|
306
311
|
cancelarPush() {
|
|
307
312
|
this.pushCtrl?.abort();
|
|
308
313
|
this.pushCtrl = undefined;
|
|
314
|
+
this.numberMatching.set(null);
|
|
309
315
|
if (this.isPushEnCurso())
|
|
310
316
|
this.estadoPush.set('idle');
|
|
311
317
|
}
|
|
312
318
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: MdVerificarMfaComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
313
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.25", type: MdVerificarMfaComponent, isStandalone: true, selector: "lib-md-verificar-mfa", inputs: { challenge: { classPropertyName: "challenge", publicName: "challenge", isSignal: true, isRequired: true, transformFunction: null }, titulo: { classPropertyName: "titulo", publicName: "titulo", isSignal: true, isRequired: false, transformFunction: null }, showCancelar: { classPropertyName: "showCancelar", publicName: "showCancelar", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { verificado: "verificado", cancelado: "cancelado" }, viewQueries: [{ propertyName: "inputCodigo", first: true, predicate: ["inputCodigo"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"verificar-mfa\">\n <div class=\"auth-card-title mb-3\">{{ titulo() }}</div>\n\n <div class=\"d-flex align-items-center gap-3 mb-3\">\n <span class=\"verificar-mfa__icono\"><i class=\"fas fa-user-shield\"></i></span>\n <div>\n <div class=\"fw-semibold\">{{ challenge().coduser }}</div>\n @if (challenge().empresa) {\n <div class=\"verificar-mfa__muted\">{{ challenge().empresa }}</div>\n }\n </div>\n </div>\n\n @if (modo() == 'push') {\n @switch (estadoPush()) {\n @case ('enviando') {\n <div class=\"duo-push\">\n <span class=\"spinner-border spinner-border-sm text-primary\"></span>\n <div class=\"flex-grow-1\">Enviando notificaci\u00F3n a tu tel\u00E9fono\u2026</div>\n </div>\n }\n @case ('esperando') {\n <div class=\"duo-push duo-push--esperando\">\n <span class=\"duo-push__icono duo-push__icono--pulso\"><i class=\"fas fa-mobile-alt\"></i></span>\n <div class=\"flex-grow-1\">\n <div class=\"fw-semibold\">Revisa tu tel\u00E9fono</div>\n <div class=\"verificar-mfa__muted\">Aprueba la notificaci\u00F3n en TSI Autenticador para ingresar.</div>\n </div>\n </div>\n }\n @default {\n <div class=\"duo-push\">\n <span class=\"duo-push__icono\"><i class=\"fas fa-bell\"></i></span>\n <div class=\"flex-grow-1\">\n <div class=\"fw-semibold\">TSI Autenticador</div>\n <div class=\"verificar-mfa__muted\">Te enviaremos una notificaci\u00F3n para que la apruebes.</div>\n </div>\n </div>\n }\n }\n @if (pushError() && !isPushEnCurso()) {\n <div class=\"codigo-field__error\"><i class=\"fas fa-exclamation-circle\"></i> {{ pushError() }}</div>\n }\n\n <div class=\"verificar-mfa__opciones\">\n @if (tieneTotp()) {\n <button type=\"button\" class=\"verificar-mfa__link\" (click)=\"usarCodigo('totp')\">\n Usar c\u00F3digo de mi app de autenticaci\u00F3n\n </button>\n }\n <button type=\"button\" class=\"verificar-mfa__link verificar-mfa__link--secundario\"\n (click)=\"usarCodigo('respaldo')\">\n \u00BFNo tienes tu tel\u00E9fono? Usa un c\u00F3digo de respaldo\n </button>\n </div>\n } @else {\n <p class=\"verificar-mfa__muted mb-4\">\n @if (tipoCodigo() == 'totp') {\n {{ challenge().mensaje || campo().descri }}\n } @else {\n {{ campo().descri }}\n }\n </p>\n\n <div class=\"codigo-field\" [class.has-error]=\"codigoError()\">\n <span class=\"codigo-field__icon\"><i class=\"fas\" [class]=\"campo().icon\"></i></span>\n <input #inputCodigo id=\"mfa-codigo\" class=\"codigo-field__input\" type=\"text\"\n [placeholder]=\"campo().placeholder\" [value]=\"codigo()\" (input)=\"onCodigoInput($event)\"\n (keydown.enter)=\"verificar()\" [attr.inputmode]=\"campo().inputmode\" autocomplete=\"one-time-code\"\n autocorrect=\"off\" autocapitalize=\"characters\" spellcheck=\"false\" [disabled]=\"isEnviando()\">\n <label for=\"mfa-codigo\" class=\"codigo-field__label\">{{ campo().label }}</label>\n </div>\n @if (codigoError()) {\n <div class=\"codigo-field__error\"><i class=\"fas fa-exclamation-circle\"></i> {{ codigoError() }}</div>\n }\n\n <div class=\"verificar-mfa__opciones\">\n @if (tienePush()) {\n <button type=\"button\" class=\"verificar-mfa__link\" (click)=\"usarPush()\">\n <i class=\"fas fa-bell me-1\"></i>Mejor env\u00EDame una notificaci\u00F3n push\n </button>\n }\n @if (tieneTotp() && tipoCodigo() != 'totp') {\n <button type=\"button\" class=\"verificar-mfa__link\" (click)=\"usarCodigo('totp')\">\n Usar c\u00F3digo de mi app de autenticaci\u00F3n\n </button>\n }\n @if (tipoCodigo() != 'respaldo') {\n <button type=\"button\" class=\"verificar-mfa__link verificar-mfa__link--secundario\"\n (click)=\"usarCodigo('respaldo')\">\n \u00BFNo tienes tu tel\u00E9fono? Usa un c\u00F3digo de respaldo\n </button>\n }\n </div>\n }\n\n <div class=\"verificar-mfa__acciones\">\n @if (modo() == 'push') {\n <button type=\"button\" class=\"auth-btn\" [disabled]=\"isPushEnCurso()\" (click)=\"enviarPush()\">\n <i class=\"fas fa-paper-plane me-1\"></i>\n {{ isPushEnCurso() ? 'Esperando aprobaci\u00F3n\u2026' : 'Reenviar notificaci\u00F3n' }}\n </button>\n } @else {\n <button type=\"button\" class=\"auth-btn\" [disabled]=\"isEnviando()\" (click)=\"verificar()\">\n <i class=\"fas fa-check me-1\"></i>\n {{ isEnviando() ? 'Verificando\u2026' : 'Verificar' }}\n </button>\n }\n @if (showCancelar()) {\n <button type=\"button\" class=\"auth-btn auth-btn--outline\" (click)=\"cancelar()\">Cancelar</button>\n }\n </div>\n</div>\n", styles: [".verificar-mfa{color:var(--text-color)}.verificar-mfa__icono{display:inline-flex;flex-shrink:0;align-items:center;justify-content:center;width:44px;height:44px;border-radius:12px;color:var(--bs-primary);background:rgba(var(--bs-primary-rgb),.1);font-size:20px}.verificar-mfa__muted{font-size:13px;line-height:1.5;color:var(--bs-secondary-color)}.verificar-mfa__link:hover{text-decoration:underline}.verificar-mfa__link{padding:0;border:0;background:none;font-size:13px;font-weight:600;color:var(--bs-primary)}.codigo-field{position:relative}.codigo-field__icon{position:absolute;left:14px;top:50%;transform:translateY(-50%);z-index:2;font-size:15px;color:var(--placeholder-color);pointer-events:none;transition:color .2s}.codigo-field__input{width:100%;height:56px;padding:0 44px;border:1.5px solid var(--font-border-input);border-radius:10px;outline:none;background:var(--background-input);color:var(--color-input);font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:22px;font-weight:600;letter-spacing:.45em;text-align:center;transition:border-color .2s,box-shadow .2s,background .2s}.codigo-field__input::placeholder{color:var(--placeholder-color);opacity:.45}.codigo-field__input:focus{border-color:var(--bs-primary);box-shadow:0 0 0 3.5px rgba(var(--bs-primary-rgb),.15);background:var(--background-focus-input)}.codigo-field__input:disabled{opacity:.7}.codigo-field__label{position:absolute;left:12px;top:0;transform:translateY(-50%);z-index:1;margin:0!important;padding:0 4px;font-size:11px!important;font-weight:500!important;line-height:1.2;color:var(--placeholder-color);background:var(--background-card);pointer-events:none;transition:color .15s ease}.codigo-field:focus-within .codigo-field__label,.codigo-field:focus-within .codigo-field__icon{color:var(--bs-primary)}.codigo-field.has-error .codigo-field__input{border-color:var(--bs-danger);box-shadow:0 0 0 3.5px rgba(var(--bs-danger-rgb),.12)}.codigo-field.has-error .codigo-field__icon,.codigo-field.has-error .codigo-field__label{color:var(--bs-danger)}.codigo-field__error{display:flex;align-items:center;gap:6px;margin-top:8px;font-size:13px;font-weight:500;color:var(--bs-danger)}.duo-push{display:flex;align-items:center;gap:12px;padding:14px;border:1.5px solid var(--font-border-input);border-radius:10px;background:var(--background-input);color:var(--text-color);font-size:14px}.duo-push--esperando{border-color:rgba(var(--bs-primary-rgb),.45);background:rgba(var(--bs-primary-rgb),.06)}.duo-push__icono{display:inline-flex;flex-shrink:0;align-items:center;justify-content:center;width:40px;height:40px;border-radius:50%;color:var(--bs-primary);background:rgba(var(--bs-primary-rgb),.1);font-size:18px}.duo-push__icono--pulso{animation:duo-pulso 1.4s ease-in-out infinite}@keyframes duo-pulso{0%,to{box-shadow:0 0 rgba(var(--bs-primary-rgb),.35)}50%{box-shadow:0 0 0 8px rgba(var(--bs-primary-rgb),0)}}@media(prefers-reduced-motion:reduce){.duo-push__icono--pulso{animation:none}}.verificar-mfa__opciones{display:flex;flex-direction:column;align-items:flex-start;gap:8px;margin-top:16px}.verificar-mfa__link--secundario{font-weight:500;color:var(--bs-secondary-color)}.verificar-mfa__acciones{margin-top:24px}\n", "@charset \"UTF-8\";.red_contrasena,.blue_contrasena{position:relative;display:inline-block;font-size:13px;text-decoration:none;padding-bottom:2px;transition:color .3s ease;cursor:pointer}.red_contrasena:after,.blue_contrasena:after{content:\"\";position:absolute;bottom:0;left:50%;width:0;height:1px;background-color:currentColor;transition:all .3s ease;transform:translate(-50%)}.red_contrasena:hover:after,.blue_contrasena:hover:after{width:60%}.red_contrasena{color:#d1326f}.red_contrasena:hover{color:#a82859}.blue_contrasena{color:#398bf7}.blue_contrasena:hover{color:#1e5fc4}.auth-wrapper-login{position:fixed;inset:0;display:grid;grid-template-columns:1.15fr .85fr;overflow:hidden;background:#060d1f}.auth-panel-left{position:relative;overflow:hidden;background:linear-gradient(145deg,#040a18,#0b1a3d 55%,#040e22);display:flex;align-items:center;justify-content:center;padding:48px 40px}.auth-panel-left:before{content:\"\";position:absolute;inset:0;background-image:radial-gradient(circle,rgba(255,255,255,.055) 1px,transparent 1px);background-size:26px 26px;z-index:1;pointer-events:none}.auth-panel-left:after{content:\"\";position:absolute;top:0;left:-120%;width:60%;height:100%;background:linear-gradient(90deg,transparent,rgba(57,139,247,.04),transparent);animation:panelSweep 7s ease-in-out infinite;z-index:1;pointer-events:none}.auth-blob{position:absolute;border-radius:50%;filter:blur(72px);z-index:0;pointer-events:none}.auth-blob-1{width:340px;height:340px;background:radial-gradient(circle,rgba(57,139,247,.45) 0%,transparent 70%);top:-90px;right:-70px;animation:blobDrift 11s ease-in-out infinite}.auth-blob-2{width:240px;height:240px;background:radial-gradient(circle,rgba(124,58,237,.4) 0%,transparent 70%);bottom:60px;left:-50px;animation:blobDrift 14s ease-in-out infinite reverse}.auth-blob-3{width:180px;height:180px;background:radial-gradient(circle,rgba(14,165,233,.35) 0%,transparent 70%);bottom:-50px;right:40px;animation:blobDrift 9s ease-in-out infinite;animation-delay:-4s}.auth-blob-4{width:120px;height:120px;background:radial-gradient(circle,rgba(209,50,111,.25) 0%,transparent 70%);top:50%;left:50%;transform:translate(-50%,-50%);animation:blobDrift 16s ease-in-out infinite;animation-delay:-8s}@keyframes blobDrift{0%,to{transform:translate(0) scale(1)}33%{transform:translate(14px,-20px) scale(1.05)}66%{transform:translate(-10px,12px) scale(.96)}}@keyframes panelSweep{0%{left:-120%}50%{left:160%}to{left:160%}}.auth-brand-panel{position:relative;z-index:2;text-align:center;color:#fff;max-width:340px}.auth-brand-logo{width:100px;height:100px;border-radius:50%;background:#ffffff0d;border:1px solid rgba(255,255,255,.1);display:flex;align-items:center;justify-content:center;margin:0 auto 28px;box-shadow:0 0 0 14px #398bf70f,0 0 50px #398bf733;backdrop-filter:blur(8px)}.auth-brand-logo img{width:64px;height:64px;object-fit:contain;filter:brightness(1.05) drop-shadow(0 0 8px rgba(57,139,247,.4))}.auth-brand-title{font-size:30px;font-weight:700;letter-spacing:-.5px;margin-bottom:10px;background:linear-gradient(135deg,#fff 20%,#93c5fd 80%);-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text}.auth-brand-subtitle{font-size:14px;color:#ffffff73;line-height:1.65;margin-bottom:40px;letter-spacing:.2px}.auth-brand-features{display:flex;flex-direction:column;gap:14px;text-align:left}.auth-brand-feature{display:flex;align-items:center;gap:12px;font-size:13px;color:#fff9}.auth-brand-feature .feat-dot{flex-shrink:0;width:7px;height:7px;border-radius:50%;background:#398bf7;box-shadow:0 0 10px #398bf7b3}.auth-brand-divider{width:60px;height:2px;background:linear-gradient(90deg,transparent,#398bf7,transparent);margin:28px auto 32px;border-radius:2px}.auth-panel-left--dev{background:linear-gradient(145deg,#18040b,#3d0b1d 55%,#220409)}.auth-panel-left--dev:after{background:linear-gradient(90deg,transparent,rgba(209,50,111,.05),transparent)}.auth-panel-left--dev .auth-blob-1{background:radial-gradient(circle,rgba(220,38,38,.52) 0%,transparent 70%)}.auth-panel-left--dev .auth-blob-2{background:radial-gradient(circle,rgba(219,39,119,.44) 0%,transparent 70%)}.auth-panel-left--dev .auth-blob-3{background:radial-gradient(circle,rgba(239,68,68,.38) 0%,transparent 70%)}.auth-panel-left--dev .auth-blob-4{background:radial-gradient(circle,rgba(249,115,22,.28) 0%,transparent 70%)}.auth-panel-left--dev .auth-brand-logo{box-shadow:0 0 0 14px #d1326f12,0 0 50px #d1326f38}.auth-panel-left--dev .auth-brand-logo img{filter:brightness(1.05) drop-shadow(0 0 8px rgba(209,50,111,.45))}.auth-panel-left--dev .auth-brand-title{background:linear-gradient(135deg,#fff 20%,#fca5a5 80%);-webkit-background-clip:text;background-clip:text}.auth-panel-left--dev .auth-brand-divider{background:linear-gradient(90deg,transparent,rgb(209,50,111),transparent)}.auth-panel-left--dev .feat-dot{background:#d1326f;box-shadow:0 0 10px #d1326fb8}.auth-panel-right{position:relative;overflow:hidden;background:var(--background-login)}.auth-panel-right:before{content:\"\";position:absolute;inset:0;background-image:repeating-linear-gradient(-55deg,transparent 0px,transparent 22px,rgba(57,139,247,.045) 22px,rgba(57,139,247,.045) 23px);animation:authLinesMove 10s linear infinite;pointer-events:none;z-index:0}.auth-panel-right:after{content:\"\";position:absolute;top:0;bottom:0;left:-25%;width:25%;background:linear-gradient(90deg,transparent 0%,rgba(57,139,247,.02) 30%,rgba(57,139,247,.045) 50%,rgba(57,139,247,.02) 70%,transparent 100%);animation:authScanLine 7s ease-in-out infinite;animation-delay:3.5s;pointer-events:none;z-index:0}@keyframes authLinesMove{0%{transform:translate(0)}to{transform:translate(46px,46px)}}@keyframes authScanLine{0%{left:-25%}50%{left:120%}to{left:120%}}.auth-panel-bg{position:absolute;inset:0;pointer-events:none;z-index:0;overflow:hidden}.auth-deco{position:absolute;border-radius:50%;pointer-events:none;filter:blur(70px)}.auth-deco-tl{width:300px;height:300px;top:0;left:-120px;transform:translateY(-40%);background:radial-gradient(circle,rgba(57,139,247,.12) 0%,transparent 70%);animation:authOrbPulse 6s ease-in-out infinite}.auth-deco-br{width:340px;height:340px;bottom:0;right:-120px;transform:translateY(40%);background:radial-gradient(circle,rgba(124,58,237,.1) 0%,transparent 70%);animation:authOrbPulse 8s ease-in-out infinite;animation-delay:-4s}@keyframes authOrbPulse{0%,to{opacity:.7}50%{opacity:1}}.auth-form-wrapper{position:absolute;inset:0;overflow-y:auto;overflow-x:hidden;display:flex;flex-direction:column;align-items:center;z-index:1}.auth-form-wrapper>div{width:100%;max-width:420px;margin:auto;padding:36px 16px;box-sizing:border-box}.auth-panel-right--dev:before{background-image:repeating-linear-gradient(-55deg,transparent 0px,transparent 22px,rgba(209,50,111,.05) 22px,rgba(209,50,111,.05) 23px)}.auth-panel-right--dev:after{background:linear-gradient(90deg,transparent 0%,rgba(209,50,111,.02) 30%,rgba(209,50,111,.045) 50%,rgba(209,50,111,.02) 70%,transparent 100%)}.auth-panel-right--dev .auth-deco-tl{background:radial-gradient(circle,rgba(209,50,111,.12) 0%,transparent 70%)}.auth-panel-right--dev .auth-deco-br{background:radial-gradient(circle,rgba(239,68,68,.1) 0%,transparent 70%)}.auth-test-badge{display:inline-flex;align-items:center;gap:7px;background:#d1326f14;border:1px solid rgba(209,50,111,.25);color:#d1326f;font-size:10.5px;font-weight:700;padding:5px 12px;border-radius:20px;margin-bottom:18px;letter-spacing:.8px}.auth-test-badge .badge-dot{width:6px;height:6px;border-radius:50%;background:#d1326f;animation:badgePulse 1.6s ease-in-out infinite;flex-shrink:0}@keyframes badgePulse{0%,to{opacity:1;transform:scale(1)}50%{opacity:.45;transform:scale(.75)}}.auth-card{background:var(--background-card);border-radius:20px;padding:36px 32px 28px;box-shadow:0 4px 28px #00000014;border:1px solid var(--border-color-modal)}.auth-card-title{font-size:22px;font-weight:700;color:var(--text-color);margin-bottom:4px;letter-spacing:-.3px}.auth-card-subtitle{font-size:13px;color:var(--placeholder-color);margin-bottom:26px}.auth-field{position:relative;margin-bottom:1rem}.auth-field .auth-field-icon{position:absolute;left:13px;top:50%;transform:translateY(-50%);color:var(--placeholder-color);font-size:13px;z-index:2;pointer-events:none;transition:color .2s}.auth-field .auth-input{width:100%;padding:15px 40px 15px 37px;background:var(--background-input);border:1.5px solid var(--font-border-input);border-radius:10px;font-size:14px;color:var(--color-input);outline:none;transition:border-color .2s,box-shadow .2s,background .2s}.auth-field .auth-input::placeholder{color:transparent}.auth-field .auth-input:focus{border-color:#398bf7;box-shadow:0 0 0 3.5px #398bf721;background:var(--background-focus-input)}.auth-field .auth-input:focus~.auth-label{top:0;font-size:11px!important;color:#398bf7!important;background:var(--background-card);padding:0 4px;transform:translateY(-50%)}.auth-field .auth-input:focus~.auth-field-icon{color:#398bf7}.auth-field .auth-input:not(:placeholder-shown)~.auth-label{top:0;font-size:11px!important;background:var(--background-card);padding:0 4px;transform:translateY(-50%)}.auth-field .auth-label{position:absolute;left:35px;top:50%;transform:translateY(-50%);color:var(--placeholder-color)!important;font-size:13px!important;font-weight:400!important;pointer-events:none;transition:top .15s ease,font-size .15s ease,color .15s ease,padding .15s ease,background .15s ease;background:transparent;z-index:1;text-align:left!important}.auth-field .auth-toggle-pw{position:absolute;right:10px;top:50%;transform:translateY(-50%);background:none;border:none;color:var(--placeholder-color);cursor:pointer;padding:4px 6px;font-size:13px;z-index:2;line-height:1;transition:color .2s}.auth-field .auth-toggle-pw:hover{color:#398bf7}.auth-field.has-error .auth-input{border-color:#dc3545;box-shadow:none}.auth-field.has-error .auth-field-icon{color:#dc3545}.auth-select{width:100%;padding:13px 14px;background:var(--background-input);border:1.5px solid var(--font-border-input);border-radius:10px;font-size:14px;color:var(--color-input);outline:none;transition:border-color .2s,box-shadow .2s;margin-bottom:1rem;cursor:pointer}.auth-select:focus{border-color:#398bf7;box-shadow:0 0 0 3.5px #398bf721}.auth-btn{width:100%;padding:13px;border:none;border-radius:10px;font-size:14px;font-weight:600;cursor:pointer;transition:transform .15s ease,box-shadow .2s ease,opacity .2s;background:linear-gradient(135deg,#398bf7,#1e5fc4);color:#fff;letter-spacing:.3px;margin-bottom:10px;display:block}.auth-btn:hover:not(:disabled){transform:translateY(-1px);box-shadow:0 5px 18px #398bf761}.auth-btn:active:not(:disabled){transform:translateY(0)}.auth-btn:disabled{opacity:.55;cursor:not-allowed}.auth-btn.auth-btn--red{background:linear-gradient(135deg,#d1326f,#a82859)}.auth-btn.auth-btn--red:hover:not(:disabled){box-shadow:0 5px 18px #d1326f61}.auth-btn.auth-btn--outline{background:transparent;border:1.5px solid var(--font-border-input);color:var(--text-color)}.auth-btn.auth-btn--outline:hover:not(:disabled){background:var(--background-btn-light-hover);box-shadow:none;transform:none}.auth-links{display:flex;flex-direction:column;align-items:center;gap:10px;margin-top:16px;padding-top:16px;border-top:1px solid var(--border-color-modal)}.auth-version{text-align:right;margin-top:14px;padding-top:12px;border-top:1px solid var(--border-color-modal)}.auth-version span{font-size:11px;color:var(--placeholder-color)}.auth-error{font-size:11.5px;color:#dc3545;margin:-6px 0 10px 2px;padding:0}.auth-hint{display:flex;align-items:flex-start;gap:6px;font-size:11.5px;color:var(--placeholder-color);margin:-6px 0 14px 2px;padding:0;line-height:1.35}.auth-hint i{margin-top:2px;flex-shrink:0}.auth-validation-list{margin:-4px 0 12px;padding:0;list-style:none}.auth-validation-list li{font-size:11.5px;color:#dc3545;padding:2px 0}.auth-validation-list li:before{content:\"\\2715 \";font-size:10px}.auth-desc{font-size:13px;color:var(--placeholder-color);margin-bottom:20px;line-height:1.65}.auth-section-title{font-size:15px;font-weight:600;color:var(--text-color);margin-bottom:20px}.font-12{font-size:12px}.form-control:focus{border-color:#0199ff9a!important;box-shadow:0 0 5px .2px #65befa44!important}@media(max-width:900px){.auth-wrapper-login{grid-template-columns:1fr;grid-template-rows:auto 1fr;overflow-y:auto;overflow-x:hidden}.auth-panel-left{padding:14px 24px;justify-content:center}.auth-panel-left .auth-brand-subtitle,.auth-panel-left .auth-brand-features,.auth-panel-left .auth-brand-divider{display:none!important}.auth-panel-left .auth-brand-panel{display:flex!important;flex-direction:row!important;align-items:center;gap:0;text-align:left;max-width:none;width:100%;justify-content:center}.auth-panel-left .auth-brand-logo{width:52px;height:52px;margin:0;flex-shrink:0}.auth-panel-left .auth-brand-logo img{width:34px;height:34px}.auth-panel-left .auth-brand-title{font-size:20px;margin-bottom:0;margin-left:.5rem;flex-shrink:1}.auth-panel-right:after{inset:-25% 0 auto;width:100%;height:25%;background:linear-gradient(180deg,transparent 0%,rgba(57,139,247,.02) 30%,rgba(57,139,247,.045) 50%,rgba(57,139,247,.02) 70%,transparent 100%);animation:authScanLineV 7s ease-in-out infinite;animation-delay:3.5s}.auth-panel-right--dev:after{background:linear-gradient(180deg,transparent 0%,rgba(209,50,111,.02) 30%,rgba(209,50,111,.045) 50%,rgba(209,50,111,.02) 70%,transparent 100%)}}@keyframes authScanLineV{0%{top:-25%}50%{top:120%}to{top:120%}}@media(max-width:480px){.auth-panel-left{padding:12px 16px}.auth-panel-left .auth-brand-logo{width:44px;height:44px}.auth-panel-left .auth-brand-logo img{width:28px;height:28px}.auth-panel-left .auth-brand-title{font-size:17px}.auth-form-wrapper>div{padding:20px 12px}.auth-card{padding:24px 18px 20px;border-radius:16px}.font-12{font-size:10px!important}}\n"] });
|
|
319
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.25", type: MdVerificarMfaComponent, isStandalone: true, selector: "lib-md-verificar-mfa", inputs: { challenge: { classPropertyName: "challenge", publicName: "challenge", isSignal: true, isRequired: true, transformFunction: null }, titulo: { classPropertyName: "titulo", publicName: "titulo", isSignal: true, isRequired: false, transformFunction: null }, showCancelar: { classPropertyName: "showCancelar", publicName: "showCancelar", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { verificado: "verificado", cancelado: "cancelado" }, viewQueries: [{ propertyName: "inputCodigo", first: true, predicate: ["inputCodigo"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"verificar-mfa\">\n <div class=\"auth-card-title mb-3\">{{ titulo() }}</div>\n\n <div class=\"d-flex align-items-center gap-3 mb-3\">\n <span class=\"verificar-mfa__icono\"><i class=\"fas fa-user-shield\"></i></span>\n <div>\n <div class=\"fw-semibold\">{{ challenge().coduser }}</div>\n @if (challenge().empresa) {\n <div class=\"verificar-mfa__muted\">{{ challenge().empresa }}</div>\n }\n </div>\n </div>\n\n @if (modo() == 'push') {\n @switch (estadoPush()) {\n @case ('enviando') {\n <div class=\"duo-push\">\n <span class=\"spinner-border spinner-border-sm text-primary\"></span>\n <div class=\"flex-grow-1\">Enviando notificaci\u00F3n a tu tel\u00E9fono\u2026</div>\n </div>\n }\n @case ('esperando') {\n <div class=\"duo-push duo-push--esperando\">\n <span class=\"duo-push__icono duo-push__icono--pulso\"><i class=\"fas fa-mobile-alt\"></i></span>\n <div class=\"flex-grow-1\">\n <div class=\"fw-semibold\">Revisa tu tel\u00E9fono</div>\n <div class=\"verificar-mfa__muted\">Aprueba la notificaci\u00F3n en TSI Autenticador para ingresar.</div>\n </div>\n </div>\n @if (numberMatching() != null) {\n <div class=\"number-matching\" role=\"status\" aria-live=\"polite\">\n <div class=\"verificar-mfa__muted\">Confirma que tu tel\u00E9fono muestre este n\u00FAmero</div>\n <div class=\"number-matching__valor\">{{ numberMatching() }}</div>\n </div>\n }\n }\n @default {\n <div class=\"duo-push\">\n <span class=\"duo-push__icono\"><i class=\"fas fa-bell\"></i></span>\n <div class=\"flex-grow-1\">\n <div class=\"fw-semibold\">TSI Autenticador</div>\n <div class=\"verificar-mfa__muted\">Te enviaremos una notificaci\u00F3n para que la apruebes.</div>\n </div>\n </div>\n }\n }\n @if (pushError() && !isPushEnCurso()) {\n <div class=\"codigo-field__error\"><i class=\"fas fa-exclamation-circle\"></i> {{ pushError() }}</div>\n }\n\n <div class=\"verificar-mfa__opciones\">\n @if (tieneTotp()) {\n <button type=\"button\" class=\"verificar-mfa__link\" (click)=\"usarCodigo('totp')\">\n Usar c\u00F3digo de mi app de autenticaci\u00F3n\n </button>\n }\n <button type=\"button\" class=\"verificar-mfa__link verificar-mfa__link--secundario\"\n (click)=\"usarCodigo('respaldo')\">\n \u00BFNo tienes tu tel\u00E9fono? Usa un c\u00F3digo de respaldo\n </button>\n </div>\n } @else {\n <p class=\"verificar-mfa__muted mb-4\">\n @if (tipoCodigo() == 'totp') {\n {{ challenge().mensaje || campo().descri }}\n } @else {\n {{ campo().descri }}\n }\n </p>\n\n <div class=\"codigo-field\" [class.has-error]=\"codigoError()\">\n <span class=\"codigo-field__icon\"><i class=\"fas\" [class]=\"campo().icon\"></i></span>\n <input #inputCodigo id=\"mfa-codigo\" class=\"codigo-field__input\" type=\"text\"\n [placeholder]=\"campo().placeholder\" [value]=\"codigo()\" (input)=\"onCodigoInput($event)\"\n (keydown.enter)=\"verificar()\" [attr.inputmode]=\"campo().inputmode\" autocomplete=\"one-time-code\"\n autocorrect=\"off\" autocapitalize=\"characters\" spellcheck=\"false\" [disabled]=\"isEnviando()\">\n <label for=\"mfa-codigo\" class=\"codigo-field__label\">{{ campo().label }}</label>\n </div>\n @if (codigoError()) {\n <div class=\"codigo-field__error\"><i class=\"fas fa-exclamation-circle\"></i> {{ codigoError() }}</div>\n }\n\n <div class=\"verificar-mfa__opciones\">\n @if (tienePush()) {\n <button type=\"button\" class=\"verificar-mfa__link\" (click)=\"usarPush()\">\n <i class=\"fas fa-bell me-1\"></i>Mejor env\u00EDame una notificaci\u00F3n push\n </button>\n }\n @if (tieneTotp() && tipoCodigo() != 'totp') {\n <button type=\"button\" class=\"verificar-mfa__link\" (click)=\"usarCodigo('totp')\">\n Usar c\u00F3digo de mi app de autenticaci\u00F3n\n </button>\n }\n @if (tipoCodigo() != 'respaldo') {\n <button type=\"button\" class=\"verificar-mfa__link verificar-mfa__link--secundario\"\n (click)=\"usarCodigo('respaldo')\">\n \u00BFNo tienes tu tel\u00E9fono? Usa un c\u00F3digo de respaldo\n </button>\n }\n </div>\n }\n\n <div class=\"verificar-mfa__acciones\">\n @if (modo() == 'push') {\n <button type=\"button\" class=\"auth-btn\" [disabled]=\"isPushEnCurso()\" (click)=\"enviarPush()\">\n <i class=\"fas fa-paper-plane me-1\"></i>\n {{ isPushEnCurso() ? 'Esperando aprobaci\u00F3n\u2026' : 'Reenviar notificaci\u00F3n' }}\n </button>\n } @else {\n <button type=\"button\" class=\"auth-btn\" [disabled]=\"isEnviando()\" (click)=\"verificar()\">\n <i class=\"fas fa-check me-1\"></i>\n {{ isEnviando() ? 'Verificando\u2026' : 'Verificar' }}\n </button>\n }\n @if (showCancelar()) {\n <button type=\"button\" class=\"auth-btn auth-btn--outline\" (click)=\"cancelar()\">Cancelar</button>\n }\n </div>\n</div>\n", styles: [".verificar-mfa{color:var(--text-color)}.verificar-mfa__icono{display:inline-flex;flex-shrink:0;align-items:center;justify-content:center;width:44px;height:44px;border-radius:12px;color:var(--bs-primary);background:rgba(var(--bs-primary-rgb),.1);font-size:20px}.verificar-mfa__muted{font-size:13px;line-height:1.5;color:var(--bs-secondary-color)}.verificar-mfa__link:hover{text-decoration:underline}.verificar-mfa__link{padding:0;border:0;background:none;font-size:13px;font-weight:600;color:var(--bs-primary)}.codigo-field{position:relative}.codigo-field__icon{position:absolute;left:14px;top:50%;transform:translateY(-50%);z-index:2;font-size:15px;color:var(--placeholder-color);pointer-events:none;transition:color .2s}.codigo-field__input{width:100%;height:56px;padding:0 44px;border:1.5px solid var(--font-border-input);border-radius:10px;outline:none;background:var(--background-input);color:var(--color-input);font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:22px;font-weight:600;letter-spacing:.45em;text-align:center;transition:border-color .2s,box-shadow .2s,background .2s}.codigo-field__input::placeholder{color:var(--placeholder-color);opacity:.45}.codigo-field__input:focus{border-color:var(--bs-primary);box-shadow:0 0 0 3.5px rgba(var(--bs-primary-rgb),.15);background:var(--background-focus-input)}.codigo-field__input:disabled{opacity:.7}.codigo-field__label{position:absolute;left:12px;top:0;transform:translateY(-50%);z-index:1;margin:0!important;padding:0 4px;font-size:11px!important;font-weight:500!important;line-height:1.2;color:var(--placeholder-color);background:var(--background-card);pointer-events:none;transition:color .15s ease}.codigo-field:focus-within .codigo-field__label,.codigo-field:focus-within .codigo-field__icon{color:var(--bs-primary)}.codigo-field.has-error .codigo-field__input{border-color:var(--bs-danger);box-shadow:0 0 0 3.5px rgba(var(--bs-danger-rgb),.12)}.codigo-field.has-error .codigo-field__icon,.codigo-field.has-error .codigo-field__label{color:var(--bs-danger)}.codigo-field__error{display:flex;align-items:center;gap:6px;margin-top:8px;font-size:13px;font-weight:500;color:var(--bs-danger)}.duo-push{display:flex;align-items:center;gap:12px;padding:14px;border:1.5px solid var(--font-border-input);border-radius:10px;background:var(--background-input);color:var(--text-color);font-size:14px}.duo-push--esperando{border-color:rgba(var(--bs-primary-rgb),.45);background:rgba(var(--bs-primary-rgb),.06)}.duo-push__icono{display:inline-flex;flex-shrink:0;align-items:center;justify-content:center;width:40px;height:40px;border-radius:50%;color:var(--bs-primary);background:rgba(var(--bs-primary-rgb),.1);font-size:18px}.duo-push__icono--pulso{animation:duo-pulso 1.4s ease-in-out infinite}.number-matching{margin-top:12px;padding:16px;border:1.5px dashed rgba(var(--bs-primary-rgb),.45);border-radius:10px;text-align:center}.number-matching__valor{margin-top:4px;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:40px;font-weight:700;line-height:1.1;letter-spacing:.12em;color:var(--bs-primary)}@keyframes duo-pulso{0%,to{box-shadow:0 0 rgba(var(--bs-primary-rgb),.35)}50%{box-shadow:0 0 0 8px rgba(var(--bs-primary-rgb),0)}}@media(prefers-reduced-motion:reduce){.duo-push__icono--pulso{animation:none}}.verificar-mfa__opciones{display:flex;flex-direction:column;align-items:flex-start;gap:8px;margin-top:16px}.verificar-mfa__link--secundario{font-weight:500;color:var(--bs-secondary-color)}.verificar-mfa__acciones{margin-top:24px}\n", "@charset \"UTF-8\";.red_contrasena,.blue_contrasena{position:relative;display:inline-block;font-size:13px;text-decoration:none;padding-bottom:2px;transition:color .3s ease;cursor:pointer}.red_contrasena:after,.blue_contrasena:after{content:\"\";position:absolute;bottom:0;left:50%;width:0;height:1px;background-color:currentColor;transition:all .3s ease;transform:translate(-50%)}.red_contrasena:hover:after,.blue_contrasena:hover:after{width:60%}.red_contrasena{color:#d1326f}.red_contrasena:hover{color:#a82859}.blue_contrasena{color:#398bf7}.blue_contrasena:hover{color:#1e5fc4}.auth-wrapper-login{position:fixed;inset:0;display:grid;grid-template-columns:1.15fr .85fr;overflow:hidden;background:#060d1f}.auth-panel-left{position:relative;overflow:hidden;background:linear-gradient(145deg,#040a18,#0b1a3d 55%,#040e22);display:flex;align-items:center;justify-content:center;padding:48px 40px}.auth-panel-left:before{content:\"\";position:absolute;inset:0;background-image:radial-gradient(circle,rgba(255,255,255,.055) 1px,transparent 1px);background-size:26px 26px;z-index:1;pointer-events:none}.auth-panel-left:after{content:\"\";position:absolute;top:0;left:-120%;width:60%;height:100%;background:linear-gradient(90deg,transparent,rgba(57,139,247,.04),transparent);animation:panelSweep 7s ease-in-out infinite;z-index:1;pointer-events:none}.auth-blob{position:absolute;border-radius:50%;filter:blur(72px);z-index:0;pointer-events:none}.auth-blob-1{width:340px;height:340px;background:radial-gradient(circle,rgba(57,139,247,.45) 0%,transparent 70%);top:-90px;right:-70px;animation:blobDrift 11s ease-in-out infinite}.auth-blob-2{width:240px;height:240px;background:radial-gradient(circle,rgba(124,58,237,.4) 0%,transparent 70%);bottom:60px;left:-50px;animation:blobDrift 14s ease-in-out infinite reverse}.auth-blob-3{width:180px;height:180px;background:radial-gradient(circle,rgba(14,165,233,.35) 0%,transparent 70%);bottom:-50px;right:40px;animation:blobDrift 9s ease-in-out infinite;animation-delay:-4s}.auth-blob-4{width:120px;height:120px;background:radial-gradient(circle,rgba(209,50,111,.25) 0%,transparent 70%);top:50%;left:50%;transform:translate(-50%,-50%);animation:blobDrift 16s ease-in-out infinite;animation-delay:-8s}@keyframes blobDrift{0%,to{transform:translate(0) scale(1)}33%{transform:translate(14px,-20px) scale(1.05)}66%{transform:translate(-10px,12px) scale(.96)}}@keyframes panelSweep{0%{left:-120%}50%{left:160%}to{left:160%}}.auth-brand-panel{position:relative;z-index:2;text-align:center;color:#fff;max-width:340px}.auth-brand-logo{width:100px;height:100px;border-radius:50%;background:#ffffff0d;border:1px solid rgba(255,255,255,.1);display:flex;align-items:center;justify-content:center;margin:0 auto 28px;box-shadow:0 0 0 14px #398bf70f,0 0 50px #398bf733;backdrop-filter:blur(8px)}.auth-brand-logo img{width:64px;height:64px;object-fit:contain;filter:brightness(1.05) drop-shadow(0 0 8px rgba(57,139,247,.4))}.auth-brand-title{font-size:30px;font-weight:700;letter-spacing:-.5px;margin-bottom:10px;background:linear-gradient(135deg,#fff 20%,#93c5fd 80%);-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text}.auth-brand-subtitle{font-size:14px;color:#ffffff73;line-height:1.65;margin-bottom:40px;letter-spacing:.2px}.auth-brand-features{display:flex;flex-direction:column;gap:14px;text-align:left}.auth-brand-feature{display:flex;align-items:center;gap:12px;font-size:13px;color:#fff9}.auth-brand-feature .feat-dot{flex-shrink:0;width:7px;height:7px;border-radius:50%;background:#398bf7;box-shadow:0 0 10px #398bf7b3}.auth-brand-divider{width:60px;height:2px;background:linear-gradient(90deg,transparent,#398bf7,transparent);margin:28px auto 32px;border-radius:2px}.auth-panel-left--dev{background:linear-gradient(145deg,#18040b,#3d0b1d 55%,#220409)}.auth-panel-left--dev:after{background:linear-gradient(90deg,transparent,rgba(209,50,111,.05),transparent)}.auth-panel-left--dev .auth-blob-1{background:radial-gradient(circle,rgba(220,38,38,.52) 0%,transparent 70%)}.auth-panel-left--dev .auth-blob-2{background:radial-gradient(circle,rgba(219,39,119,.44) 0%,transparent 70%)}.auth-panel-left--dev .auth-blob-3{background:radial-gradient(circle,rgba(239,68,68,.38) 0%,transparent 70%)}.auth-panel-left--dev .auth-blob-4{background:radial-gradient(circle,rgba(249,115,22,.28) 0%,transparent 70%)}.auth-panel-left--dev .auth-brand-logo{box-shadow:0 0 0 14px #d1326f12,0 0 50px #d1326f38}.auth-panel-left--dev .auth-brand-logo img{filter:brightness(1.05) drop-shadow(0 0 8px rgba(209,50,111,.45))}.auth-panel-left--dev .auth-brand-title{background:linear-gradient(135deg,#fff 20%,#fca5a5 80%);-webkit-background-clip:text;background-clip:text}.auth-panel-left--dev .auth-brand-divider{background:linear-gradient(90deg,transparent,rgb(209,50,111),transparent)}.auth-panel-left--dev .feat-dot{background:#d1326f;box-shadow:0 0 10px #d1326fb8}.auth-panel-right{position:relative;overflow:hidden;background:var(--background-login)}.auth-panel-right:before{content:\"\";position:absolute;inset:0;background-image:repeating-linear-gradient(-55deg,transparent 0px,transparent 22px,rgba(57,139,247,.045) 22px,rgba(57,139,247,.045) 23px);animation:authLinesMove 10s linear infinite;pointer-events:none;z-index:0}.auth-panel-right:after{content:\"\";position:absolute;top:0;bottom:0;left:-25%;width:25%;background:linear-gradient(90deg,transparent 0%,rgba(57,139,247,.02) 30%,rgba(57,139,247,.045) 50%,rgba(57,139,247,.02) 70%,transparent 100%);animation:authScanLine 7s ease-in-out infinite;animation-delay:3.5s;pointer-events:none;z-index:0}@keyframes authLinesMove{0%{transform:translate(0)}to{transform:translate(46px,46px)}}@keyframes authScanLine{0%{left:-25%}50%{left:120%}to{left:120%}}.auth-panel-bg{position:absolute;inset:0;pointer-events:none;z-index:0;overflow:hidden}.auth-deco{position:absolute;border-radius:50%;pointer-events:none;filter:blur(70px)}.auth-deco-tl{width:300px;height:300px;top:0;left:-120px;transform:translateY(-40%);background:radial-gradient(circle,rgba(57,139,247,.12) 0%,transparent 70%);animation:authOrbPulse 6s ease-in-out infinite}.auth-deco-br{width:340px;height:340px;bottom:0;right:-120px;transform:translateY(40%);background:radial-gradient(circle,rgba(124,58,237,.1) 0%,transparent 70%);animation:authOrbPulse 8s ease-in-out infinite;animation-delay:-4s}@keyframes authOrbPulse{0%,to{opacity:.7}50%{opacity:1}}.auth-form-wrapper{position:absolute;inset:0;overflow-y:auto;overflow-x:hidden;display:flex;flex-direction:column;align-items:center;z-index:1}.auth-form-wrapper>div{width:100%;max-width:420px;margin:auto;padding:36px 16px;box-sizing:border-box}.auth-panel-right--dev:before{background-image:repeating-linear-gradient(-55deg,transparent 0px,transparent 22px,rgba(209,50,111,.05) 22px,rgba(209,50,111,.05) 23px)}.auth-panel-right--dev:after{background:linear-gradient(90deg,transparent 0%,rgba(209,50,111,.02) 30%,rgba(209,50,111,.045) 50%,rgba(209,50,111,.02) 70%,transparent 100%)}.auth-panel-right--dev .auth-deco-tl{background:radial-gradient(circle,rgba(209,50,111,.12) 0%,transparent 70%)}.auth-panel-right--dev .auth-deco-br{background:radial-gradient(circle,rgba(239,68,68,.1) 0%,transparent 70%)}.auth-test-badge{display:inline-flex;align-items:center;gap:7px;background:#d1326f14;border:1px solid rgba(209,50,111,.25);color:#d1326f;font-size:10.5px;font-weight:700;padding:5px 12px;border-radius:20px;margin-bottom:18px;letter-spacing:.8px}.auth-test-badge .badge-dot{width:6px;height:6px;border-radius:50%;background:#d1326f;animation:badgePulse 1.6s ease-in-out infinite;flex-shrink:0}@keyframes badgePulse{0%,to{opacity:1;transform:scale(1)}50%{opacity:.45;transform:scale(.75)}}.auth-card{background:var(--background-card);border-radius:20px;padding:36px 32px 28px;box-shadow:0 4px 28px #00000014;border:1px solid var(--border-color-modal)}.auth-card-title{font-size:22px;font-weight:700;color:var(--text-color);margin-bottom:4px;letter-spacing:-.3px}.auth-card-subtitle{font-size:13px;color:var(--placeholder-color);margin-bottom:26px}.auth-field{position:relative;margin-bottom:1rem}.auth-field .auth-field-icon{position:absolute;left:13px;top:50%;transform:translateY(-50%);color:var(--placeholder-color);font-size:13px;z-index:2;pointer-events:none;transition:color .2s}.auth-field .auth-input{width:100%;padding:15px 40px 15px 37px;background:var(--background-input);border:1.5px solid var(--font-border-input);border-radius:10px;font-size:14px;color:var(--color-input);outline:none;transition:border-color .2s,box-shadow .2s,background .2s}.auth-field .auth-input::placeholder{color:transparent}.auth-field .auth-input:focus{border-color:#398bf7;box-shadow:0 0 0 3.5px #398bf721;background:var(--background-focus-input)}.auth-field .auth-input:focus~.auth-label{top:0;font-size:11px!important;color:#398bf7!important;background:var(--background-card);padding:0 4px;transform:translateY(-50%)}.auth-field .auth-input:focus~.auth-field-icon{color:#398bf7}.auth-field .auth-input:not(:placeholder-shown)~.auth-label{top:0;font-size:11px!important;background:var(--background-card);padding:0 4px;transform:translateY(-50%)}.auth-field .auth-label{position:absolute;left:35px;top:50%;transform:translateY(-50%);color:var(--placeholder-color)!important;font-size:13px!important;font-weight:400!important;pointer-events:none;transition:top .15s ease,font-size .15s ease,color .15s ease,padding .15s ease,background .15s ease;background:transparent;z-index:1;text-align:left!important}.auth-field .auth-toggle-pw{position:absolute;right:10px;top:50%;transform:translateY(-50%);background:none;border:none;color:var(--placeholder-color);cursor:pointer;padding:4px 6px;font-size:13px;z-index:2;line-height:1;transition:color .2s}.auth-field .auth-toggle-pw:hover{color:#398bf7}.auth-field.has-error .auth-input{border-color:#dc3545;box-shadow:none}.auth-field.has-error .auth-field-icon{color:#dc3545}.auth-select{width:100%;padding:13px 14px;background:var(--background-input);border:1.5px solid var(--font-border-input);border-radius:10px;font-size:14px;color:var(--color-input);outline:none;transition:border-color .2s,box-shadow .2s;margin-bottom:1rem;cursor:pointer}.auth-select:focus{border-color:#398bf7;box-shadow:0 0 0 3.5px #398bf721}.auth-btn{width:100%;padding:13px;border:none;border-radius:10px;font-size:14px;font-weight:600;cursor:pointer;transition:transform .15s ease,box-shadow .2s ease,opacity .2s;background:linear-gradient(135deg,#398bf7,#1e5fc4);color:#fff;letter-spacing:.3px;margin-bottom:10px;display:block}.auth-btn:hover:not(:disabled){transform:translateY(-1px);box-shadow:0 5px 18px #398bf761}.auth-btn:active:not(:disabled){transform:translateY(0)}.auth-btn:disabled{opacity:.55;cursor:not-allowed}.auth-btn.auth-btn--red{background:linear-gradient(135deg,#d1326f,#a82859)}.auth-btn.auth-btn--red:hover:not(:disabled){box-shadow:0 5px 18px #d1326f61}.auth-btn.auth-btn--outline{background:transparent;border:1.5px solid var(--font-border-input);color:var(--text-color)}.auth-btn.auth-btn--outline:hover:not(:disabled){background:var(--background-btn-light-hover);box-shadow:none;transform:none}.auth-links{display:flex;flex-direction:column;align-items:center;gap:10px;margin-top:16px;padding-top:16px;border-top:1px solid var(--border-color-modal)}.auth-version{text-align:right;margin-top:14px;padding-top:12px;border-top:1px solid var(--border-color-modal)}.auth-version span{font-size:11px;color:var(--placeholder-color)}.auth-error{font-size:11.5px;color:#dc3545;margin:-6px 0 10px 2px;padding:0}.auth-hint{display:flex;align-items:flex-start;gap:6px;font-size:11.5px;color:var(--placeholder-color);margin:-6px 0 14px 2px;padding:0;line-height:1.35}.auth-hint i{margin-top:2px;flex-shrink:0}.auth-validation-list{margin:-4px 0 12px;padding:0;list-style:none}.auth-validation-list li{font-size:11.5px;color:#dc3545;padding:2px 0}.auth-validation-list li:before{content:\"\\2715 \";font-size:10px}.auth-desc{font-size:13px;color:var(--placeholder-color);margin-bottom:20px;line-height:1.65}.auth-section-title{font-size:15px;font-weight:600;color:var(--text-color);margin-bottom:20px}.font-12{font-size:12px}.form-control:focus{border-color:#0199ff9a!important;box-shadow:0 0 5px .2px #65befa44!important}@media(max-width:900px){.auth-wrapper-login{grid-template-columns:1fr;grid-template-rows:auto 1fr;overflow-y:auto;overflow-x:hidden}.auth-panel-left{padding:14px 24px;justify-content:center}.auth-panel-left .auth-brand-subtitle,.auth-panel-left .auth-brand-features,.auth-panel-left .auth-brand-divider{display:none!important}.auth-panel-left .auth-brand-panel{display:flex!important;flex-direction:row!important;align-items:center;gap:0;text-align:left;max-width:none;width:100%;justify-content:center}.auth-panel-left .auth-brand-logo{width:52px;height:52px;margin:0;flex-shrink:0}.auth-panel-left .auth-brand-logo img{width:34px;height:34px}.auth-panel-left .auth-brand-title{font-size:20px;margin-bottom:0;margin-left:.5rem;flex-shrink:1}.auth-panel-right:after{inset:-25% 0 auto;width:100%;height:25%;background:linear-gradient(180deg,transparent 0%,rgba(57,139,247,.02) 30%,rgba(57,139,247,.045) 50%,rgba(57,139,247,.02) 70%,transparent 100%);animation:authScanLineV 7s ease-in-out infinite;animation-delay:3.5s}.auth-panel-right--dev:after{background:linear-gradient(180deg,transparent 0%,rgba(209,50,111,.02) 30%,rgba(209,50,111,.045) 50%,rgba(209,50,111,.02) 70%,transparent 100%)}}@keyframes authScanLineV{0%{top:-25%}50%{top:120%}to{top:120%}}@media(max-width:480px){.auth-panel-left{padding:12px 16px}.auth-panel-left .auth-brand-logo{width:44px;height:44px}.auth-panel-left .auth-brand-logo img{width:28px;height:28px}.auth-panel-left .auth-brand-title{font-size:17px}.auth-form-wrapper>div{padding:20px 12px}.auth-card{padding:24px 18px 20px;border-radius:16px}.font-12{font-size:10px!important}}\n"] });
|
|
314
320
|
}
|
|
315
321
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: MdVerificarMfaComponent, decorators: [{
|
|
316
322
|
type: Component,
|
|
317
|
-
args: [{ selector: 'lib-md-verificar-mfa', template: "<div class=\"verificar-mfa\">\n <div class=\"auth-card-title mb-3\">{{ titulo() }}</div>\n\n <div class=\"d-flex align-items-center gap-3 mb-3\">\n <span class=\"verificar-mfa__icono\"><i class=\"fas fa-user-shield\"></i></span>\n <div>\n <div class=\"fw-semibold\">{{ challenge().coduser }}</div>\n @if (challenge().empresa) {\n <div class=\"verificar-mfa__muted\">{{ challenge().empresa }}</div>\n }\n </div>\n </div>\n\n @if (modo() == 'push') {\n @switch (estadoPush()) {\n @case ('enviando') {\n <div class=\"duo-push\">\n <span class=\"spinner-border spinner-border-sm text-primary\"></span>\n <div class=\"flex-grow-1\">Enviando notificaci\u00F3n a tu tel\u00E9fono\u2026</div>\n </div>\n }\n @case ('esperando') {\n <div class=\"duo-push duo-push--esperando\">\n <span class=\"duo-push__icono duo-push__icono--pulso\"><i class=\"fas fa-mobile-alt\"></i></span>\n <div class=\"flex-grow-1\">\n <div class=\"fw-semibold\">Revisa tu tel\u00E9fono</div>\n <div class=\"verificar-mfa__muted\">Aprueba la notificaci\u00F3n en TSI Autenticador para ingresar.</div>\n </div>\n </div>\n }\n @default {\n <div class=\"duo-push\">\n <span class=\"duo-push__icono\"><i class=\"fas fa-bell\"></i></span>\n <div class=\"flex-grow-1\">\n <div class=\"fw-semibold\">TSI Autenticador</div>\n <div class=\"verificar-mfa__muted\">Te enviaremos una notificaci\u00F3n para que la apruebes.</div>\n </div>\n </div>\n }\n }\n @if (pushError() && !isPushEnCurso()) {\n <div class=\"codigo-field__error\"><i class=\"fas fa-exclamation-circle\"></i> {{ pushError() }}</div>\n }\n\n <div class=\"verificar-mfa__opciones\">\n @if (tieneTotp()) {\n <button type=\"button\" class=\"verificar-mfa__link\" (click)=\"usarCodigo('totp')\">\n Usar c\u00F3digo de mi app de autenticaci\u00F3n\n </button>\n }\n <button type=\"button\" class=\"verificar-mfa__link verificar-mfa__link--secundario\"\n (click)=\"usarCodigo('respaldo')\">\n \u00BFNo tienes tu tel\u00E9fono? Usa un c\u00F3digo de respaldo\n </button>\n </div>\n } @else {\n <p class=\"verificar-mfa__muted mb-4\">\n @if (tipoCodigo() == 'totp') {\n {{ challenge().mensaje || campo().descri }}\n } @else {\n {{ campo().descri }}\n }\n </p>\n\n <div class=\"codigo-field\" [class.has-error]=\"codigoError()\">\n <span class=\"codigo-field__icon\"><i class=\"fas\" [class]=\"campo().icon\"></i></span>\n <input #inputCodigo id=\"mfa-codigo\" class=\"codigo-field__input\" type=\"text\"\n [placeholder]=\"campo().placeholder\" [value]=\"codigo()\" (input)=\"onCodigoInput($event)\"\n (keydown.enter)=\"verificar()\" [attr.inputmode]=\"campo().inputmode\" autocomplete=\"one-time-code\"\n autocorrect=\"off\" autocapitalize=\"characters\" spellcheck=\"false\" [disabled]=\"isEnviando()\">\n <label for=\"mfa-codigo\" class=\"codigo-field__label\">{{ campo().label }}</label>\n </div>\n @if (codigoError()) {\n <div class=\"codigo-field__error\"><i class=\"fas fa-exclamation-circle\"></i> {{ codigoError() }}</div>\n }\n\n <div class=\"verificar-mfa__opciones\">\n @if (tienePush()) {\n <button type=\"button\" class=\"verificar-mfa__link\" (click)=\"usarPush()\">\n <i class=\"fas fa-bell me-1\"></i>Mejor env\u00EDame una notificaci\u00F3n push\n </button>\n }\n @if (tieneTotp() && tipoCodigo() != 'totp') {\n <button type=\"button\" class=\"verificar-mfa__link\" (click)=\"usarCodigo('totp')\">\n Usar c\u00F3digo de mi app de autenticaci\u00F3n\n </button>\n }\n @if (tipoCodigo() != 'respaldo') {\n <button type=\"button\" class=\"verificar-mfa__link verificar-mfa__link--secundario\"\n (click)=\"usarCodigo('respaldo')\">\n \u00BFNo tienes tu tel\u00E9fono? Usa un c\u00F3digo de respaldo\n </button>\n }\n </div>\n }\n\n <div class=\"verificar-mfa__acciones\">\n @if (modo() == 'push') {\n <button type=\"button\" class=\"auth-btn\" [disabled]=\"isPushEnCurso()\" (click)=\"enviarPush()\">\n <i class=\"fas fa-paper-plane me-1\"></i>\n {{ isPushEnCurso() ? 'Esperando aprobaci\u00F3n\u2026' : 'Reenviar notificaci\u00F3n' }}\n </button>\n } @else {\n <button type=\"button\" class=\"auth-btn\" [disabled]=\"isEnviando()\" (click)=\"verificar()\">\n <i class=\"fas fa-check me-1\"></i>\n {{ isEnviando() ? 'Verificando\u2026' : 'Verificar' }}\n </button>\n }\n @if (showCancelar()) {\n <button type=\"button\" class=\"auth-btn auth-btn--outline\" (click)=\"cancelar()\">Cancelar</button>\n }\n </div>\n</div>\n", styles: [".verificar-mfa{color:var(--text-color)}.verificar-mfa__icono{display:inline-flex;flex-shrink:0;align-items:center;justify-content:center;width:44px;height:44px;border-radius:12px;color:var(--bs-primary);background:rgba(var(--bs-primary-rgb),.1);font-size:20px}.verificar-mfa__muted{font-size:13px;line-height:1.5;color:var(--bs-secondary-color)}.verificar-mfa__link:hover{text-decoration:underline}.verificar-mfa__link{padding:0;border:0;background:none;font-size:13px;font-weight:600;color:var(--bs-primary)}.codigo-field{position:relative}.codigo-field__icon{position:absolute;left:14px;top:50%;transform:translateY(-50%);z-index:2;font-size:15px;color:var(--placeholder-color);pointer-events:none;transition:color .2s}.codigo-field__input{width:100%;height:56px;padding:0 44px;border:1.5px solid var(--font-border-input);border-radius:10px;outline:none;background:var(--background-input);color:var(--color-input);font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:22px;font-weight:600;letter-spacing:.45em;text-align:center;transition:border-color .2s,box-shadow .2s,background .2s}.codigo-field__input::placeholder{color:var(--placeholder-color);opacity:.45}.codigo-field__input:focus{border-color:var(--bs-primary);box-shadow:0 0 0 3.5px rgba(var(--bs-primary-rgb),.15);background:var(--background-focus-input)}.codigo-field__input:disabled{opacity:.7}.codigo-field__label{position:absolute;left:12px;top:0;transform:translateY(-50%);z-index:1;margin:0!important;padding:0 4px;font-size:11px!important;font-weight:500!important;line-height:1.2;color:var(--placeholder-color);background:var(--background-card);pointer-events:none;transition:color .15s ease}.codigo-field:focus-within .codigo-field__label,.codigo-field:focus-within .codigo-field__icon{color:var(--bs-primary)}.codigo-field.has-error .codigo-field__input{border-color:var(--bs-danger);box-shadow:0 0 0 3.5px rgba(var(--bs-danger-rgb),.12)}.codigo-field.has-error .codigo-field__icon,.codigo-field.has-error .codigo-field__label{color:var(--bs-danger)}.codigo-field__error{display:flex;align-items:center;gap:6px;margin-top:8px;font-size:13px;font-weight:500;color:var(--bs-danger)}.duo-push{display:flex;align-items:center;gap:12px;padding:14px;border:1.5px solid var(--font-border-input);border-radius:10px;background:var(--background-input);color:var(--text-color);font-size:14px}.duo-push--esperando{border-color:rgba(var(--bs-primary-rgb),.45);background:rgba(var(--bs-primary-rgb),.06)}.duo-push__icono{display:inline-flex;flex-shrink:0;align-items:center;justify-content:center;width:40px;height:40px;border-radius:50%;color:var(--bs-primary);background:rgba(var(--bs-primary-rgb),.1);font-size:18px}.duo-push__icono--pulso{animation:duo-pulso 1.4s ease-in-out infinite}@keyframes duo-pulso{0%,to{box-shadow:0 0 rgba(var(--bs-primary-rgb),.35)}50%{box-shadow:0 0 0 8px rgba(var(--bs-primary-rgb),0)}}@media(prefers-reduced-motion:reduce){.duo-push__icono--pulso{animation:none}}.verificar-mfa__opciones{display:flex;flex-direction:column;align-items:flex-start;gap:8px;margin-top:16px}.verificar-mfa__link--secundario{font-weight:500;color:var(--bs-secondary-color)}.verificar-mfa__acciones{margin-top:24px}\n", "@charset \"UTF-8\";.red_contrasena,.blue_contrasena{position:relative;display:inline-block;font-size:13px;text-decoration:none;padding-bottom:2px;transition:color .3s ease;cursor:pointer}.red_contrasena:after,.blue_contrasena:after{content:\"\";position:absolute;bottom:0;left:50%;width:0;height:1px;background-color:currentColor;transition:all .3s ease;transform:translate(-50%)}.red_contrasena:hover:after,.blue_contrasena:hover:after{width:60%}.red_contrasena{color:#d1326f}.red_contrasena:hover{color:#a82859}.blue_contrasena{color:#398bf7}.blue_contrasena:hover{color:#1e5fc4}.auth-wrapper-login{position:fixed;inset:0;display:grid;grid-template-columns:1.15fr .85fr;overflow:hidden;background:#060d1f}.auth-panel-left{position:relative;overflow:hidden;background:linear-gradient(145deg,#040a18,#0b1a3d 55%,#040e22);display:flex;align-items:center;justify-content:center;padding:48px 40px}.auth-panel-left:before{content:\"\";position:absolute;inset:0;background-image:radial-gradient(circle,rgba(255,255,255,.055) 1px,transparent 1px);background-size:26px 26px;z-index:1;pointer-events:none}.auth-panel-left:after{content:\"\";position:absolute;top:0;left:-120%;width:60%;height:100%;background:linear-gradient(90deg,transparent,rgba(57,139,247,.04),transparent);animation:panelSweep 7s ease-in-out infinite;z-index:1;pointer-events:none}.auth-blob{position:absolute;border-radius:50%;filter:blur(72px);z-index:0;pointer-events:none}.auth-blob-1{width:340px;height:340px;background:radial-gradient(circle,rgba(57,139,247,.45) 0%,transparent 70%);top:-90px;right:-70px;animation:blobDrift 11s ease-in-out infinite}.auth-blob-2{width:240px;height:240px;background:radial-gradient(circle,rgba(124,58,237,.4) 0%,transparent 70%);bottom:60px;left:-50px;animation:blobDrift 14s ease-in-out infinite reverse}.auth-blob-3{width:180px;height:180px;background:radial-gradient(circle,rgba(14,165,233,.35) 0%,transparent 70%);bottom:-50px;right:40px;animation:blobDrift 9s ease-in-out infinite;animation-delay:-4s}.auth-blob-4{width:120px;height:120px;background:radial-gradient(circle,rgba(209,50,111,.25) 0%,transparent 70%);top:50%;left:50%;transform:translate(-50%,-50%);animation:blobDrift 16s ease-in-out infinite;animation-delay:-8s}@keyframes blobDrift{0%,to{transform:translate(0) scale(1)}33%{transform:translate(14px,-20px) scale(1.05)}66%{transform:translate(-10px,12px) scale(.96)}}@keyframes panelSweep{0%{left:-120%}50%{left:160%}to{left:160%}}.auth-brand-panel{position:relative;z-index:2;text-align:center;color:#fff;max-width:340px}.auth-brand-logo{width:100px;height:100px;border-radius:50%;background:#ffffff0d;border:1px solid rgba(255,255,255,.1);display:flex;align-items:center;justify-content:center;margin:0 auto 28px;box-shadow:0 0 0 14px #398bf70f,0 0 50px #398bf733;backdrop-filter:blur(8px)}.auth-brand-logo img{width:64px;height:64px;object-fit:contain;filter:brightness(1.05) drop-shadow(0 0 8px rgba(57,139,247,.4))}.auth-brand-title{font-size:30px;font-weight:700;letter-spacing:-.5px;margin-bottom:10px;background:linear-gradient(135deg,#fff 20%,#93c5fd 80%);-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text}.auth-brand-subtitle{font-size:14px;color:#ffffff73;line-height:1.65;margin-bottom:40px;letter-spacing:.2px}.auth-brand-features{display:flex;flex-direction:column;gap:14px;text-align:left}.auth-brand-feature{display:flex;align-items:center;gap:12px;font-size:13px;color:#fff9}.auth-brand-feature .feat-dot{flex-shrink:0;width:7px;height:7px;border-radius:50%;background:#398bf7;box-shadow:0 0 10px #398bf7b3}.auth-brand-divider{width:60px;height:2px;background:linear-gradient(90deg,transparent,#398bf7,transparent);margin:28px auto 32px;border-radius:2px}.auth-panel-left--dev{background:linear-gradient(145deg,#18040b,#3d0b1d 55%,#220409)}.auth-panel-left--dev:after{background:linear-gradient(90deg,transparent,rgba(209,50,111,.05),transparent)}.auth-panel-left--dev .auth-blob-1{background:radial-gradient(circle,rgba(220,38,38,.52) 0%,transparent 70%)}.auth-panel-left--dev .auth-blob-2{background:radial-gradient(circle,rgba(219,39,119,.44) 0%,transparent 70%)}.auth-panel-left--dev .auth-blob-3{background:radial-gradient(circle,rgba(239,68,68,.38) 0%,transparent 70%)}.auth-panel-left--dev .auth-blob-4{background:radial-gradient(circle,rgba(249,115,22,.28) 0%,transparent 70%)}.auth-panel-left--dev .auth-brand-logo{box-shadow:0 0 0 14px #d1326f12,0 0 50px #d1326f38}.auth-panel-left--dev .auth-brand-logo img{filter:brightness(1.05) drop-shadow(0 0 8px rgba(209,50,111,.45))}.auth-panel-left--dev .auth-brand-title{background:linear-gradient(135deg,#fff 20%,#fca5a5 80%);-webkit-background-clip:text;background-clip:text}.auth-panel-left--dev .auth-brand-divider{background:linear-gradient(90deg,transparent,rgb(209,50,111),transparent)}.auth-panel-left--dev .feat-dot{background:#d1326f;box-shadow:0 0 10px #d1326fb8}.auth-panel-right{position:relative;overflow:hidden;background:var(--background-login)}.auth-panel-right:before{content:\"\";position:absolute;inset:0;background-image:repeating-linear-gradient(-55deg,transparent 0px,transparent 22px,rgba(57,139,247,.045) 22px,rgba(57,139,247,.045) 23px);animation:authLinesMove 10s linear infinite;pointer-events:none;z-index:0}.auth-panel-right:after{content:\"\";position:absolute;top:0;bottom:0;left:-25%;width:25%;background:linear-gradient(90deg,transparent 0%,rgba(57,139,247,.02) 30%,rgba(57,139,247,.045) 50%,rgba(57,139,247,.02) 70%,transparent 100%);animation:authScanLine 7s ease-in-out infinite;animation-delay:3.5s;pointer-events:none;z-index:0}@keyframes authLinesMove{0%{transform:translate(0)}to{transform:translate(46px,46px)}}@keyframes authScanLine{0%{left:-25%}50%{left:120%}to{left:120%}}.auth-panel-bg{position:absolute;inset:0;pointer-events:none;z-index:0;overflow:hidden}.auth-deco{position:absolute;border-radius:50%;pointer-events:none;filter:blur(70px)}.auth-deco-tl{width:300px;height:300px;top:0;left:-120px;transform:translateY(-40%);background:radial-gradient(circle,rgba(57,139,247,.12) 0%,transparent 70%);animation:authOrbPulse 6s ease-in-out infinite}.auth-deco-br{width:340px;height:340px;bottom:0;right:-120px;transform:translateY(40%);background:radial-gradient(circle,rgba(124,58,237,.1) 0%,transparent 70%);animation:authOrbPulse 8s ease-in-out infinite;animation-delay:-4s}@keyframes authOrbPulse{0%,to{opacity:.7}50%{opacity:1}}.auth-form-wrapper{position:absolute;inset:0;overflow-y:auto;overflow-x:hidden;display:flex;flex-direction:column;align-items:center;z-index:1}.auth-form-wrapper>div{width:100%;max-width:420px;margin:auto;padding:36px 16px;box-sizing:border-box}.auth-panel-right--dev:before{background-image:repeating-linear-gradient(-55deg,transparent 0px,transparent 22px,rgba(209,50,111,.05) 22px,rgba(209,50,111,.05) 23px)}.auth-panel-right--dev:after{background:linear-gradient(90deg,transparent 0%,rgba(209,50,111,.02) 30%,rgba(209,50,111,.045) 50%,rgba(209,50,111,.02) 70%,transparent 100%)}.auth-panel-right--dev .auth-deco-tl{background:radial-gradient(circle,rgba(209,50,111,.12) 0%,transparent 70%)}.auth-panel-right--dev .auth-deco-br{background:radial-gradient(circle,rgba(239,68,68,.1) 0%,transparent 70%)}.auth-test-badge{display:inline-flex;align-items:center;gap:7px;background:#d1326f14;border:1px solid rgba(209,50,111,.25);color:#d1326f;font-size:10.5px;font-weight:700;padding:5px 12px;border-radius:20px;margin-bottom:18px;letter-spacing:.8px}.auth-test-badge .badge-dot{width:6px;height:6px;border-radius:50%;background:#d1326f;animation:badgePulse 1.6s ease-in-out infinite;flex-shrink:0}@keyframes badgePulse{0%,to{opacity:1;transform:scale(1)}50%{opacity:.45;transform:scale(.75)}}.auth-card{background:var(--background-card);border-radius:20px;padding:36px 32px 28px;box-shadow:0 4px 28px #00000014;border:1px solid var(--border-color-modal)}.auth-card-title{font-size:22px;font-weight:700;color:var(--text-color);margin-bottom:4px;letter-spacing:-.3px}.auth-card-subtitle{font-size:13px;color:var(--placeholder-color);margin-bottom:26px}.auth-field{position:relative;margin-bottom:1rem}.auth-field .auth-field-icon{position:absolute;left:13px;top:50%;transform:translateY(-50%);color:var(--placeholder-color);font-size:13px;z-index:2;pointer-events:none;transition:color .2s}.auth-field .auth-input{width:100%;padding:15px 40px 15px 37px;background:var(--background-input);border:1.5px solid var(--font-border-input);border-radius:10px;font-size:14px;color:var(--color-input);outline:none;transition:border-color .2s,box-shadow .2s,background .2s}.auth-field .auth-input::placeholder{color:transparent}.auth-field .auth-input:focus{border-color:#398bf7;box-shadow:0 0 0 3.5px #398bf721;background:var(--background-focus-input)}.auth-field .auth-input:focus~.auth-label{top:0;font-size:11px!important;color:#398bf7!important;background:var(--background-card);padding:0 4px;transform:translateY(-50%)}.auth-field .auth-input:focus~.auth-field-icon{color:#398bf7}.auth-field .auth-input:not(:placeholder-shown)~.auth-label{top:0;font-size:11px!important;background:var(--background-card);padding:0 4px;transform:translateY(-50%)}.auth-field .auth-label{position:absolute;left:35px;top:50%;transform:translateY(-50%);color:var(--placeholder-color)!important;font-size:13px!important;font-weight:400!important;pointer-events:none;transition:top .15s ease,font-size .15s ease,color .15s ease,padding .15s ease,background .15s ease;background:transparent;z-index:1;text-align:left!important}.auth-field .auth-toggle-pw{position:absolute;right:10px;top:50%;transform:translateY(-50%);background:none;border:none;color:var(--placeholder-color);cursor:pointer;padding:4px 6px;font-size:13px;z-index:2;line-height:1;transition:color .2s}.auth-field .auth-toggle-pw:hover{color:#398bf7}.auth-field.has-error .auth-input{border-color:#dc3545;box-shadow:none}.auth-field.has-error .auth-field-icon{color:#dc3545}.auth-select{width:100%;padding:13px 14px;background:var(--background-input);border:1.5px solid var(--font-border-input);border-radius:10px;font-size:14px;color:var(--color-input);outline:none;transition:border-color .2s,box-shadow .2s;margin-bottom:1rem;cursor:pointer}.auth-select:focus{border-color:#398bf7;box-shadow:0 0 0 3.5px #398bf721}.auth-btn{width:100%;padding:13px;border:none;border-radius:10px;font-size:14px;font-weight:600;cursor:pointer;transition:transform .15s ease,box-shadow .2s ease,opacity .2s;background:linear-gradient(135deg,#398bf7,#1e5fc4);color:#fff;letter-spacing:.3px;margin-bottom:10px;display:block}.auth-btn:hover:not(:disabled){transform:translateY(-1px);box-shadow:0 5px 18px #398bf761}.auth-btn:active:not(:disabled){transform:translateY(0)}.auth-btn:disabled{opacity:.55;cursor:not-allowed}.auth-btn.auth-btn--red{background:linear-gradient(135deg,#d1326f,#a82859)}.auth-btn.auth-btn--red:hover:not(:disabled){box-shadow:0 5px 18px #d1326f61}.auth-btn.auth-btn--outline{background:transparent;border:1.5px solid var(--font-border-input);color:var(--text-color)}.auth-btn.auth-btn--outline:hover:not(:disabled){background:var(--background-btn-light-hover);box-shadow:none;transform:none}.auth-links{display:flex;flex-direction:column;align-items:center;gap:10px;margin-top:16px;padding-top:16px;border-top:1px solid var(--border-color-modal)}.auth-version{text-align:right;margin-top:14px;padding-top:12px;border-top:1px solid var(--border-color-modal)}.auth-version span{font-size:11px;color:var(--placeholder-color)}.auth-error{font-size:11.5px;color:#dc3545;margin:-6px 0 10px 2px;padding:0}.auth-hint{display:flex;align-items:flex-start;gap:6px;font-size:11.5px;color:var(--placeholder-color);margin:-6px 0 14px 2px;padding:0;line-height:1.35}.auth-hint i{margin-top:2px;flex-shrink:0}.auth-validation-list{margin:-4px 0 12px;padding:0;list-style:none}.auth-validation-list li{font-size:11.5px;color:#dc3545;padding:2px 0}.auth-validation-list li:before{content:\"\\2715 \";font-size:10px}.auth-desc{font-size:13px;color:var(--placeholder-color);margin-bottom:20px;line-height:1.65}.auth-section-title{font-size:15px;font-weight:600;color:var(--text-color);margin-bottom:20px}.font-12{font-size:12px}.form-control:focus{border-color:#0199ff9a!important;box-shadow:0 0 5px .2px #65befa44!important}@media(max-width:900px){.auth-wrapper-login{grid-template-columns:1fr;grid-template-rows:auto 1fr;overflow-y:auto;overflow-x:hidden}.auth-panel-left{padding:14px 24px;justify-content:center}.auth-panel-left .auth-brand-subtitle,.auth-panel-left .auth-brand-features,.auth-panel-left .auth-brand-divider{display:none!important}.auth-panel-left .auth-brand-panel{display:flex!important;flex-direction:row!important;align-items:center;gap:0;text-align:left;max-width:none;width:100%;justify-content:center}.auth-panel-left .auth-brand-logo{width:52px;height:52px;margin:0;flex-shrink:0}.auth-panel-left .auth-brand-logo img{width:34px;height:34px}.auth-panel-left .auth-brand-title{font-size:20px;margin-bottom:0;margin-left:.5rem;flex-shrink:1}.auth-panel-right:after{inset:-25% 0 auto;width:100%;height:25%;background:linear-gradient(180deg,transparent 0%,rgba(57,139,247,.02) 30%,rgba(57,139,247,.045) 50%,rgba(57,139,247,.02) 70%,transparent 100%);animation:authScanLineV 7s ease-in-out infinite;animation-delay:3.5s}.auth-panel-right--dev:after{background:linear-gradient(180deg,transparent 0%,rgba(209,50,111,.02) 30%,rgba(209,50,111,.045) 50%,rgba(209,50,111,.02) 70%,transparent 100%)}}@keyframes authScanLineV{0%{top:-25%}50%{top:120%}to{top:120%}}@media(max-width:480px){.auth-panel-left{padding:12px 16px}.auth-panel-left .auth-brand-logo{width:44px;height:44px}.auth-panel-left .auth-brand-logo img{width:28px;height:28px}.auth-panel-left .auth-brand-title{font-size:17px}.auth-form-wrapper>div{padding:20px 12px}.auth-card{padding:24px 18px 20px;border-radius:16px}.font-12{font-size:10px!important}}\n"] }]
|
|
323
|
+
args: [{ selector: 'lib-md-verificar-mfa', template: "<div class=\"verificar-mfa\">\n <div class=\"auth-card-title mb-3\">{{ titulo() }}</div>\n\n <div class=\"d-flex align-items-center gap-3 mb-3\">\n <span class=\"verificar-mfa__icono\"><i class=\"fas fa-user-shield\"></i></span>\n <div>\n <div class=\"fw-semibold\">{{ challenge().coduser }}</div>\n @if (challenge().empresa) {\n <div class=\"verificar-mfa__muted\">{{ challenge().empresa }}</div>\n }\n </div>\n </div>\n\n @if (modo() == 'push') {\n @switch (estadoPush()) {\n @case ('enviando') {\n <div class=\"duo-push\">\n <span class=\"spinner-border spinner-border-sm text-primary\"></span>\n <div class=\"flex-grow-1\">Enviando notificaci\u00F3n a tu tel\u00E9fono\u2026</div>\n </div>\n }\n @case ('esperando') {\n <div class=\"duo-push duo-push--esperando\">\n <span class=\"duo-push__icono duo-push__icono--pulso\"><i class=\"fas fa-mobile-alt\"></i></span>\n <div class=\"flex-grow-1\">\n <div class=\"fw-semibold\">Revisa tu tel\u00E9fono</div>\n <div class=\"verificar-mfa__muted\">Aprueba la notificaci\u00F3n en TSI Autenticador para ingresar.</div>\n </div>\n </div>\n @if (numberMatching() != null) {\n <div class=\"number-matching\" role=\"status\" aria-live=\"polite\">\n <div class=\"verificar-mfa__muted\">Confirma que tu tel\u00E9fono muestre este n\u00FAmero</div>\n <div class=\"number-matching__valor\">{{ numberMatching() }}</div>\n </div>\n }\n }\n @default {\n <div class=\"duo-push\">\n <span class=\"duo-push__icono\"><i class=\"fas fa-bell\"></i></span>\n <div class=\"flex-grow-1\">\n <div class=\"fw-semibold\">TSI Autenticador</div>\n <div class=\"verificar-mfa__muted\">Te enviaremos una notificaci\u00F3n para que la apruebes.</div>\n </div>\n </div>\n }\n }\n @if (pushError() && !isPushEnCurso()) {\n <div class=\"codigo-field__error\"><i class=\"fas fa-exclamation-circle\"></i> {{ pushError() }}</div>\n }\n\n <div class=\"verificar-mfa__opciones\">\n @if (tieneTotp()) {\n <button type=\"button\" class=\"verificar-mfa__link\" (click)=\"usarCodigo('totp')\">\n Usar c\u00F3digo de mi app de autenticaci\u00F3n\n </button>\n }\n <button type=\"button\" class=\"verificar-mfa__link verificar-mfa__link--secundario\"\n (click)=\"usarCodigo('respaldo')\">\n \u00BFNo tienes tu tel\u00E9fono? Usa un c\u00F3digo de respaldo\n </button>\n </div>\n } @else {\n <p class=\"verificar-mfa__muted mb-4\">\n @if (tipoCodigo() == 'totp') {\n {{ challenge().mensaje || campo().descri }}\n } @else {\n {{ campo().descri }}\n }\n </p>\n\n <div class=\"codigo-field\" [class.has-error]=\"codigoError()\">\n <span class=\"codigo-field__icon\"><i class=\"fas\" [class]=\"campo().icon\"></i></span>\n <input #inputCodigo id=\"mfa-codigo\" class=\"codigo-field__input\" type=\"text\"\n [placeholder]=\"campo().placeholder\" [value]=\"codigo()\" (input)=\"onCodigoInput($event)\"\n (keydown.enter)=\"verificar()\" [attr.inputmode]=\"campo().inputmode\" autocomplete=\"one-time-code\"\n autocorrect=\"off\" autocapitalize=\"characters\" spellcheck=\"false\" [disabled]=\"isEnviando()\">\n <label for=\"mfa-codigo\" class=\"codigo-field__label\">{{ campo().label }}</label>\n </div>\n @if (codigoError()) {\n <div class=\"codigo-field__error\"><i class=\"fas fa-exclamation-circle\"></i> {{ codigoError() }}</div>\n }\n\n <div class=\"verificar-mfa__opciones\">\n @if (tienePush()) {\n <button type=\"button\" class=\"verificar-mfa__link\" (click)=\"usarPush()\">\n <i class=\"fas fa-bell me-1\"></i>Mejor env\u00EDame una notificaci\u00F3n push\n </button>\n }\n @if (tieneTotp() && tipoCodigo() != 'totp') {\n <button type=\"button\" class=\"verificar-mfa__link\" (click)=\"usarCodigo('totp')\">\n Usar c\u00F3digo de mi app de autenticaci\u00F3n\n </button>\n }\n @if (tipoCodigo() != 'respaldo') {\n <button type=\"button\" class=\"verificar-mfa__link verificar-mfa__link--secundario\"\n (click)=\"usarCodigo('respaldo')\">\n \u00BFNo tienes tu tel\u00E9fono? Usa un c\u00F3digo de respaldo\n </button>\n }\n </div>\n }\n\n <div class=\"verificar-mfa__acciones\">\n @if (modo() == 'push') {\n <button type=\"button\" class=\"auth-btn\" [disabled]=\"isPushEnCurso()\" (click)=\"enviarPush()\">\n <i class=\"fas fa-paper-plane me-1\"></i>\n {{ isPushEnCurso() ? 'Esperando aprobaci\u00F3n\u2026' : 'Reenviar notificaci\u00F3n' }}\n </button>\n } @else {\n <button type=\"button\" class=\"auth-btn\" [disabled]=\"isEnviando()\" (click)=\"verificar()\">\n <i class=\"fas fa-check me-1\"></i>\n {{ isEnviando() ? 'Verificando\u2026' : 'Verificar' }}\n </button>\n }\n @if (showCancelar()) {\n <button type=\"button\" class=\"auth-btn auth-btn--outline\" (click)=\"cancelar()\">Cancelar</button>\n }\n </div>\n</div>\n", styles: [".verificar-mfa{color:var(--text-color)}.verificar-mfa__icono{display:inline-flex;flex-shrink:0;align-items:center;justify-content:center;width:44px;height:44px;border-radius:12px;color:var(--bs-primary);background:rgba(var(--bs-primary-rgb),.1);font-size:20px}.verificar-mfa__muted{font-size:13px;line-height:1.5;color:var(--bs-secondary-color)}.verificar-mfa__link:hover{text-decoration:underline}.verificar-mfa__link{padding:0;border:0;background:none;font-size:13px;font-weight:600;color:var(--bs-primary)}.codigo-field{position:relative}.codigo-field__icon{position:absolute;left:14px;top:50%;transform:translateY(-50%);z-index:2;font-size:15px;color:var(--placeholder-color);pointer-events:none;transition:color .2s}.codigo-field__input{width:100%;height:56px;padding:0 44px;border:1.5px solid var(--font-border-input);border-radius:10px;outline:none;background:var(--background-input);color:var(--color-input);font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:22px;font-weight:600;letter-spacing:.45em;text-align:center;transition:border-color .2s,box-shadow .2s,background .2s}.codigo-field__input::placeholder{color:var(--placeholder-color);opacity:.45}.codigo-field__input:focus{border-color:var(--bs-primary);box-shadow:0 0 0 3.5px rgba(var(--bs-primary-rgb),.15);background:var(--background-focus-input)}.codigo-field__input:disabled{opacity:.7}.codigo-field__label{position:absolute;left:12px;top:0;transform:translateY(-50%);z-index:1;margin:0!important;padding:0 4px;font-size:11px!important;font-weight:500!important;line-height:1.2;color:var(--placeholder-color);background:var(--background-card);pointer-events:none;transition:color .15s ease}.codigo-field:focus-within .codigo-field__label,.codigo-field:focus-within .codigo-field__icon{color:var(--bs-primary)}.codigo-field.has-error .codigo-field__input{border-color:var(--bs-danger);box-shadow:0 0 0 3.5px rgba(var(--bs-danger-rgb),.12)}.codigo-field.has-error .codigo-field__icon,.codigo-field.has-error .codigo-field__label{color:var(--bs-danger)}.codigo-field__error{display:flex;align-items:center;gap:6px;margin-top:8px;font-size:13px;font-weight:500;color:var(--bs-danger)}.duo-push{display:flex;align-items:center;gap:12px;padding:14px;border:1.5px solid var(--font-border-input);border-radius:10px;background:var(--background-input);color:var(--text-color);font-size:14px}.duo-push--esperando{border-color:rgba(var(--bs-primary-rgb),.45);background:rgba(var(--bs-primary-rgb),.06)}.duo-push__icono{display:inline-flex;flex-shrink:0;align-items:center;justify-content:center;width:40px;height:40px;border-radius:50%;color:var(--bs-primary);background:rgba(var(--bs-primary-rgb),.1);font-size:18px}.duo-push__icono--pulso{animation:duo-pulso 1.4s ease-in-out infinite}.number-matching{margin-top:12px;padding:16px;border:1.5px dashed rgba(var(--bs-primary-rgb),.45);border-radius:10px;text-align:center}.number-matching__valor{margin-top:4px;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:40px;font-weight:700;line-height:1.1;letter-spacing:.12em;color:var(--bs-primary)}@keyframes duo-pulso{0%,to{box-shadow:0 0 rgba(var(--bs-primary-rgb),.35)}50%{box-shadow:0 0 0 8px rgba(var(--bs-primary-rgb),0)}}@media(prefers-reduced-motion:reduce){.duo-push__icono--pulso{animation:none}}.verificar-mfa__opciones{display:flex;flex-direction:column;align-items:flex-start;gap:8px;margin-top:16px}.verificar-mfa__link--secundario{font-weight:500;color:var(--bs-secondary-color)}.verificar-mfa__acciones{margin-top:24px}\n", "@charset \"UTF-8\";.red_contrasena,.blue_contrasena{position:relative;display:inline-block;font-size:13px;text-decoration:none;padding-bottom:2px;transition:color .3s ease;cursor:pointer}.red_contrasena:after,.blue_contrasena:after{content:\"\";position:absolute;bottom:0;left:50%;width:0;height:1px;background-color:currentColor;transition:all .3s ease;transform:translate(-50%)}.red_contrasena:hover:after,.blue_contrasena:hover:after{width:60%}.red_contrasena{color:#d1326f}.red_contrasena:hover{color:#a82859}.blue_contrasena{color:#398bf7}.blue_contrasena:hover{color:#1e5fc4}.auth-wrapper-login{position:fixed;inset:0;display:grid;grid-template-columns:1.15fr .85fr;overflow:hidden;background:#060d1f}.auth-panel-left{position:relative;overflow:hidden;background:linear-gradient(145deg,#040a18,#0b1a3d 55%,#040e22);display:flex;align-items:center;justify-content:center;padding:48px 40px}.auth-panel-left:before{content:\"\";position:absolute;inset:0;background-image:radial-gradient(circle,rgba(255,255,255,.055) 1px,transparent 1px);background-size:26px 26px;z-index:1;pointer-events:none}.auth-panel-left:after{content:\"\";position:absolute;top:0;left:-120%;width:60%;height:100%;background:linear-gradient(90deg,transparent,rgba(57,139,247,.04),transparent);animation:panelSweep 7s ease-in-out infinite;z-index:1;pointer-events:none}.auth-blob{position:absolute;border-radius:50%;filter:blur(72px);z-index:0;pointer-events:none}.auth-blob-1{width:340px;height:340px;background:radial-gradient(circle,rgba(57,139,247,.45) 0%,transparent 70%);top:-90px;right:-70px;animation:blobDrift 11s ease-in-out infinite}.auth-blob-2{width:240px;height:240px;background:radial-gradient(circle,rgba(124,58,237,.4) 0%,transparent 70%);bottom:60px;left:-50px;animation:blobDrift 14s ease-in-out infinite reverse}.auth-blob-3{width:180px;height:180px;background:radial-gradient(circle,rgba(14,165,233,.35) 0%,transparent 70%);bottom:-50px;right:40px;animation:blobDrift 9s ease-in-out infinite;animation-delay:-4s}.auth-blob-4{width:120px;height:120px;background:radial-gradient(circle,rgba(209,50,111,.25) 0%,transparent 70%);top:50%;left:50%;transform:translate(-50%,-50%);animation:blobDrift 16s ease-in-out infinite;animation-delay:-8s}@keyframes blobDrift{0%,to{transform:translate(0) scale(1)}33%{transform:translate(14px,-20px) scale(1.05)}66%{transform:translate(-10px,12px) scale(.96)}}@keyframes panelSweep{0%{left:-120%}50%{left:160%}to{left:160%}}.auth-brand-panel{position:relative;z-index:2;text-align:center;color:#fff;max-width:340px}.auth-brand-logo{width:100px;height:100px;border-radius:50%;background:#ffffff0d;border:1px solid rgba(255,255,255,.1);display:flex;align-items:center;justify-content:center;margin:0 auto 28px;box-shadow:0 0 0 14px #398bf70f,0 0 50px #398bf733;backdrop-filter:blur(8px)}.auth-brand-logo img{width:64px;height:64px;object-fit:contain;filter:brightness(1.05) drop-shadow(0 0 8px rgba(57,139,247,.4))}.auth-brand-title{font-size:30px;font-weight:700;letter-spacing:-.5px;margin-bottom:10px;background:linear-gradient(135deg,#fff 20%,#93c5fd 80%);-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text}.auth-brand-subtitle{font-size:14px;color:#ffffff73;line-height:1.65;margin-bottom:40px;letter-spacing:.2px}.auth-brand-features{display:flex;flex-direction:column;gap:14px;text-align:left}.auth-brand-feature{display:flex;align-items:center;gap:12px;font-size:13px;color:#fff9}.auth-brand-feature .feat-dot{flex-shrink:0;width:7px;height:7px;border-radius:50%;background:#398bf7;box-shadow:0 0 10px #398bf7b3}.auth-brand-divider{width:60px;height:2px;background:linear-gradient(90deg,transparent,#398bf7,transparent);margin:28px auto 32px;border-radius:2px}.auth-panel-left--dev{background:linear-gradient(145deg,#18040b,#3d0b1d 55%,#220409)}.auth-panel-left--dev:after{background:linear-gradient(90deg,transparent,rgba(209,50,111,.05),transparent)}.auth-panel-left--dev .auth-blob-1{background:radial-gradient(circle,rgba(220,38,38,.52) 0%,transparent 70%)}.auth-panel-left--dev .auth-blob-2{background:radial-gradient(circle,rgba(219,39,119,.44) 0%,transparent 70%)}.auth-panel-left--dev .auth-blob-3{background:radial-gradient(circle,rgba(239,68,68,.38) 0%,transparent 70%)}.auth-panel-left--dev .auth-blob-4{background:radial-gradient(circle,rgba(249,115,22,.28) 0%,transparent 70%)}.auth-panel-left--dev .auth-brand-logo{box-shadow:0 0 0 14px #d1326f12,0 0 50px #d1326f38}.auth-panel-left--dev .auth-brand-logo img{filter:brightness(1.05) drop-shadow(0 0 8px rgba(209,50,111,.45))}.auth-panel-left--dev .auth-brand-title{background:linear-gradient(135deg,#fff 20%,#fca5a5 80%);-webkit-background-clip:text;background-clip:text}.auth-panel-left--dev .auth-brand-divider{background:linear-gradient(90deg,transparent,rgb(209,50,111),transparent)}.auth-panel-left--dev .feat-dot{background:#d1326f;box-shadow:0 0 10px #d1326fb8}.auth-panel-right{position:relative;overflow:hidden;background:var(--background-login)}.auth-panel-right:before{content:\"\";position:absolute;inset:0;background-image:repeating-linear-gradient(-55deg,transparent 0px,transparent 22px,rgba(57,139,247,.045) 22px,rgba(57,139,247,.045) 23px);animation:authLinesMove 10s linear infinite;pointer-events:none;z-index:0}.auth-panel-right:after{content:\"\";position:absolute;top:0;bottom:0;left:-25%;width:25%;background:linear-gradient(90deg,transparent 0%,rgba(57,139,247,.02) 30%,rgba(57,139,247,.045) 50%,rgba(57,139,247,.02) 70%,transparent 100%);animation:authScanLine 7s ease-in-out infinite;animation-delay:3.5s;pointer-events:none;z-index:0}@keyframes authLinesMove{0%{transform:translate(0)}to{transform:translate(46px,46px)}}@keyframes authScanLine{0%{left:-25%}50%{left:120%}to{left:120%}}.auth-panel-bg{position:absolute;inset:0;pointer-events:none;z-index:0;overflow:hidden}.auth-deco{position:absolute;border-radius:50%;pointer-events:none;filter:blur(70px)}.auth-deco-tl{width:300px;height:300px;top:0;left:-120px;transform:translateY(-40%);background:radial-gradient(circle,rgba(57,139,247,.12) 0%,transparent 70%);animation:authOrbPulse 6s ease-in-out infinite}.auth-deco-br{width:340px;height:340px;bottom:0;right:-120px;transform:translateY(40%);background:radial-gradient(circle,rgba(124,58,237,.1) 0%,transparent 70%);animation:authOrbPulse 8s ease-in-out infinite;animation-delay:-4s}@keyframes authOrbPulse{0%,to{opacity:.7}50%{opacity:1}}.auth-form-wrapper{position:absolute;inset:0;overflow-y:auto;overflow-x:hidden;display:flex;flex-direction:column;align-items:center;z-index:1}.auth-form-wrapper>div{width:100%;max-width:420px;margin:auto;padding:36px 16px;box-sizing:border-box}.auth-panel-right--dev:before{background-image:repeating-linear-gradient(-55deg,transparent 0px,transparent 22px,rgba(209,50,111,.05) 22px,rgba(209,50,111,.05) 23px)}.auth-panel-right--dev:after{background:linear-gradient(90deg,transparent 0%,rgba(209,50,111,.02) 30%,rgba(209,50,111,.045) 50%,rgba(209,50,111,.02) 70%,transparent 100%)}.auth-panel-right--dev .auth-deco-tl{background:radial-gradient(circle,rgba(209,50,111,.12) 0%,transparent 70%)}.auth-panel-right--dev .auth-deco-br{background:radial-gradient(circle,rgba(239,68,68,.1) 0%,transparent 70%)}.auth-test-badge{display:inline-flex;align-items:center;gap:7px;background:#d1326f14;border:1px solid rgba(209,50,111,.25);color:#d1326f;font-size:10.5px;font-weight:700;padding:5px 12px;border-radius:20px;margin-bottom:18px;letter-spacing:.8px}.auth-test-badge .badge-dot{width:6px;height:6px;border-radius:50%;background:#d1326f;animation:badgePulse 1.6s ease-in-out infinite;flex-shrink:0}@keyframes badgePulse{0%,to{opacity:1;transform:scale(1)}50%{opacity:.45;transform:scale(.75)}}.auth-card{background:var(--background-card);border-radius:20px;padding:36px 32px 28px;box-shadow:0 4px 28px #00000014;border:1px solid var(--border-color-modal)}.auth-card-title{font-size:22px;font-weight:700;color:var(--text-color);margin-bottom:4px;letter-spacing:-.3px}.auth-card-subtitle{font-size:13px;color:var(--placeholder-color);margin-bottom:26px}.auth-field{position:relative;margin-bottom:1rem}.auth-field .auth-field-icon{position:absolute;left:13px;top:50%;transform:translateY(-50%);color:var(--placeholder-color);font-size:13px;z-index:2;pointer-events:none;transition:color .2s}.auth-field .auth-input{width:100%;padding:15px 40px 15px 37px;background:var(--background-input);border:1.5px solid var(--font-border-input);border-radius:10px;font-size:14px;color:var(--color-input);outline:none;transition:border-color .2s,box-shadow .2s,background .2s}.auth-field .auth-input::placeholder{color:transparent}.auth-field .auth-input:focus{border-color:#398bf7;box-shadow:0 0 0 3.5px #398bf721;background:var(--background-focus-input)}.auth-field .auth-input:focus~.auth-label{top:0;font-size:11px!important;color:#398bf7!important;background:var(--background-card);padding:0 4px;transform:translateY(-50%)}.auth-field .auth-input:focus~.auth-field-icon{color:#398bf7}.auth-field .auth-input:not(:placeholder-shown)~.auth-label{top:0;font-size:11px!important;background:var(--background-card);padding:0 4px;transform:translateY(-50%)}.auth-field .auth-label{position:absolute;left:35px;top:50%;transform:translateY(-50%);color:var(--placeholder-color)!important;font-size:13px!important;font-weight:400!important;pointer-events:none;transition:top .15s ease,font-size .15s ease,color .15s ease,padding .15s ease,background .15s ease;background:transparent;z-index:1;text-align:left!important}.auth-field .auth-toggle-pw{position:absolute;right:10px;top:50%;transform:translateY(-50%);background:none;border:none;color:var(--placeholder-color);cursor:pointer;padding:4px 6px;font-size:13px;z-index:2;line-height:1;transition:color .2s}.auth-field .auth-toggle-pw:hover{color:#398bf7}.auth-field.has-error .auth-input{border-color:#dc3545;box-shadow:none}.auth-field.has-error .auth-field-icon{color:#dc3545}.auth-select{width:100%;padding:13px 14px;background:var(--background-input);border:1.5px solid var(--font-border-input);border-radius:10px;font-size:14px;color:var(--color-input);outline:none;transition:border-color .2s,box-shadow .2s;margin-bottom:1rem;cursor:pointer}.auth-select:focus{border-color:#398bf7;box-shadow:0 0 0 3.5px #398bf721}.auth-btn{width:100%;padding:13px;border:none;border-radius:10px;font-size:14px;font-weight:600;cursor:pointer;transition:transform .15s ease,box-shadow .2s ease,opacity .2s;background:linear-gradient(135deg,#398bf7,#1e5fc4);color:#fff;letter-spacing:.3px;margin-bottom:10px;display:block}.auth-btn:hover:not(:disabled){transform:translateY(-1px);box-shadow:0 5px 18px #398bf761}.auth-btn:active:not(:disabled){transform:translateY(0)}.auth-btn:disabled{opacity:.55;cursor:not-allowed}.auth-btn.auth-btn--red{background:linear-gradient(135deg,#d1326f,#a82859)}.auth-btn.auth-btn--red:hover:not(:disabled){box-shadow:0 5px 18px #d1326f61}.auth-btn.auth-btn--outline{background:transparent;border:1.5px solid var(--font-border-input);color:var(--text-color)}.auth-btn.auth-btn--outline:hover:not(:disabled){background:var(--background-btn-light-hover);box-shadow:none;transform:none}.auth-links{display:flex;flex-direction:column;align-items:center;gap:10px;margin-top:16px;padding-top:16px;border-top:1px solid var(--border-color-modal)}.auth-version{text-align:right;margin-top:14px;padding-top:12px;border-top:1px solid var(--border-color-modal)}.auth-version span{font-size:11px;color:var(--placeholder-color)}.auth-error{font-size:11.5px;color:#dc3545;margin:-6px 0 10px 2px;padding:0}.auth-hint{display:flex;align-items:flex-start;gap:6px;font-size:11.5px;color:var(--placeholder-color);margin:-6px 0 14px 2px;padding:0;line-height:1.35}.auth-hint i{margin-top:2px;flex-shrink:0}.auth-validation-list{margin:-4px 0 12px;padding:0;list-style:none}.auth-validation-list li{font-size:11.5px;color:#dc3545;padding:2px 0}.auth-validation-list li:before{content:\"\\2715 \";font-size:10px}.auth-desc{font-size:13px;color:var(--placeholder-color);margin-bottom:20px;line-height:1.65}.auth-section-title{font-size:15px;font-weight:600;color:var(--text-color);margin-bottom:20px}.font-12{font-size:12px}.form-control:focus{border-color:#0199ff9a!important;box-shadow:0 0 5px .2px #65befa44!important}@media(max-width:900px){.auth-wrapper-login{grid-template-columns:1fr;grid-template-rows:auto 1fr;overflow-y:auto;overflow-x:hidden}.auth-panel-left{padding:14px 24px;justify-content:center}.auth-panel-left .auth-brand-subtitle,.auth-panel-left .auth-brand-features,.auth-panel-left .auth-brand-divider{display:none!important}.auth-panel-left .auth-brand-panel{display:flex!important;flex-direction:row!important;align-items:center;gap:0;text-align:left;max-width:none;width:100%;justify-content:center}.auth-panel-left .auth-brand-logo{width:52px;height:52px;margin:0;flex-shrink:0}.auth-panel-left .auth-brand-logo img{width:34px;height:34px}.auth-panel-left .auth-brand-title{font-size:20px;margin-bottom:0;margin-left:.5rem;flex-shrink:1}.auth-panel-right:after{inset:-25% 0 auto;width:100%;height:25%;background:linear-gradient(180deg,transparent 0%,rgba(57,139,247,.02) 30%,rgba(57,139,247,.045) 50%,rgba(57,139,247,.02) 70%,transparent 100%);animation:authScanLineV 7s ease-in-out infinite;animation-delay:3.5s}.auth-panel-right--dev:after{background:linear-gradient(180deg,transparent 0%,rgba(209,50,111,.02) 30%,rgba(209,50,111,.045) 50%,rgba(209,50,111,.02) 70%,transparent 100%)}}@keyframes authScanLineV{0%{top:-25%}50%{top:120%}to{top:120%}}@media(max-width:480px){.auth-panel-left{padding:12px 16px}.auth-panel-left .auth-brand-logo{width:44px;height:44px}.auth-panel-left .auth-brand-logo img{width:28px;height:28px}.auth-panel-left .auth-brand-title{font-size:17px}.auth-form-wrapper>div{padding:20px 12px}.auth-card{padding:24px 18px 20px;border-radius:16px}.font-12{font-size:10px!important}}\n"] }]
|
|
318
324
|
}], ctorParameters: () => [] });
|
|
319
325
|
|
|
320
326
|
const MENSAJE_ERROR_LOGIN = 'No se pudo iniciar sesión.';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"login-tsi.mjs","sources":["../../../projects/login-tsi/src/lib/utils/animations.ts","../../../projects/login-tsi/src/lib/models/auth-api.ts","../../../projects/login-tsi/src/lib/utils/mensaje-error.ts","../../../projects/login-tsi/src/lib/models/verificar-mfa.ts","../../../projects/login-tsi/src/lib/pwa-install.service.ts","../../../projects/login-tsi/src/lib/components/pwa-floating/pwa-floating.component.ts","../../../projects/login-tsi/src/lib/components/pwa-floating/pwa-floating.component.html","../../../projects/login-tsi/src/lib/components/refresh-floating/refresh-floating.component.ts","../../../projects/login-tsi/src/lib/components/refresh-floating/refresh-floating.component.html","../../../projects/login-tsi/src/lib/components/md-verificar-mfa/md-verificar-mfa.component.ts","../../../projects/login-tsi/src/lib/components/md-verificar-mfa/md-verificar-mfa.component.html","../../../projects/login-tsi/src/lib/components/auth/auth.component.ts","../../../projects/login-tsi/src/lib/components/auth/auth.component.html","../../../projects/login-tsi/src/lib/components/expired-password/expired-password.component.ts","../../../projects/login-tsi/src/lib/components/expired-password/expired-password.component.html","../../../projects/login-tsi/src/lib/components/recover-password/recover-password.component.ts","../../../projects/login-tsi/src/lib/components/recover-password/recover-password.component.html","../../../projects/login-tsi/src/lib/components/select-branch/select-branch.component.ts","../../../projects/login-tsi/src/lib/components/select-branch/select-branch.component.html","../../../projects/login-tsi/src/lib/models/auth-sender.ts","../../../projects/login-tsi/src/public-api.ts","../../../projects/login-tsi/src/login-tsi.ts"],"sourcesContent":["import { animate, style, transition, trigger } from \"@angular/animations\";\r\n\r\nexport const fadeInOut = trigger('fadeInOut', [\r\n transition(':enter', [\r\n style({ opacity: 0, transform: 'translateY(-5px)' }),\r\n animate('200ms ease-out', style({ opacity: 1, transform: 'translateY(0)' })),\r\n ]),\r\n transition(':leave', [\r\n animate('200ms ease-in', style({ opacity: 0, transform: 'translateY(-5px)' })),\r\n ]),\r\n ])","import { InjectionToken, Provider, Type } from '@angular/core'\nimport { AuthSender } from './auth-sender'\nimport { MfaChallengeResponse, MfaEstadoPush, MfaLoginSender } from './verificar-mfa'\n\nexport interface AuthApi {\n login(sender: AuthSender): Promise<MfaChallengeResponse | void>\n verificarCodigo(sender: MfaLoginSender): Promise<void>\n enviarPush(preauthToken: string): Promise<string>\n estadoPush(sender: MfaLoginSender): Promise<MfaEstadoPush>\n}\n\nexport const AUTH_API = new InjectionToken<AuthApi>('AUTH_API')\n\nexport function provideAuthApi(servicio: Type<AuthApi>): Provider {\n return { provide: AUTH_API, useExisting: servicio }\n}\n","const textoValido = (valor: unknown): valor is string => typeof valor == 'string' && !!valor.trim()\n\nexport const mensajeDe = (err: unknown, defecto: string): string => {\n if (textoValido(err)) return err\n if (err && typeof err == 'object' && 'error' in err) {\n const body = (err as { error: unknown }).error\n if (textoValido(body)) return body\n const mensaje = (body as { message?: unknown })?.message\n return textoValido(mensaje) ? mensaje : defecto\n }\n const mensaje = (err as { message?: unknown })?.message\n return textoValido(mensaje) && !/^\\d+$/.test(mensaje) ? mensaje : defecto\n}\n","export interface MfaChallengeResponse {\n mfaRequerido: boolean\n preauthToken: string\n coduser?: string\n empresa?: string\n mensaje?: string\n tipos?: string[]\n}\n\nexport interface MfaLoginSender {\n preauthToken: string\n codigo?: string\n solicitudId?: string\n}\n\nexport interface MfaPushEstadoPendiente {\n result: 'waiting' | 'deny' | 'expired'\n}\n\nexport type MfaEstadoPush = 'aprobado' | 'waiting' | 'deny' | 'expired'\n\nexport function isMfaChallenge(body: any): body is MfaChallengeResponse {\n return body?.mfaRequerido === true && !!body?.preauthToken\n}\n\nexport function isPushPendiente(body: any): body is MfaPushEstadoPendiente {\n return body?.result === 'waiting' || body?.result === 'deny' || body?.result === 'expired'\n}\n","import { Injectable, signal } from '@angular/core';\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class PwaInstallService {\r\n\r\n readonly isAndroid = /Android/i.test(navigator.userAgent)\r\n readonly isIOS = /iPad|iPhone|iPod/i.test(navigator.userAgent)\r\n readonly isSafariMac = /^((?!Chrome|Android).)*Safari/i.test(navigator.userAgent) && /Mac/i.test(navigator.platform)\r\n readonly isChrome = /Chrome|Chromium|Edg/i.test(navigator.userAgent) && !/Android/i.test(navigator.userAgent)\r\n\r\n readonly showButton = signal<boolean>(\r\n !window.matchMedia('(display-mode: standalone)').matches\r\n )\r\n readonly showGuide = signal<boolean>(false)\r\n\r\n private get deferredPrompt(): any { return (window as any).__pwaPrompt ?? null }\r\n\r\n get canAutoInstall(): boolean { return !!this.deferredPrompt }\r\n\r\n async tryInstall(): Promise<void> {\r\n const prompt = this.deferredPrompt\r\n if (!prompt) return\r\n prompt.prompt()\r\n const { outcome } = await prompt.userChoice\r\n if (outcome === 'accepted') this.showButton.set(false)\r\n else (window as any).__pwaPrompt = null\r\n }\r\n\r\n toggleGuide() { this.showGuide.update(v => !v) }\r\n\r\n markAsAdded() {\r\n this.showGuide.set(false)\r\n this.showButton.set(false)\r\n }\r\n}\r\n","import { Component, inject, input, output } from '@angular/core';\r\nimport { PwaInstallService } from '../../pwa-install.service';\r\n\r\n@Component({\r\n selector: 'app-pwa-floating',\r\n templateUrl: './pwa-floating.component.html',\r\n styleUrl: './pwa-floating.component.scss'\r\n})\r\n\r\nexport class PwaFloatingComponent {\r\n\r\n readonly pwa = inject(PwaInstallService)\r\n\r\n appName = input<string>('ERP TSI')\r\n logo = input<string>('assets/images/logo-tsi-tres.png')\r\n chipLabel = input<string>('Instalar app')\r\n\r\n beforeInstall = output<void>()\r\n guideClosed = output<void>()\r\n\r\n onChipClick() {\r\n if (!this.pwa.showGuide()) {\r\n this.beforeInstall.emit()\r\n } else {\r\n this.guideClosed.emit()\r\n }\r\n this.pwa.toggleGuide()\r\n }\r\n\r\n onCloseGuide() {\r\n this.guideClosed.emit()\r\n this.pwa.toggleGuide()\r\n }\r\n\r\n onMarkAsAdded() {\r\n this.guideClosed.emit()\r\n this.pwa.markAsAdded()\r\n }\r\n\r\n}\r\n","@if (pwa.showButton()) {\r\n<div class=\"pwa-wrap\">\r\n\r\n @if (pwa.showGuide()) {\r\n <div class=\"pwa-guide\">\r\n <button class=\"pwa-guide__close\" (click)=\"onCloseGuide()\">\r\n <i class=\"fas fa-xmark\"></i>\r\n </button>\r\n\r\n <div class=\"pwa-guide__header\">\r\n <img [src]=\"logo()\" alt=\"\" class=\"pwa-guide__logo\">\r\n <div>\r\n <p class=\"pwa-guide__title\">Instalar {{ appName() }}</p>\r\n <p class=\"pwa-guide__sub\">Úsalo como una app desde tu dispositivo</p>\r\n </div>\r\n </div>\r\n\r\n @if (!pwa.canAutoInstall) {\r\n <ol class=\"pwa-guide__steps\">\r\n @if (pwa.isIOS) {\r\n <li>Toca el botón <span class=\"pwa-guide__badge\"><i class=\"fas fa-arrow-up-from-bracket\"></i></span> en la barra inferior del navegador</li>\r\n <li>Desplázate y selecciona <strong>\"En la pantalla de inicio\"</strong></li>\r\n <li>Toca <strong>\"Añadir\"</strong> en la esquina superior derecha</li>\r\n } @else if (pwa.isAndroid) {\r\n <li>Toca el menú <span class=\"pwa-guide__badge\"><i class=\"fas fa-ellipsis-vertical\"></i></span> en la esquina superior derecha</li>\r\n <li>Selecciona <strong>\"Instalar aplicación\"</strong> o <strong>\"Añadir a pantalla de inicio\"</strong></li>\r\n <li>Toca <strong>\"Instalar\"</strong> para confirmar</li>\r\n } @else if (pwa.isSafariMac) {\r\n <li>Abre el menú <strong>\"Archivo\"</strong> en la barra superior del Mac</li>\r\n <li>Selecciona <strong>\"Añadir al Dock...\"</strong></li>\r\n <li>Haz clic en <strong>\"Añadir\"</strong> para confirmar</li>\r\n } @else if (pwa.isChrome) {\r\n <li>Busca el ícono <span class=\"pwa-guide__badge\"><i class=\"fas fa-display\"></i></span> al final de la barra de direcciones</li>\r\n <li>Haz clic en él y selecciona <strong>\"Instalar\"</strong></li>\r\n <li>Confirma en el diálogo que aparece</li>\r\n } @else {\r\n <li>Abre el menú <span class=\"pwa-guide__badge\"><i class=\"fas fa-ellipsis-vertical\"></i></span> de tu navegador</li>\r\n <li>Busca <strong>\"Instalar aplicación\"</strong> o <strong>\"Añadir a pantalla de inicio\"</strong></li>\r\n <li>Confirma para instalar</li>\r\n }\r\n </ol>\r\n }\r\n\r\n @if (pwa.canAutoInstall) {\r\n <button class=\"pwa-guide__install\" (click)=\"pwa.tryInstall()\">\r\n <i class=\"fas fa-download\"></i> Instalar ahora\r\n </button>\r\n }\r\n <button class=\"pwa-guide__done\" (click)=\"onMarkAsAdded()\">\r\n <i class=\"fas fa-check\"></i> Ya lo instalé\r\n </button>\r\n </div>\r\n }\r\n\r\n <button class=\"pwa-chip\" (click)=\"onChipClick()\">\r\n <img [src]=\"logo()\" alt=\"\" class=\"pwa-chip__logo\">\r\n <span>{{ chipLabel() }}</span>\r\n </button>\r\n\r\n</div>\r\n}\r\n","import { Component, signal } from '@angular/core';\r\n\r\n@Component({\r\n selector: 'app-refresh-floating',\r\n templateUrl: './refresh-floating.component.html',\r\n styleUrl: './refresh-floating.component.scss'\r\n})\r\n\r\nexport class RefreshFloatingComponent {\r\n\r\n showGuide = signal<boolean>(false)\r\n\r\n toggleGuide() {\r\n this.showGuide.update(v => !v)\r\n }\r\n\r\n actualizar() {\r\n window.location.reload()\r\n }\r\n\r\n async actualizarTotal() {\r\n if ('serviceWorker' in navigator) {\r\n const registrations = await navigator.serviceWorker.getRegistrations()\r\n await Promise.all(registrations.map(r => r.unregister()))\r\n }\r\n if ('caches' in window) {\r\n const names = await caches.keys()\r\n await Promise.all(names.map(name => caches.delete(name)))\r\n }\r\n window.location.href = window.location.pathname + '?_r=' + Date.now()\r\n }\r\n}\r\n","<div class=\"refresh-wrap\">\r\n\r\n @if (showGuide()) {\r\n <div class=\"refresh-guide\">\r\n <button class=\"refresh-guide__close\" (click)=\"toggleGuide()\">\r\n <i class=\"fas fa-xmark\"></i>\r\n </button>\r\n\r\n <p class=\"refresh-guide__title\">Actualizar aplicación</p>\r\n\r\n <button class=\"refresh-guide__option\" (click)=\"actualizar()\">\r\n <i class=\"fas fa-rotate\"></i> Actualizar\r\n </button>\r\n\r\n <button class=\"refresh-guide__option refresh-guide__option--force\" (click)=\"actualizarTotal()\">\r\n <i class=\"fas fa-rotate-right\"></i> Forzar actualización\r\n </button>\r\n </div>\r\n }\r\n\r\n <button class=\"refresh-chip\" (click)=\"toggleGuide()\" title=\"Actualizar\">\r\n <i class=\"fas fa-rotate\"></i>\r\n </button>\r\n\r\n</div>\r\n","import { afterRenderEffect, Component, computed, DestroyRef, effect, ElementRef, inject, input, output, signal, untracked, viewChild } from '@angular/core';\r\nimport { MfaChallengeResponse, MfaEstadoPush } from '../../models/verificar-mfa';\r\nimport { AUTH_API } from '../../models/auth-api';\r\nimport { mensajeDe } from '../../utils/mensaje-error';\r\n\r\ntype ModoVerificacion = 'codigo' | 'push'\r\ntype TipoCodigo = 'totp' | 'respaldo'\r\ntype EstadoPush = 'idle' | 'enviando' | 'esperando' | 'rechazado' | 'expirado'\r\n\r\nconst INTERVALO_ESTADO_MS = 2000\r\nconst MAXIMO_ESPERA_MS = 120000\r\n\r\ninterface CampoCodigo {\r\n label: string\r\n placeholder: string\r\n descri: string\r\n icon: string\r\n inputmode: string\r\n patron: RegExp\r\n mensajeInvalido: string\r\n mensajeIncorrecto: string\r\n}\r\n\r\nconst CAMPOS_CODIGO: Record<TipoCodigo, CampoCodigo> = {\r\n totp: {\r\n label: 'Código de verificación', placeholder: '000000', icon: 'fa-mobile-alt', inputmode: 'numeric',\r\n patron: /^\\d{6}$/,\r\n descri: 'Ingresa el código de 6 dígitos que muestra tu app de autenticación.',\r\n mensajeInvalido: 'Ingresa el código de 6 dígitos de tu app.',\r\n mensajeIncorrecto: 'Código incorrecto. Verifica la hora de tu dispositivo.'\r\n },\r\n respaldo: {\r\n label: 'Código de respaldo', placeholder: 'XXXX-XXXX', icon: 'fa-key', inputmode: 'text',\r\n patron: /^[A-Z0-9]{4}-[A-Z0-9]{4}$/,\r\n descri: 'Ingresa uno de tus códigos de respaldo. Cada código sirve una sola vez.',\r\n mensajeInvalido: 'Ingresa un código de respaldo válido (XXXX-XXXX).',\r\n mensajeIncorrecto: 'Código de respaldo incorrecto o ya utilizado.'\r\n }\r\n}\r\n\r\nconst limpiarCodigo = (valor: string, tipo: TipoCodigo) => {\r\n if (tipo == 'totp') return valor.replace(/\\D/g, '').slice(0, 6)\r\n const base = valor.toUpperCase().replace(/[^A-Z0-9]/g, '').slice(0, 8)\r\n return base.length > 4 ? `${base.slice(0, 4)}-${base.slice(4)}` : base\r\n}\r\n\r\n\r\nconst esperar = (ms: number, signal: AbortSignal) => new Promise<void>(resolve => {\r\n const id = setTimeout(resolve, ms)\r\n signal.addEventListener('abort', () => { clearTimeout(id); resolve() }, { once: true })\r\n})\r\n\r\n@Component({\r\n selector: 'lib-md-verificar-mfa',\r\n templateUrl: './md-verificar-mfa.component.html',\r\n styleUrls: ['./md-verificar-mfa.component.scss', '../auth.scss']\r\n})\r\nexport class MdVerificarMfaComponent {\r\n\r\n private api = inject(AUTH_API)\r\n\r\n challenge = input.required<MfaChallengeResponse>()\r\n titulo = input<string>('Verificación en dos pasos')\r\n showCancelar = input<boolean>(true)\r\n\r\n verificado = output<void>()\r\n cancelado = output<void>()\r\n\r\n tienePush = computed(() => (this.challenge().tipos ?? []).includes('PUSH'))\r\n tieneTotp = computed(() => {\r\n const tipos = this.challenge().tipos ?? []\r\n return tipos.length == 0 || tipos.includes('TOTP')\r\n })\r\n\r\n modo = signal<ModoVerificacion>('codigo')\r\n tipoCodigo = signal<TipoCodigo>('totp')\r\n campo = computed(() => CAMPOS_CODIGO[this.tipoCodigo()])\r\n\r\n codigo = signal<string>('')\r\n codigoError = signal<string>('')\r\n isEnviando = signal<boolean>(false)\r\n\r\n estadoPush = signal<EstadoPush>('idle')\r\n isPushEnCurso = computed(() => this.estadoPush() == 'enviando' || this.estadoPush() == 'esperando')\r\n pushError = signal<string>('')\r\n\r\n private inputCodigo = viewChild<ElementRef<HTMLInputElement>>('inputCodigo')\r\n private pushCtrl?: AbortController\r\n\r\n constructor() {\r\n inject(DestroyRef).onDestroy(() => this.cancelarPush())\r\n\r\n effect(() => {\r\n this.challenge()\r\n untracked(() => this.iniciar())\r\n })\r\n\r\n afterRenderEffect(() => {\r\n if (this.modo() != 'codigo' || this.isEnviando()) return\r\n this.tipoCodigo()\r\n this.codigoError()\r\n this.inputCodigo()?.nativeElement.focus()\r\n })\r\n }\r\n\r\n private iniciar() {\r\n this.cancelarPush()\r\n this.pushError.set('')\r\n if (this.tienePush() && !this.tieneTotp()) {\r\n this.usarPush()\r\n return\r\n }\r\n this.usarCodigo('totp')\r\n }\r\n\r\n onCodigoInput(event: Event) {\r\n const input = event.target as HTMLInputElement\r\n const limpio = limpiarCodigo(input.value, this.tipoCodigo())\r\n input.value = limpio\r\n this.codigo.set(limpio)\r\n if (this.codigoError()) this.codigoError.set('')\r\n }\r\n\r\n usarCodigo(tipo: TipoCodigo) {\r\n this.cancelarPush()\r\n this.modo.set('codigo')\r\n this.tipoCodigo.set(tipo)\r\n this.codigo.set('')\r\n this.codigoError.set('')\r\n }\r\n\r\n async verificar() {\r\n if (this.modo() == 'push' || this.isEnviando()) return\r\n const campo = this.campo()\r\n if (!campo.patron.test(this.codigo())) {\r\n this.codigoError.set(campo.mensajeInvalido)\r\n return\r\n }\r\n this.isEnviando.set(true)\r\n this.codigoError.set('')\r\n try {\r\n await this.api.verificarCodigo({ preauthToken: this.challenge().preauthToken, codigo: this.codigo() })\r\n this.verificado.emit()\r\n } catch (err) {\r\n this.codigo.set('')\r\n this.codigoError.set(mensajeDe(err, campo.mensajeIncorrecto))\r\n } finally {\r\n this.isEnviando.set(false)\r\n }\r\n }\r\n\r\n usarPush() {\r\n this.modo.set('push')\r\n this.codigoError.set('')\r\n this.enviarPush()\r\n }\r\n\r\n async enviarPush() {\r\n this.cancelarPush()\r\n const ctrl = new AbortController()\r\n this.pushCtrl = ctrl\r\n this.pushError.set('')\r\n this.estadoPush.set('enviando')\r\n const preauthToken = this.challenge().preauthToken\r\n\r\n try {\r\n const solicitudId = await this.api.enviarPush(preauthToken)\r\n if (ctrl.signal.aborted) return\r\n this.estadoPush.set('esperando')\r\n\r\n const limite = Date.now() + MAXIMO_ESPERA_MS\r\n while (Date.now() < limite) {\r\n const estado = await this.api.estadoPush({ preauthToken, solicitudId })\r\n if (ctrl.signal.aborted) return\r\n if (estado != 'waiting') {\r\n this.resolverPush(estado)\r\n return\r\n }\r\n await esperar(INTERVALO_ESTADO_MS, ctrl.signal)\r\n if (ctrl.signal.aborted) return\r\n }\r\n this.estadoPush.set('expirado')\r\n this.pushError.set('No respondiste a tiempo la notificación. Vuelve a enviarla.')\r\n } catch (err) {\r\n if (ctrl.signal.aborted) return\r\n this.estadoPush.set('idle')\r\n this.pushError.set(mensajeDe(err, 'No se pudo enviar la notificación.'))\r\n }\r\n }\r\n\r\n cancelar() {\r\n this.cancelarPush()\r\n this.cancelado.emit()\r\n }\r\n\r\n private resolverPush(estado: Exclude<MfaEstadoPush, 'waiting'>) {\r\n if (estado == 'aprobado') {\r\n this.estadoPush.set('idle')\r\n this.verificado.emit()\r\n return\r\n }\r\n if (estado == 'expired') {\r\n this.estadoPush.set('expirado')\r\n this.pushError.set('La solicitud expiró. Vuelve a enviarla.')\r\n return\r\n }\r\n this.estadoPush.set('rechazado')\r\n this.pushError.set('Rechazaste la notificación en tu teléfono.')\r\n }\r\n\r\n private cancelarPush() {\r\n this.pushCtrl?.abort()\r\n this.pushCtrl = undefined\r\n if (this.isPushEnCurso()) this.estadoPush.set('idle')\r\n }\r\n\r\n}\r\n","<div class=\"verificar-mfa\">\n <div class=\"auth-card-title mb-3\">{{ titulo() }}</div>\n\n <div class=\"d-flex align-items-center gap-3 mb-3\">\n <span class=\"verificar-mfa__icono\"><i class=\"fas fa-user-shield\"></i></span>\n <div>\n <div class=\"fw-semibold\">{{ challenge().coduser }}</div>\n @if (challenge().empresa) {\n <div class=\"verificar-mfa__muted\">{{ challenge().empresa }}</div>\n }\n </div>\n </div>\n\n @if (modo() == 'push') {\n @switch (estadoPush()) {\n @case ('enviando') {\n <div class=\"duo-push\">\n <span class=\"spinner-border spinner-border-sm text-primary\"></span>\n <div class=\"flex-grow-1\">Enviando notificación a tu teléfono…</div>\n </div>\n }\n @case ('esperando') {\n <div class=\"duo-push duo-push--esperando\">\n <span class=\"duo-push__icono duo-push__icono--pulso\"><i class=\"fas fa-mobile-alt\"></i></span>\n <div class=\"flex-grow-1\">\n <div class=\"fw-semibold\">Revisa tu teléfono</div>\n <div class=\"verificar-mfa__muted\">Aprueba la notificación en TSI Autenticador para ingresar.</div>\n </div>\n </div>\n }\n @default {\n <div class=\"duo-push\">\n <span class=\"duo-push__icono\"><i class=\"fas fa-bell\"></i></span>\n <div class=\"flex-grow-1\">\n <div class=\"fw-semibold\">TSI Autenticador</div>\n <div class=\"verificar-mfa__muted\">Te enviaremos una notificación para que la apruebes.</div>\n </div>\n </div>\n }\n }\n @if (pushError() && !isPushEnCurso()) {\n <div class=\"codigo-field__error\"><i class=\"fas fa-exclamation-circle\"></i> {{ pushError() }}</div>\n }\n\n <div class=\"verificar-mfa__opciones\">\n @if (tieneTotp()) {\n <button type=\"button\" class=\"verificar-mfa__link\" (click)=\"usarCodigo('totp')\">\n Usar código de mi app de autenticación\n </button>\n }\n <button type=\"button\" class=\"verificar-mfa__link verificar-mfa__link--secundario\"\n (click)=\"usarCodigo('respaldo')\">\n ¿No tienes tu teléfono? Usa un código de respaldo\n </button>\n </div>\n } @else {\n <p class=\"verificar-mfa__muted mb-4\">\n @if (tipoCodigo() == 'totp') {\n {{ challenge().mensaje || campo().descri }}\n } @else {\n {{ campo().descri }}\n }\n </p>\n\n <div class=\"codigo-field\" [class.has-error]=\"codigoError()\">\n <span class=\"codigo-field__icon\"><i class=\"fas\" [class]=\"campo().icon\"></i></span>\n <input #inputCodigo id=\"mfa-codigo\" class=\"codigo-field__input\" type=\"text\"\n [placeholder]=\"campo().placeholder\" [value]=\"codigo()\" (input)=\"onCodigoInput($event)\"\n (keydown.enter)=\"verificar()\" [attr.inputmode]=\"campo().inputmode\" autocomplete=\"one-time-code\"\n autocorrect=\"off\" autocapitalize=\"characters\" spellcheck=\"false\" [disabled]=\"isEnviando()\">\n <label for=\"mfa-codigo\" class=\"codigo-field__label\">{{ campo().label }}</label>\n </div>\n @if (codigoError()) {\n <div class=\"codigo-field__error\"><i class=\"fas fa-exclamation-circle\"></i> {{ codigoError() }}</div>\n }\n\n <div class=\"verificar-mfa__opciones\">\n @if (tienePush()) {\n <button type=\"button\" class=\"verificar-mfa__link\" (click)=\"usarPush()\">\n <i class=\"fas fa-bell me-1\"></i>Mejor envíame una notificación push\n </button>\n }\n @if (tieneTotp() && tipoCodigo() != 'totp') {\n <button type=\"button\" class=\"verificar-mfa__link\" (click)=\"usarCodigo('totp')\">\n Usar código de mi app de autenticación\n </button>\n }\n @if (tipoCodigo() != 'respaldo') {\n <button type=\"button\" class=\"verificar-mfa__link verificar-mfa__link--secundario\"\n (click)=\"usarCodigo('respaldo')\">\n ¿No tienes tu teléfono? Usa un código de respaldo\n </button>\n }\n </div>\n }\n\n <div class=\"verificar-mfa__acciones\">\n @if (modo() == 'push') {\n <button type=\"button\" class=\"auth-btn\" [disabled]=\"isPushEnCurso()\" (click)=\"enviarPush()\">\n <i class=\"fas fa-paper-plane me-1\"></i>\n {{ isPushEnCurso() ? 'Esperando aprobación…' : 'Reenviar notificación' }}\n </button>\n } @else {\n <button type=\"button\" class=\"auth-btn\" [disabled]=\"isEnviando()\" (click)=\"verificar()\">\n <i class=\"fas fa-check me-1\"></i>\n {{ isEnviando() ? 'Verificando…' : 'Verificar' }}\n </button>\n }\n @if (showCancelar()) {\n <button type=\"button\" class=\"auth-btn auth-btn--outline\" (click)=\"cancelar()\">Cancelar</button>\n }\n </div>\n</div>\n","import { NgClass } from '@angular/common';\r\nimport { Component, ElementRef, inject, input, output, signal, viewChild } from '@angular/core';\r\nimport { FormGroup, ReactiveFormsModule } from '@angular/forms';\r\nimport { AuthSender } from '../../models/auth-sender';\r\nimport { fadeInOut } from '../../utils/animations';\r\nimport { LoginEvent } from '../../models/login-event';\r\nimport { AUTH_API } from '../../models/auth-api';\r\nimport { mensajeDe } from '../../utils/mensaje-error';\r\nimport { isMfaChallenge, MfaChallengeResponse } from '../../models/verificar-mfa';\r\nimport { PwaFloatingComponent } from '../pwa-floating/pwa-floating.component';\r\nimport { RefreshFloatingComponent } from '../refresh-floating/refresh-floating.component';\r\nimport { MdVerificarMfaComponent } from '../md-verificar-mfa/md-verificar-mfa.component';\r\n\r\ninterface PasoMfa {\r\n challenge: MfaChallengeResponse\r\n data: AuthSender\r\n}\r\n\r\nconst MENSAJE_ERROR_LOGIN = 'No se pudo iniciar sesión.'\r\nconst CLASE_CERRANDO = 'auth-mfa-dialog--cerrando'\r\nconst MAXIMO_SALIDA_MS = 400\r\n\r\n@Component({\r\n selector: 'lib-auth-tsi',\r\n imports: [NgClass, ReactiveFormsModule, PwaFloatingComponent, RefreshFloatingComponent, MdVerificarMfaComponent],\r\n templateUrl: './auth.component.html',\r\n styleUrls: ['./auth.component.scss', '../auth.scss'],\r\n animations: [fadeInOut]\r\n})\r\nexport class AuthComponent {\r\n\r\n private api = inject(AUTH_API, { optional: true })\r\n\r\n production = input<boolean>(true)\r\n module = input<string>('ERP')\r\n versionApp = input<string>('1.0.0')\r\n product = input<string>()\r\n authForm = input.required<FormGroup>();\r\n\r\n aboutList = input<string[]>([\r\n 'Gestión de compras y logística',\r\n 'Control financiero avanzado',\r\n 'Reportes y análisis en tiempo real',\r\n 'Integración con inteligencia artificial'\r\n ])\r\n\r\n showFloatingApp = input<boolean>(true)\r\n showFloatingUpdate = input<boolean>(true)\r\n\r\n loginEvent = output<LoginEvent>()\r\n beforeInstall = output<void>()\r\n\r\n showPassword = signal<boolean>(false)\r\n isIngresando = signal<boolean>(false)\r\n pasoMfa = signal<PasoMfa | null>(null)\r\n\r\n private dialogMfa = viewChild.required<ElementRef<HTMLDialogElement>>('dialogMfa')\r\n\r\n onBeforeInstall = () => this.beforeInstall.emit()\r\n\r\n recover = () => this.loginEvent.emit({type: \"RECOVER\"})\r\n forget = () => this.loginEvent.emit({type: \"FORGET\"})\r\n\r\n togglePassword = () => this.showPassword.set(!this.showPassword())\r\n\r\n login = async () => {\r\n if (this.isIngresando() || !this.validacionInit()) return\r\n const data = this.armarSender()\r\n if (!this.api) {\r\n this.loginEvent.emit({type: \"LOGIN\", data})\r\n return\r\n }\r\n this.isIngresando.set(true)\r\n try {\r\n const respuesta = await this.api.login(data)\r\n if (isMfaChallenge(respuesta)) {\r\n this.abrirMfa({ challenge: respuesta, data })\r\n return\r\n }\r\n this.loginEvent.emit({type: \"AUTENTICADO\", data})\r\n } catch (err) {\r\n this.returnError(mensajeDe(err, MENSAJE_ERROR_LOGIN))\r\n } finally {\r\n this.isIngresando.set(false)\r\n }\r\n }\r\n\r\n onMfaVerificado = async () => {\r\n const paso = this.pasoMfa()\r\n await this.cerrarMfa()\r\n if (paso) this.loginEvent.emit({type: \"AUTENTICADO\", data: paso.data})\r\n }\r\n\r\n onMfaCancelado = async () => {\r\n await this.cerrarMfa()\r\n this.authForm().patchValue({ clave: '' })\r\n }\r\n\r\n private abrirMfa(paso: PasoMfa) {\r\n const dialog = this.dialogMfa().nativeElement\r\n dialog.classList.remove(CLASE_CERRANDO)\r\n this.pasoMfa.set(paso)\r\n if (!dialog.open) dialog.showModal()\r\n }\r\n\r\n private cerrarMfa() {\r\n const dialog = this.dialogMfa().nativeElement\r\n if (!dialog.open) {\r\n this.pasoMfa.set(null)\r\n return Promise.resolve()\r\n }\r\n return new Promise<void>(resolve => {\r\n let terminado = false\r\n const terminar = () => {\r\n if (terminado) return\r\n terminado = true\r\n clearTimeout(respaldo)\r\n dialog.removeEventListener('animationend', alTerminarAnimacion)\r\n dialog.close()\r\n dialog.classList.remove(CLASE_CERRANDO)\r\n this.pasoMfa.set(null)\r\n resolve()\r\n }\r\n const alTerminarAnimacion = (event: AnimationEvent) => {\r\n if (event.target == dialog) terminar()\r\n }\r\n const respaldo = setTimeout(terminar, MAXIMO_SALIDA_MS)\r\n dialog.addEventListener('animationend', alTerminarAnimacion)\r\n dialog.classList.add(CLASE_CERRANDO)\r\n })\r\n }\r\n\r\n private armarSender(): AuthSender {\r\n const dataForm = this.authForm().value\r\n return {\r\n ruc: dataForm.ruc,\r\n coduser: dataForm.nomuser,\r\n clave: btoa(dataForm.clave),\r\n producto: this.product()\r\n }\r\n }\r\n\r\n validacion(value: string) {\r\n const authForm = this.authForm()\r\n if (authForm.get(value).touched && authForm.get(value).errors) {\r\n return true\r\n }\r\n return false\r\n }\r\n\r\n validacionInit() {\r\n const dataForm = this.authForm().value\r\n const { ruc, nomuser, clave } = dataForm\r\n\r\n if (!ruc) return this.returnError('Debe ingresar un N° de RUC')\r\n if (!nomuser) return this.returnError('Debe ingresar un usuario')\r\n if (!clave) return this.returnError('Debe ingresar una contraseña')\r\n return true\r\n }\r\n\r\n returnError = (message:string) => {\r\n this.loginEvent.emit({type: \"ERROR\", message})\r\n return false\r\n }\r\n}\r\n","<div class=\"auth-wrapper-login\">\r\n @let produccion = production();\r\n <div class=\"auth-panel-left\" [class.auth-panel-left--dev]=\"!produccion\">\r\n <span class=\"auth-blob auth-blob-1\"></span>\r\n <span class=\"auth-blob auth-blob-2\"></span>\r\n <span class=\"auth-blob auth-blob-3\"></span>\r\n <span class=\"auth-blob auth-blob-4\"></span>\r\n\r\n <div class=\"auth-brand-panel\">\r\n <div class=\"auth-brand-logo\">\r\n <img src=\"assets/images/logo-tsi-tres.png\" alt=\"TSI\" />\r\n </div>\r\n <h1 class=\"auth-brand-title\">{{module()}}</h1>\r\n <p class=\"auth-brand-subtitle\">Plataforma integrada de gestión<br>empresarial</p>\r\n\r\n <div class=\"auth-brand-divider\"></div>\r\n\r\n <div class=\"auth-brand-features\">\r\n @for (item of aboutList(); track $index) {\r\n <div class=\"auth-brand-feature\">\r\n <span class=\"feat-dot\"></span> {{item}}\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"auth-panel-right\" [class.auth-panel-right--dev]=\"!produccion\">\r\n <div class=\"auth-panel-bg\">\r\n <span class=\"auth-deco auth-deco-tl\"></span>\r\n <span class=\"auth-deco auth-deco-br\"></span>\r\n </div>\r\n\r\n <div class=\"auth-form-wrapper\">\r\n <div>\r\n @if (!produccion) {\r\n <div>\r\n <span class=\"auth-test-badge\">\r\n <span class=\"badge-dot\"></span> ENTORNO DE PRUEBAS\r\n </span>\r\n </div>\r\n }\r\n\r\n <div class=\"auth-card\">\r\n <h2 class=\"auth-card-title\">Bienvenido de vuelta</h2>\r\n <p class=\"auth-card-subtitle\">Ingresa tus credenciales para continuar</p>\r\n\r\n <form [formGroup]=\"authForm()\" id=\"loginform\">\r\n\r\n <p class=\"auth-hint\">\r\n <i class=\"fas fa-circle-info\"></i>\r\n Si piensas instalar la app, te recomendamos completar el RUC y Usuario antes, estos quedarán guardados y siempre aparecerán completos al abrirla.\r\n </p>\r\n\r\n <div class=\"auth-field\" [class.has-error]=\"validacion('ruc')\">\r\n <span class=\"auth-field-icon\"><i class=\"fas fa-building\"></i></span>\r\n <input type=\"text\" formControlName=\"ruc\" class=\"auth-input\" placeholder=\" \" maxlength=\"11\"\r\n id=\"f-ruc\" autocomplete=\"off\">\r\n <label for=\"f-ruc\" class=\"auth-label\">RUC</label>\r\n </div>\r\n @if (validacion('ruc')) {\r\n <p class=\"auth-error\" @fadeInOut>Ingresar RUC</p>\r\n }\r\n\r\n <div class=\"auth-field\" [class.has-error]=\"validacion('nomuser')\">\r\n <span class=\"auth-field-icon\"><i class=\"fas fa-user\"></i></span>\r\n <input type=\"text\" formControlName=\"nomuser\" class=\"auth-input\" placeholder=\" \" id=\"f-user\"\r\n autocomplete=\"off\">\r\n <label for=\"f-user\" class=\"auth-label\">Usuario</label>\r\n </div>\r\n @if (validacion('nomuser')) {\r\n <p class=\"auth-error\" @fadeInOut>Ingresar usuario</p>\r\n }\r\n\r\n <div class=\"auth-field\" [class.has-error]=\"validacion('clave')\">\r\n <span class=\"auth-field-icon\"><i class=\"fas fa-lock\"></i></span>\r\n <input [type]=\"showPassword() ? 'text' : 'password'\" formControlName=\"clave\"\r\n class=\"auth-input\" placeholder=\" \" id=\"f-clave\" autocomplete=\"off\" autocorrect=\"off\"\r\n autocapitalize=\"off\" spellcheck=\"false\">\r\n <label for=\"f-clave\" class=\"auth-label\">Contraseña</label>\r\n <button type=\"button\" class=\"auth-toggle-pw\" (click)=\"togglePassword()\">\r\n <i [class]=\"showPassword() ? 'fas fa-eye' : 'fas fa-eye-slash'\"></i>\r\n </button>\r\n </div>\r\n @if (validacion('clave')) {\r\n <p class=\"auth-error\" @fadeInOut>Ingresar clave</p>\r\n }\r\n\r\n <button class=\"auth-btn mt-2\" [class.auth-btn--red]=\"!produccion\" [disabled]=\"isIngresando()\"\r\n (click)=\"login()\">\r\n {{ isIngresando() ? 'Ingresando…' : 'Ingresar' }}\r\n </button>\r\n\r\n <div class=\"auth-links\">\r\n <a [ngClass]=\"produccion ? 'blue_contrasena' : 'red_contrasena'\"\r\n (click)=\"recover()\">¿Olvidaste tu contraseña?</a>\r\n <a [ngClass]=\"produccion ? 'blue_contrasena' : 'red_contrasena'\"\r\n (click)=\"forget()\">¿Contraseña vencida?</a>\r\n </div>\r\n\r\n </form>\r\n\r\n <div class=\"auth-version\">\r\n <span>v{{versionApp()}}</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<dialog #dialogMfa class=\"auth-mfa-dialog\" (cancel)=\"$event.preventDefault()\">\r\n @if (pasoMfa(); as paso) {\r\n <lib-md-verificar-mfa [challenge]=\"paso.challenge\" (verificado)=\"onMfaVerificado()\"\r\n (cancelado)=\"onMfaCancelado()\" />\r\n }\r\n</dialog>\r\n\r\n@if (showFloatingApp()) {\r\n<app-pwa-floating [appName]=\"module()\" (beforeInstall)=\"onBeforeInstall()\" />\r\n}\r\n@if (showFloatingUpdate()) {\r\n<app-refresh-floating />\r\n}","import { Component, inject, input, output, signal } from '@angular/core';\r\nimport { AbstractControl, FormBuilder, ReactiveFormsModule, Validators } from '@angular/forms';\r\nimport { AuthSender } from '../../models/auth-sender';\r\nimport { fadeInOut } from '../../utils/animations';\r\nimport { LoginEvent } from '../../models/login-event';\r\n\r\n@Component({\r\n selector: 'lib-expired-password',\r\n imports: [ReactiveFormsModule],\r\n templateUrl: './expired-password.component.html',\r\n styleUrls: ['./expired-password.component.scss', '../auth.scss'],\r\n animations: [fadeInOut]\r\n})\r\nexport class ExpiredPasswordComponent {\r\n\r\n private readonly fb = inject(FormBuilder)\r\n\r\n production = input<boolean>(true)\r\n module = input<string>('ERP') // DEFECTO ERP\r\n\r\n loginEvent = output<LoginEvent>()\r\n\r\n passwordVisibility = signal({\r\n claveAntigua: false,\r\n claveNueva: false,\r\n claveNuevaConfirmar: false\r\n })\r\n\r\n expiredForm = this.fb.group({\r\n ruc: ['', [Validators.required, Validators.minLength(11), Validators.maxLength(11)]],\r\n coduser: ['', Validators.required],\r\n claveAntigua: ['', [Validators.required, Validators.maxLength(20)]],\r\n claveNueva: ['', [\r\n Validators.required,\r\n Validators.minLength(8),\r\n this.regexValidator(/[a-z]/, { minuscula: true }),\r\n this.regexValidator(/[A-Z]/, { mayuscula: true }),\r\n this.regexValidator(/[0-9]/, { numero: true }),\r\n this.regexValidator(/[!@#$%^&*(),.?\":{}|<>]/, { especial: true })\r\n ]],\r\n claveNuevaConfirmar: ['', Validators.required]\r\n }, {\r\n validators: this.validatePassword('claveNueva', 'claveNuevaConfirmar')\r\n })\r\n\r\n regexValidator(regex: RegExp, error: any) {\r\n return (control: AbstractControl) => {\r\n if (!control.value) return null\r\n return regex.test(control.value) ? null : error\r\n }\r\n }\r\n\r\n validatePassword(pass1: string, pass2: string) {\r\n return (formGroup: AbstractControl) => {\r\n const c1 = formGroup.get(pass1)?.value\r\n const c2 = formGroup.get(pass2)?.value\r\n if (c1 != c2) {\r\n formGroup.get(pass2)?.setErrors({ coinciden: true })\r\n return { coinciden: true }\r\n }\r\n return null\r\n }\r\n }\r\n\r\n togglePassword(field: 'claveAntigua' | 'claveNueva' | 'claveNuevaConfirmar') {\r\n this.passwordVisibility.update(vis => ({ ...vis, [field]: !vis[field] }));\r\n }\r\n\r\n recover = () => {\r\n if (this.expiredForm.invalid) {\r\n this.loginEvent.emit({type: \"ERROR\", message: 'Debes completar todos los campos y cumplir los requisitos.'})\r\n return\r\n }\r\n \r\n const values = this.expiredForm.value\r\n const sender: AuthSender = {\r\n ruc: values.ruc!,\r\n coduser: values.coduser!,\r\n clave: values.claveAntigua!,\r\n nuevaclave: values.claveNueva!\r\n }\r\n this.loginEvent.emit({ type: \"FORGET\", data: sender })\r\n }\r\n\r\n back = () => {\r\n this.expiredForm.reset()\r\n this.loginEvent.emit({ type: \"BACK\" })\r\n }\r\n}\r\n","<div class=\"auth-wrapper-login\">\r\n @let produccion = production();\r\n <div class=\"auth-panel-left\" [class.auth-panel-left--dev]=\"!produccion\">\r\n <span class=\"auth-blob auth-blob-1\"></span>\r\n <span class=\"auth-blob auth-blob-2\"></span>\r\n <span class=\"auth-blob auth-blob-3\"></span>\r\n <span class=\"auth-blob auth-blob-4\"></span>\r\n\r\n <div class=\"auth-brand-panel\">\r\n <div class=\"auth-brand-logo\">\r\n <img src=\"assets/images/logo-tsi-tres.png\" alt=\"TSI\" />\r\n </div>\r\n <h1 class=\"auth-brand-title\">{{module()}}</h1>\r\n <p class=\"auth-brand-subtitle\">Renueva tu contraseña y mantén tu cuenta segura</p>\r\n\r\n <div class=\"auth-brand-divider\"></div>\r\n\r\n <div class=\"auth-brand-features\">\r\n <div class=\"auth-brand-feature\">\r\n <span class=\"feat-dot\"></span> Mínimo 8 caracteres\r\n </div>\r\n <div class=\"auth-brand-feature\">\r\n <span class=\"feat-dot\"></span> Letras mayúsculas y minúsculas\r\n </div>\r\n <div class=\"auth-brand-feature\">\r\n <span class=\"feat-dot\"></span> Al menos un número y símbolo\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"auth-panel-right\" [class.auth-panel-right--dev]=\"!produccion\">\r\n <div class=\"auth-panel-bg\">\r\n <span class=\"auth-deco auth-deco-tl\"></span>\r\n <span class=\"auth-deco auth-deco-br\"></span>\r\n </div>\r\n\r\n <div class=\"auth-form-wrapper\">\r\n <div>\r\n @if (!produccion) {\r\n <div>\r\n <span class=\"auth-test-badge\">\r\n <span class=\"badge-dot\"></span> ENTORNO DE PRUEBAS\r\n </span>\r\n </div>\r\n }\r\n\r\n <div class=\"auth-card\">\r\n <h2 class=\"auth-card-title\">Renovar contraseña</h2>\r\n <p class=\"auth-card-subtitle\">Proporciona tus datos y elige una nueva clave</p>\r\n\r\n <form [formGroup]=\"expiredForm\">\r\n\r\n <div class=\"auth-field\"\r\n [class.has-error]=\"expiredForm.get('ruc')?.invalid && expiredForm.get('ruc')?.touched\">\r\n <span class=\"auth-field-icon\"><i class=\"fas fa-building\"></i></span>\r\n <input type=\"text\" class=\"auth-input\" placeholder=\" \" maxlength=\"11\"\r\n formControlName=\"ruc\" id=\"exp-ruc\" onlyNumber autocomplete=\"off\">\r\n <label for=\"exp-ruc\" class=\"auth-label\">RUC</label>\r\n </div>\r\n @if (expiredForm.get('ruc')?.invalid && expiredForm.get('ruc')?.touched) {\r\n <p class=\"auth-error\" @fadeInOut>RUC debe tener 11 dígitos</p>\r\n }\r\n\r\n <div class=\"auth-field\"\r\n [class.has-error]=\"expiredForm.get('coduser')?.invalid && expiredForm.get('coduser')?.touched\">\r\n <span class=\"auth-field-icon\"><i class=\"fas fa-user\"></i></span>\r\n <input type=\"text\" class=\"auth-input\" placeholder=\" \"\r\n formControlName=\"coduser\" id=\"exp-user\" autocomplete=\"off\">\r\n <label for=\"exp-user\" class=\"auth-label\">Usuario</label>\r\n </div>\r\n @if (expiredForm.get('coduser')?.invalid && expiredForm.get('coduser')?.touched) {\r\n <p class=\"auth-error\" @fadeInOut>El usuario es obligatorio</p>\r\n }\r\n\r\n <div class=\"auth-field\">\r\n <span class=\"auth-field-icon\"><i class=\"fas fa-lock-open\"></i></span>\r\n <input [type]=\"passwordVisibility().claveAntigua ? 'text' : 'password'\"\r\n class=\"auth-input\" placeholder=\" \" maxlength=\"20\"\r\n formControlName=\"claveAntigua\" id=\"exp-old-pw\" autocomplete=\"new-password\">\r\n <label for=\"exp-old-pw\" class=\"auth-label\">Contraseña antigua</label>\r\n <button type=\"button\" class=\"auth-toggle-pw\" (click)=\"togglePassword('claveAntigua')\">\r\n <i [class]=\"passwordVisibility().claveAntigua ? 'fas fa-eye' : 'fas fa-eye-slash'\"></i>\r\n </button>\r\n </div>\r\n\r\n <div class=\"auth-field\">\r\n <span class=\"auth-field-icon\"><i class=\"fas fa-lock\"></i></span>\r\n <input [type]=\"passwordVisibility().claveNueva ? 'text' : 'password'\"\r\n class=\"auth-input\" placeholder=\" \" maxlength=\"20\"\r\n formControlName=\"claveNueva\" id=\"exp-new-pw\" autocomplete=\"new-password\">\r\n <label for=\"exp-new-pw\" class=\"auth-label\">Contraseña nueva</label>\r\n <button type=\"button\" class=\"auth-toggle-pw\" (click)=\"togglePassword('claveNueva')\">\r\n <i [class]=\"passwordVisibility().claveNueva ? 'fas fa-eye' : 'fas fa-eye-slash'\"></i>\r\n </button>\r\n </div>\r\n\r\n @if (expiredForm.get('claveNueva')?.value?.length > 0) {\r\n <ul class=\"auth-validation-list\" @fadeInOut>\r\n @if (expiredForm.get('claveNueva')?.errors?.['minlength']) {\r\n <li>Al menos 8 caracteres</li>\r\n }\r\n @if (expiredForm.get('claveNueva')?.errors?.['minuscula']) {\r\n <li>Al menos 1 letra minúscula</li>\r\n }\r\n @if (expiredForm.get('claveNueva')?.errors?.['mayuscula']) {\r\n <li>Al menos 1 letra mayúscula</li>\r\n }\r\n @if (expiredForm.get('claveNueva')?.errors?.['numero']) {\r\n <li>Al menos 1 número</li>\r\n }\r\n @if (expiredForm.get('claveNueva')?.errors?.['especial']) {\r\n <li>Al menos 1 carácter especial</li>\r\n }\r\n </ul>\r\n }\r\n\r\n <div class=\"auth-field\"\r\n [class.has-error]=\"expiredForm.get('claveNuevaConfirmar')?.errors?.['coinciden'] && expiredForm.get('claveNuevaConfirmar')?.touched\">\r\n <span class=\"auth-field-icon\"><i class=\"fas fa-check-circle\"></i></span>\r\n <input [type]=\"passwordVisibility().claveNuevaConfirmar ? 'text' : 'password'\"\r\n class=\"auth-input\" placeholder=\" \" maxlength=\"20\"\r\n formControlName=\"claveNuevaConfirmar\" id=\"exp-confirm-pw\" autocomplete=\"new-password\">\r\n <label for=\"exp-confirm-pw\" class=\"auth-label\">Confirmar contraseña</label>\r\n <button type=\"button\" class=\"auth-toggle-pw\" (click)=\"togglePassword('claveNuevaConfirmar')\">\r\n <i [class]=\"passwordVisibility().claveNuevaConfirmar ? 'fas fa-eye' : 'fas fa-eye-slash'\"></i>\r\n </button>\r\n </div>\r\n @if (expiredForm.get('claveNuevaConfirmar')?.errors?.['coinciden'] && expiredForm.get('claveNuevaConfirmar')?.touched) {\r\n <p class=\"auth-error\" @fadeInOut>Las contraseñas deben coincidir</p>\r\n }\r\n\r\n <button type=\"button\" class=\"auth-btn\" [class.auth-btn--red]=\"!produccion\"\r\n [disabled]=\"expiredForm.invalid\" (click)=\"recover()\">\r\n Renovar contraseña\r\n </button>\r\n\r\n <button type=\"button\" class=\"auth-btn auth-btn--outline\" (click)=\"back()\">\r\n Volver al inicio de sesión\r\n </button>\r\n\r\n </form>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n","import { Component, inject, input, output } from '@angular/core';\r\nimport { FormBuilder, ReactiveFormsModule, Validators } from '@angular/forms';\r\nimport { AuthSender } from '../../models/auth-sender';\r\nimport { fadeInOut } from '../../utils/animations';\r\nimport { LoginEvent } from '../../models/login-event';\r\n\r\n@Component({\r\n selector: 'lib-recover-password',\r\n imports: [ReactiveFormsModule],\r\n templateUrl: './recover-password.component.html',\r\n styleUrls: ['./recover-password.component.scss', '../auth.scss'],\r\n animations: [fadeInOut]\r\n})\r\nexport class RecoverPasswordComponent {\r\n\r\n private fb = inject(FormBuilder)\r\n\r\n production = input<boolean>(true)\r\n module = input<string>('ERP') // DEFECTO ERP\r\n\r\n loginEvent = output<LoginEvent>()\r\n\r\n recoverForm = this.fb.group({\r\n ruc: ['', [Validators.required, Validators.minLength(11), Validators.maxLength(11)]],\r\n usuario: ['', Validators.required]\r\n })\r\n\r\n enviar = () => {\r\n if (this.recoverForm.invalid) {\r\n this.loginEvent.emit({ type: \"ERROR\", message: 'Debes completar todos los campos' })\r\n return\r\n }\r\n\r\n const formValues = this.recoverForm.value\r\n const sender: AuthSender = {\r\n ruc: formValues.ruc!,\r\n coduser: formValues.usuario!\r\n }\r\n\r\n this.loginEvent.emit({ type: \"RECOVER\", data: sender })\r\n }\r\n\r\n back = () => this.loginEvent.emit({ type: \"BACK\" })\r\n \r\n}\r\n","<div class=\"auth-wrapper-login\">\r\n @let produccion = production();\r\n <div class=\"auth-panel-left\" [class.auth-panel-left--dev]=\"!produccion\">\r\n <span class=\"auth-blob auth-blob-1\"></span>\r\n <span class=\"auth-blob auth-blob-2\"></span>\r\n <span class=\"auth-blob auth-blob-3\"></span>\r\n <span class=\"auth-blob auth-blob-4\"></span>\r\n\r\n <div class=\"auth-brand-panel\">\r\n <div class=\"auth-brand-logo\">\r\n <img src=\"assets/images/logo-tsi-tres.png\" alt=\"TSI\" />\r\n </div>\r\n <h1 class=\"auth-brand-title\">{{module()}}</h1>\r\n <p class=\"auth-brand-subtitle\">Recupera el acceso a tu cuenta de forma rápida y segura</p>\r\n\r\n <div class=\"auth-brand-divider\"></div>\r\n\r\n <div class=\"auth-brand-features\">\r\n <div class=\"auth-brand-feature\">\r\n <span class=\"feat-dot\"></span> Verificación por correo electrónico\r\n </div>\r\n <div class=\"auth-brand-feature\">\r\n <span class=\"feat-dot\"></span> Proceso seguro y encriptado\r\n </div>\r\n <div class=\"auth-brand-feature\">\r\n <span class=\"feat-dot\"></span> Nueva clave en minutos\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"auth-panel-right\" [class.auth-panel-right--dev]=\"!produccion\">\r\n <div class=\"auth-panel-bg\">\r\n <span class=\"auth-deco auth-deco-tl\"></span>\r\n <span class=\"auth-deco auth-deco-br\"></span>\r\n </div>\r\n\r\n <div class=\"auth-form-wrapper\">\r\n <div>\r\n @if (!produccion) {\r\n <div>\r\n <span class=\"auth-test-badge\">\r\n <span class=\"badge-dot\"></span> ENTORNO DE PRUEBAS\r\n </span>\r\n </div>\r\n }\r\n\r\n <div class=\"auth-card\">\r\n <h2 class=\"auth-card-title\">Recuperar contraseña</h2>\r\n <p class=\"auth-card-subtitle\">\r\n Confírmanos tu RUC y usuario. Enviaremos a tu correo registrado la nueva contraseña.\r\n </p>\r\n\r\n <form [formGroup]=\"recoverForm\">\r\n\r\n <div class=\"auth-field\">\r\n <span class=\"auth-field-icon\"><i class=\"fas fa-building\"></i></span>\r\n <input type=\"text\" class=\"auth-input\" placeholder=\" \" maxlength=\"11\" formControlName=\"ruc\"\r\n id=\"rec-ruc\" onlyNumber autocomplete=\"off\">\r\n <label for=\"rec-ruc\" class=\"auth-label\">RUC</label>\r\n </div>\r\n\r\n <div class=\"auth-field\">\r\n <span class=\"auth-field-icon\"><i class=\"fas fa-user\"></i></span>\r\n <input type=\"text\" class=\"auth-input\" placeholder=\" \" formControlName=\"usuario\"\r\n id=\"rec-user\" autocomplete=\"off\">\r\n <label for=\"rec-user\" class=\"auth-label\">Usuario</label>\r\n </div>\r\n\r\n <button type=\"button\" class=\"auth-btn\" [class.auth-btn--red]=\"!produccion\"\r\n [disabled]=\"recoverForm.invalid\" (click)=\"enviar()\">\r\n Enviar instrucciones\r\n </button>\r\n\r\n <button type=\"button\" class=\"auth-btn auth-btn--outline\" (click)=\"back()\">\r\n Volver al inicio de sesión\r\n </button>\r\n\r\n </form>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>","import { Component, computed, HostListener, input, model, output } from '@angular/core';\r\nimport { FormsModule } from '@angular/forms';\r\nimport { LoginEvent } from '../../models/login-event';\r\n\r\n@Component({\r\n selector: 'lib-select-branch',\r\n imports: [FormsModule],\r\n templateUrl: './select-branch.component.html',\r\n styleUrls: ['./select-branch.component.scss', '../auth.scss']\r\n})\r\nexport class SelectBranchComponent {\r\n\r\n production = input<boolean>(true)\r\n module = input<string>('ERP') // DEFECTO ERP\r\n title = computed(() => this.production() ? `MÓDULO: ${this.module()}` : `MÓDULO DE PRUEBA: ${this.module()}`)\r\n\r\n codsuc = model<number>(-1)\r\n sucursalesList = input<any[]>([])\r\n\r\n loginEvent = output<LoginEvent>()\r\n\r\n @HostListener('document:keydown', ['$event'])\r\n handleEnter(_event: KeyboardEvent) {\r\n if(_event.key !== 'Enter') return\r\n if (!this.codsuc) {\r\n return\r\n }\r\n this.goMain()\r\n }\r\n\r\n goMain = () => {\r\n this.loginEvent.emit({type: \"BRANCH\", data: { codsuc: this.codsuc() }})\r\n }\r\n}\r\n","<div class=\"auth-wrapper-login\">\r\n @let produccion = production();\r\n <div class=\"auth-panel-left\" [class.auth-panel-left--dev]=\"!produccion\">\r\n <span class=\"auth-blob auth-blob-1\"></span>\r\n <span class=\"auth-blob auth-blob-2\"></span>\r\n <span class=\"auth-blob auth-blob-3\"></span>\r\n <span class=\"auth-blob auth-blob-4\"></span>\r\n\r\n <div class=\"auth-brand-panel\">\r\n <div class=\"auth-brand-logo\">\r\n <img src=\"assets/images/logo-tsi-tres.png\" alt=\"TSI\" />\r\n </div>\r\n <h1 class=\"auth-brand-title\">{{module()}}</h1>\r\n <p class=\"auth-brand-subtitle\">Selecciona la sucursal desde donde vas a operar hoy</p>\r\n\r\n <div class=\"auth-brand-divider\"></div>\r\n\r\n <div class=\"auth-brand-features\">\r\n <div class=\"auth-brand-feature\">\r\n <span class=\"feat-dot\"></span> Acceso segmentado por sucursal\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"auth-panel-right\" [class.auth-panel-right--dev]=\"!produccion\">\r\n <div class=\"auth-panel-bg\">\r\n <span class=\"auth-deco auth-deco-tl\"></span>\r\n <span class=\"auth-deco auth-deco-br\"></span>\r\n </div>\r\n\r\n <div class=\"auth-form-wrapper\">\r\n <div>\r\n @if (!produccion) {\r\n <div>\r\n <span class=\"auth-test-badge\">\r\n <span class=\"badge-dot\"></span> ENTORNO DE PRUEBAS\r\n </span>\r\n </div>\r\n }\r\n\r\n <div class=\"auth-card\">\r\n <h2 class=\"auth-card-title\">Seleccionar sucursal</h2>\r\n <p class=\"auth-card-subtitle\">{{title()}}</p>\r\n\r\n <select class=\"auth-select\" [(ngModel)]=\"codsuc\">\r\n @for (suc of sucursalesList(); track $index) {\r\n <option [value]=\"suc.codsuc\">{{suc.sucursal}}</option>\r\n }\r\n </select>\r\n\r\n <button class=\"auth-btn\" [class.auth-btn--red]=\"!produccion\" (click)=\"goMain()\">\r\n Continuar\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>","export class AuthSender {\r\n ruc?: string\r\n coduser?: string\r\n clave?: string\r\n nuevaclave?: string\r\n producto?: string\r\n codsuc?: number\r\n}","/*\n * Public API Surface of login-tsi\n */\n\nexport * from './lib/components/auth/auth.component';\nexport * from './lib/components/expired-password/expired-password.component';\nexport * from './lib/components/recover-password/recover-password.component';\nexport * from './lib/components/select-branch/select-branch.component';\nexport * from './lib/models/auth-sender';\nexport * from './lib/models/login-event';\nexport * from './lib/models/login-type-event';\n\n// PWA (instalación, guía, actualización/refresh forzado)\nexport * from './lib/components/pwa-floating/pwa-floating.component';\nexport * from './lib/components/refresh-floating/refresh-floating.component';\nexport * from './lib/pwa-install.service';\nexport * from './lib/models/verificar-mfa';\nexport * from './lib/models/auth-api';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"login-tsi.mjs","sources":["../../../projects/login-tsi/src/lib/utils/animations.ts","../../../projects/login-tsi/src/lib/models/auth-api.ts","../../../projects/login-tsi/src/lib/utils/mensaje-error.ts","../../../projects/login-tsi/src/lib/models/verificar-mfa.ts","../../../projects/login-tsi/src/lib/pwa-install.service.ts","../../../projects/login-tsi/src/lib/components/pwa-floating/pwa-floating.component.ts","../../../projects/login-tsi/src/lib/components/pwa-floating/pwa-floating.component.html","../../../projects/login-tsi/src/lib/components/refresh-floating/refresh-floating.component.ts","../../../projects/login-tsi/src/lib/components/refresh-floating/refresh-floating.component.html","../../../projects/login-tsi/src/lib/components/md-verificar-mfa/md-verificar-mfa.component.ts","../../../projects/login-tsi/src/lib/components/md-verificar-mfa/md-verificar-mfa.component.html","../../../projects/login-tsi/src/lib/components/auth/auth.component.ts","../../../projects/login-tsi/src/lib/components/auth/auth.component.html","../../../projects/login-tsi/src/lib/components/expired-password/expired-password.component.ts","../../../projects/login-tsi/src/lib/components/expired-password/expired-password.component.html","../../../projects/login-tsi/src/lib/components/recover-password/recover-password.component.ts","../../../projects/login-tsi/src/lib/components/recover-password/recover-password.component.html","../../../projects/login-tsi/src/lib/components/select-branch/select-branch.component.ts","../../../projects/login-tsi/src/lib/components/select-branch/select-branch.component.html","../../../projects/login-tsi/src/lib/models/auth-sender.ts","../../../projects/login-tsi/src/public-api.ts","../../../projects/login-tsi/src/login-tsi.ts"],"sourcesContent":["import { animate, style, transition, trigger } from \"@angular/animations\";\r\n\r\nexport const fadeInOut = trigger('fadeInOut', [\r\n transition(':enter', [\r\n style({ opacity: 0, transform: 'translateY(-5px)' }),\r\n animate('200ms ease-out', style({ opacity: 1, transform: 'translateY(0)' })),\r\n ]),\r\n transition(':leave', [\r\n animate('200ms ease-in', style({ opacity: 0, transform: 'translateY(-5px)' })),\r\n ]),\r\n ])","import { InjectionToken, Provider, Type } from '@angular/core'\nimport { AuthSender } from './auth-sender'\nimport { MfaChallengeResponse, MfaEstadoPush, MfaLoginSender, PushSolicitudInicio } from './verificar-mfa'\n\nexport interface AuthApi {\n login(sender: AuthSender): Promise<MfaChallengeResponse | void>\n verificarCodigo(sender: MfaLoginSender): Promise<void>\n enviarPush(preauthToken: string): Promise<PushSolicitudInicio>\n estadoPush(sender: MfaLoginSender): Promise<MfaEstadoPush>\n}\n\nexport const AUTH_API = new InjectionToken<AuthApi>('AUTH_API')\n\nexport function provideAuthApi(servicio: Type<AuthApi>): Provider {\n return { provide: AUTH_API, useExisting: servicio }\n}\n","const textoValido = (valor: unknown): valor is string => typeof valor == 'string' && !!valor.trim()\n\nexport const mensajeDe = (err: unknown, defecto: string): string => {\n if (textoValido(err)) return err\n if (err && typeof err == 'object' && 'error' in err) {\n const body = (err as { error: unknown }).error\n if (textoValido(body)) return body\n const mensaje = (body as { message?: unknown })?.message\n return textoValido(mensaje) ? mensaje : defecto\n }\n const mensaje = (err as { message?: unknown })?.message\n return textoValido(mensaje) && !/^\\d+$/.test(mensaje) ? mensaje : defecto\n}\n","export interface MfaChallengeResponse {\n mfaRequerido: boolean\n preauthToken: string\n coduser?: string\n empresa?: string\n mensaje?: string\n tipos?: string[]\n}\n\nexport interface MfaLoginSender {\n preauthToken: string\n codigo?: string\n solicitudId?: string\n}\n\nexport interface PushSolicitudInicio {\n solicitudId: string\n numberMatching: number\n}\n\nexport interface MfaPushEstadoPendiente {\n result: 'waiting' | 'deny' | 'expired'\n}\n\nexport type MfaEstadoPush = 'aprobado' | 'waiting' | 'deny' | 'expired'\n\nexport function isMfaChallenge(body: any): body is MfaChallengeResponse {\n return body?.mfaRequerido === true && !!body?.preauthToken\n}\n\nexport function isPushPendiente(body: any): body is MfaPushEstadoPendiente {\n return body?.result === 'waiting' || body?.result === 'deny' || body?.result === 'expired'\n}\n","import { Injectable, signal } from '@angular/core';\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class PwaInstallService {\r\n\r\n readonly isAndroid = /Android/i.test(navigator.userAgent)\r\n readonly isIOS = /iPad|iPhone|iPod/i.test(navigator.userAgent)\r\n readonly isSafariMac = /^((?!Chrome|Android).)*Safari/i.test(navigator.userAgent) && /Mac/i.test(navigator.platform)\r\n readonly isChrome = /Chrome|Chromium|Edg/i.test(navigator.userAgent) && !/Android/i.test(navigator.userAgent)\r\n\r\n readonly showButton = signal<boolean>(\r\n !window.matchMedia('(display-mode: standalone)').matches\r\n )\r\n readonly showGuide = signal<boolean>(false)\r\n\r\n private get deferredPrompt(): any { return (window as any).__pwaPrompt ?? null }\r\n\r\n get canAutoInstall(): boolean { return !!this.deferredPrompt }\r\n\r\n async tryInstall(): Promise<void> {\r\n const prompt = this.deferredPrompt\r\n if (!prompt) return\r\n prompt.prompt()\r\n const { outcome } = await prompt.userChoice\r\n if (outcome === 'accepted') this.showButton.set(false)\r\n else (window as any).__pwaPrompt = null\r\n }\r\n\r\n toggleGuide() { this.showGuide.update(v => !v) }\r\n\r\n markAsAdded() {\r\n this.showGuide.set(false)\r\n this.showButton.set(false)\r\n }\r\n}\r\n","import { Component, inject, input, output } from '@angular/core';\r\nimport { PwaInstallService } from '../../pwa-install.service';\r\n\r\n@Component({\r\n selector: 'app-pwa-floating',\r\n templateUrl: './pwa-floating.component.html',\r\n styleUrl: './pwa-floating.component.scss'\r\n})\r\n\r\nexport class PwaFloatingComponent {\r\n\r\n readonly pwa = inject(PwaInstallService)\r\n\r\n appName = input<string>('ERP TSI')\r\n logo = input<string>('assets/images/logo-tsi-tres.png')\r\n chipLabel = input<string>('Instalar app')\r\n\r\n beforeInstall = output<void>()\r\n guideClosed = output<void>()\r\n\r\n onChipClick() {\r\n if (!this.pwa.showGuide()) {\r\n this.beforeInstall.emit()\r\n } else {\r\n this.guideClosed.emit()\r\n }\r\n this.pwa.toggleGuide()\r\n }\r\n\r\n onCloseGuide() {\r\n this.guideClosed.emit()\r\n this.pwa.toggleGuide()\r\n }\r\n\r\n onMarkAsAdded() {\r\n this.guideClosed.emit()\r\n this.pwa.markAsAdded()\r\n }\r\n\r\n}\r\n","@if (pwa.showButton()) {\r\n<div class=\"pwa-wrap\">\r\n\r\n @if (pwa.showGuide()) {\r\n <div class=\"pwa-guide\">\r\n <button class=\"pwa-guide__close\" (click)=\"onCloseGuide()\">\r\n <i class=\"fas fa-xmark\"></i>\r\n </button>\r\n\r\n <div class=\"pwa-guide__header\">\r\n <img [src]=\"logo()\" alt=\"\" class=\"pwa-guide__logo\">\r\n <div>\r\n <p class=\"pwa-guide__title\">Instalar {{ appName() }}</p>\r\n <p class=\"pwa-guide__sub\">Úsalo como una app desde tu dispositivo</p>\r\n </div>\r\n </div>\r\n\r\n @if (!pwa.canAutoInstall) {\r\n <ol class=\"pwa-guide__steps\">\r\n @if (pwa.isIOS) {\r\n <li>Toca el botón <span class=\"pwa-guide__badge\"><i class=\"fas fa-arrow-up-from-bracket\"></i></span> en la barra inferior del navegador</li>\r\n <li>Desplázate y selecciona <strong>\"En la pantalla de inicio\"</strong></li>\r\n <li>Toca <strong>\"Añadir\"</strong> en la esquina superior derecha</li>\r\n } @else if (pwa.isAndroid) {\r\n <li>Toca el menú <span class=\"pwa-guide__badge\"><i class=\"fas fa-ellipsis-vertical\"></i></span> en la esquina superior derecha</li>\r\n <li>Selecciona <strong>\"Instalar aplicación\"</strong> o <strong>\"Añadir a pantalla de inicio\"</strong></li>\r\n <li>Toca <strong>\"Instalar\"</strong> para confirmar</li>\r\n } @else if (pwa.isSafariMac) {\r\n <li>Abre el menú <strong>\"Archivo\"</strong> en la barra superior del Mac</li>\r\n <li>Selecciona <strong>\"Añadir al Dock...\"</strong></li>\r\n <li>Haz clic en <strong>\"Añadir\"</strong> para confirmar</li>\r\n } @else if (pwa.isChrome) {\r\n <li>Busca el ícono <span class=\"pwa-guide__badge\"><i class=\"fas fa-display\"></i></span> al final de la barra de direcciones</li>\r\n <li>Haz clic en él y selecciona <strong>\"Instalar\"</strong></li>\r\n <li>Confirma en el diálogo que aparece</li>\r\n } @else {\r\n <li>Abre el menú <span class=\"pwa-guide__badge\"><i class=\"fas fa-ellipsis-vertical\"></i></span> de tu navegador</li>\r\n <li>Busca <strong>\"Instalar aplicación\"</strong> o <strong>\"Añadir a pantalla de inicio\"</strong></li>\r\n <li>Confirma para instalar</li>\r\n }\r\n </ol>\r\n }\r\n\r\n @if (pwa.canAutoInstall) {\r\n <button class=\"pwa-guide__install\" (click)=\"pwa.tryInstall()\">\r\n <i class=\"fas fa-download\"></i> Instalar ahora\r\n </button>\r\n }\r\n <button class=\"pwa-guide__done\" (click)=\"onMarkAsAdded()\">\r\n <i class=\"fas fa-check\"></i> Ya lo instalé\r\n </button>\r\n </div>\r\n }\r\n\r\n <button class=\"pwa-chip\" (click)=\"onChipClick()\">\r\n <img [src]=\"logo()\" alt=\"\" class=\"pwa-chip__logo\">\r\n <span>{{ chipLabel() }}</span>\r\n </button>\r\n\r\n</div>\r\n}\r\n","import { Component, signal } from '@angular/core';\r\n\r\n@Component({\r\n selector: 'app-refresh-floating',\r\n templateUrl: './refresh-floating.component.html',\r\n styleUrl: './refresh-floating.component.scss'\r\n})\r\n\r\nexport class RefreshFloatingComponent {\r\n\r\n showGuide = signal<boolean>(false)\r\n\r\n toggleGuide() {\r\n this.showGuide.update(v => !v)\r\n }\r\n\r\n actualizar() {\r\n window.location.reload()\r\n }\r\n\r\n async actualizarTotal() {\r\n if ('serviceWorker' in navigator) {\r\n const registrations = await navigator.serviceWorker.getRegistrations()\r\n await Promise.all(registrations.map(r => r.unregister()))\r\n }\r\n if ('caches' in window) {\r\n const names = await caches.keys()\r\n await Promise.all(names.map(name => caches.delete(name)))\r\n }\r\n window.location.href = window.location.pathname + '?_r=' + Date.now()\r\n }\r\n}\r\n","<div class=\"refresh-wrap\">\r\n\r\n @if (showGuide()) {\r\n <div class=\"refresh-guide\">\r\n <button class=\"refresh-guide__close\" (click)=\"toggleGuide()\">\r\n <i class=\"fas fa-xmark\"></i>\r\n </button>\r\n\r\n <p class=\"refresh-guide__title\">Actualizar aplicación</p>\r\n\r\n <button class=\"refresh-guide__option\" (click)=\"actualizar()\">\r\n <i class=\"fas fa-rotate\"></i> Actualizar\r\n </button>\r\n\r\n <button class=\"refresh-guide__option refresh-guide__option--force\" (click)=\"actualizarTotal()\">\r\n <i class=\"fas fa-rotate-right\"></i> Forzar actualización\r\n </button>\r\n </div>\r\n }\r\n\r\n <button class=\"refresh-chip\" (click)=\"toggleGuide()\" title=\"Actualizar\">\r\n <i class=\"fas fa-rotate\"></i>\r\n </button>\r\n\r\n</div>\r\n","import { afterRenderEffect, Component, computed, DestroyRef, effect, ElementRef, inject, input, output, signal, untracked, viewChild } from '@angular/core';\nimport { MfaChallengeResponse, MfaEstadoPush } from '../../models/verificar-mfa';\nimport { AUTH_API } from '../../models/auth-api';\nimport { mensajeDe } from '../../utils/mensaje-error';\n\ntype ModoVerificacion = 'codigo' | 'push'\ntype TipoCodigo = 'totp' | 'respaldo'\ntype EstadoPush = 'idle' | 'enviando' | 'esperando' | 'rechazado' | 'expirado'\n\nconst INTERVALO_ESTADO_MS = 2000\nconst MAXIMO_ESPERA_MS = 120000\n\ninterface CampoCodigo {\n label: string\n placeholder: string\n descri: string\n icon: string\n inputmode: string\n patron: RegExp\n mensajeInvalido: string\n mensajeIncorrecto: string\n}\n\nconst CAMPOS_CODIGO: Record<TipoCodigo, CampoCodigo> = {\n totp: {\n label: 'Código de verificación', placeholder: '000000', icon: 'fa-mobile-alt', inputmode: 'numeric',\n patron: /^\\d{6}$/,\n descri: 'Ingresa el código de 6 dígitos que muestra tu app de autenticación.',\n mensajeInvalido: 'Ingresa el código de 6 dígitos de tu app.',\n mensajeIncorrecto: 'Código incorrecto. Verifica la hora de tu dispositivo.'\n },\n respaldo: {\n label: 'Código de respaldo', placeholder: 'XXXX-XXXX', icon: 'fa-key', inputmode: 'text',\n patron: /^[A-Z0-9]{4}-[A-Z0-9]{4}$/,\n descri: 'Ingresa uno de tus códigos de respaldo. Cada código sirve una sola vez.',\n mensajeInvalido: 'Ingresa un código de respaldo válido (XXXX-XXXX).',\n mensajeIncorrecto: 'Código de respaldo incorrecto o ya utilizado.'\n }\n}\n\nconst limpiarCodigo = (valor: string, tipo: TipoCodigo) => {\n if (tipo == 'totp') return valor.replace(/\\D/g, '').slice(0, 6)\n const base = valor.toUpperCase().replace(/[^A-Z0-9]/g, '').slice(0, 8)\n return base.length > 4 ? `${base.slice(0, 4)}-${base.slice(4)}` : base\n}\n\n\nconst esperar = (ms: number, signal: AbortSignal) => new Promise<void>(resolve => {\n const id = setTimeout(resolve, ms)\n signal.addEventListener('abort', () => { clearTimeout(id); resolve() }, { once: true })\n})\n\n@Component({\n selector: 'lib-md-verificar-mfa',\n templateUrl: './md-verificar-mfa.component.html',\n styleUrls: ['./md-verificar-mfa.component.scss', '../auth.scss']\n})\nexport class MdVerificarMfaComponent {\n\n private api = inject(AUTH_API)\n\n challenge = input.required<MfaChallengeResponse>()\n titulo = input<string>('Verificación en dos pasos')\n showCancelar = input<boolean>(true)\n\n verificado = output<void>()\n cancelado = output<void>()\n\n tienePush = computed(() => (this.challenge().tipos ?? []).includes('PUSH'))\n tieneTotp = computed(() => {\n const tipos = this.challenge().tipos ?? []\n return tipos.length == 0 || tipos.includes('TOTP')\n })\n\n modo = signal<ModoVerificacion>('codigo')\n tipoCodigo = signal<TipoCodigo>('totp')\n campo = computed(() => CAMPOS_CODIGO[this.tipoCodigo()])\n\n codigo = signal<string>('')\n codigoError = signal<string>('')\n isEnviando = signal<boolean>(false)\n\n estadoPush = signal<EstadoPush>('idle')\n isPushEnCurso = computed(() => this.estadoPush() == 'enviando' || this.estadoPush() == 'esperando')\n pushError = signal<string>('')\n numberMatching = signal<number | null>(null)\n\n private inputCodigo = viewChild<ElementRef<HTMLInputElement>>('inputCodigo')\n private pushCtrl?: AbortController\n\n constructor() {\n inject(DestroyRef).onDestroy(() => this.cancelarPush())\n\n effect(() => {\n this.challenge()\n untracked(() => this.iniciar())\n })\n\n afterRenderEffect(() => {\n if (this.modo() != 'codigo' || this.isEnviando()) return\n this.tipoCodigo()\n this.codigoError()\n this.inputCodigo()?.nativeElement.focus()\n })\n }\n\n private iniciar() {\n this.cancelarPush()\n this.pushError.set('')\n if (this.tienePush() && !this.tieneTotp()) {\n this.usarPush()\n return\n }\n this.usarCodigo('totp')\n }\n\n onCodigoInput(event: Event) {\n const input = event.target as HTMLInputElement\n const limpio = limpiarCodigo(input.value, this.tipoCodigo())\n input.value = limpio\n this.codigo.set(limpio)\n if (this.codigoError()) this.codigoError.set('')\n }\n\n usarCodigo(tipo: TipoCodigo) {\n this.cancelarPush()\n this.modo.set('codigo')\n this.tipoCodigo.set(tipo)\n this.codigo.set('')\n this.codigoError.set('')\n }\n\n async verificar() {\n if (this.modo() == 'push' || this.isEnviando()) return\n const campo = this.campo()\n if (!campo.patron.test(this.codigo())) {\n this.codigoError.set(campo.mensajeInvalido)\n return\n }\n this.isEnviando.set(true)\n this.codigoError.set('')\n try {\n await this.api.verificarCodigo({ preauthToken: this.challenge().preauthToken, codigo: this.codigo() })\n this.verificado.emit()\n } catch (err) {\n this.codigo.set('')\n this.codigoError.set(mensajeDe(err, campo.mensajeIncorrecto))\n } finally {\n this.isEnviando.set(false)\n }\n }\n\n usarPush() {\n this.modo.set('push')\n this.codigoError.set('')\n this.enviarPush()\n }\n\n async enviarPush() {\n this.cancelarPush()\n const ctrl = new AbortController()\n this.pushCtrl = ctrl\n this.pushError.set('')\n this.estadoPush.set('enviando')\n this.numberMatching.set(null)\n const preauthToken = this.challenge().preauthToken\n\n try {\n const { solicitudId, numberMatching } = await this.api.enviarPush(preauthToken)\n if (ctrl.signal.aborted) return\n this.numberMatching.set(numberMatching ?? null)\n this.estadoPush.set('esperando')\n\n const limite = Date.now() + MAXIMO_ESPERA_MS\n while (Date.now() < limite) {\n const estado = await this.api.estadoPush({ preauthToken, solicitudId })\n if (ctrl.signal.aborted) return\n if (estado != 'waiting') {\n this.resolverPush(estado)\n return\n }\n await esperar(INTERVALO_ESTADO_MS, ctrl.signal)\n if (ctrl.signal.aborted) return\n }\n this.numberMatching.set(null)\n this.estadoPush.set('expirado')\n this.pushError.set('No respondiste a tiempo la notificación. Vuelve a enviarla.')\n } catch (err) {\n if (ctrl.signal.aborted) return\n this.estadoPush.set('idle')\n this.pushError.set(mensajeDe(err, 'No se pudo enviar la notificación.'))\n }\n }\n\n cancelar() {\n this.cancelarPush()\n this.cancelado.emit()\n }\n\n private resolverPush(estado: Exclude<MfaEstadoPush, 'waiting'>) {\n this.numberMatching.set(null)\n if (estado == 'aprobado') {\n this.estadoPush.set('idle')\n this.verificado.emit()\n return\n }\n if (estado == 'expired') {\n this.estadoPush.set('expirado')\n this.pushError.set('La solicitud expiró. Vuelve a enviarla.')\n return\n }\n this.estadoPush.set('rechazado')\n this.pushError.set('Rechazaste la notificación en tu teléfono.')\n }\n\n private cancelarPush() {\n this.pushCtrl?.abort()\n this.pushCtrl = undefined\n this.numberMatching.set(null)\n if (this.isPushEnCurso()) this.estadoPush.set('idle')\n }\n\n}\n","<div class=\"verificar-mfa\">\n <div class=\"auth-card-title mb-3\">{{ titulo() }}</div>\n\n <div class=\"d-flex align-items-center gap-3 mb-3\">\n <span class=\"verificar-mfa__icono\"><i class=\"fas fa-user-shield\"></i></span>\n <div>\n <div class=\"fw-semibold\">{{ challenge().coduser }}</div>\n @if (challenge().empresa) {\n <div class=\"verificar-mfa__muted\">{{ challenge().empresa }}</div>\n }\n </div>\n </div>\n\n @if (modo() == 'push') {\n @switch (estadoPush()) {\n @case ('enviando') {\n <div class=\"duo-push\">\n <span class=\"spinner-border spinner-border-sm text-primary\"></span>\n <div class=\"flex-grow-1\">Enviando notificación a tu teléfono…</div>\n </div>\n }\n @case ('esperando') {\n <div class=\"duo-push duo-push--esperando\">\n <span class=\"duo-push__icono duo-push__icono--pulso\"><i class=\"fas fa-mobile-alt\"></i></span>\n <div class=\"flex-grow-1\">\n <div class=\"fw-semibold\">Revisa tu teléfono</div>\n <div class=\"verificar-mfa__muted\">Aprueba la notificación en TSI Autenticador para ingresar.</div>\n </div>\n </div>\n @if (numberMatching() != null) {\n <div class=\"number-matching\" role=\"status\" aria-live=\"polite\">\n <div class=\"verificar-mfa__muted\">Confirma que tu teléfono muestre este número</div>\n <div class=\"number-matching__valor\">{{ numberMatching() }}</div>\n </div>\n }\n }\n @default {\n <div class=\"duo-push\">\n <span class=\"duo-push__icono\"><i class=\"fas fa-bell\"></i></span>\n <div class=\"flex-grow-1\">\n <div class=\"fw-semibold\">TSI Autenticador</div>\n <div class=\"verificar-mfa__muted\">Te enviaremos una notificación para que la apruebes.</div>\n </div>\n </div>\n }\n }\n @if (pushError() && !isPushEnCurso()) {\n <div class=\"codigo-field__error\"><i class=\"fas fa-exclamation-circle\"></i> {{ pushError() }}</div>\n }\n\n <div class=\"verificar-mfa__opciones\">\n @if (tieneTotp()) {\n <button type=\"button\" class=\"verificar-mfa__link\" (click)=\"usarCodigo('totp')\">\n Usar código de mi app de autenticación\n </button>\n }\n <button type=\"button\" class=\"verificar-mfa__link verificar-mfa__link--secundario\"\n (click)=\"usarCodigo('respaldo')\">\n ¿No tienes tu teléfono? Usa un código de respaldo\n </button>\n </div>\n } @else {\n <p class=\"verificar-mfa__muted mb-4\">\n @if (tipoCodigo() == 'totp') {\n {{ challenge().mensaje || campo().descri }}\n } @else {\n {{ campo().descri }}\n }\n </p>\n\n <div class=\"codigo-field\" [class.has-error]=\"codigoError()\">\n <span class=\"codigo-field__icon\"><i class=\"fas\" [class]=\"campo().icon\"></i></span>\n <input #inputCodigo id=\"mfa-codigo\" class=\"codigo-field__input\" type=\"text\"\n [placeholder]=\"campo().placeholder\" [value]=\"codigo()\" (input)=\"onCodigoInput($event)\"\n (keydown.enter)=\"verificar()\" [attr.inputmode]=\"campo().inputmode\" autocomplete=\"one-time-code\"\n autocorrect=\"off\" autocapitalize=\"characters\" spellcheck=\"false\" [disabled]=\"isEnviando()\">\n <label for=\"mfa-codigo\" class=\"codigo-field__label\">{{ campo().label }}</label>\n </div>\n @if (codigoError()) {\n <div class=\"codigo-field__error\"><i class=\"fas fa-exclamation-circle\"></i> {{ codigoError() }}</div>\n }\n\n <div class=\"verificar-mfa__opciones\">\n @if (tienePush()) {\n <button type=\"button\" class=\"verificar-mfa__link\" (click)=\"usarPush()\">\n <i class=\"fas fa-bell me-1\"></i>Mejor envíame una notificación push\n </button>\n }\n @if (tieneTotp() && tipoCodigo() != 'totp') {\n <button type=\"button\" class=\"verificar-mfa__link\" (click)=\"usarCodigo('totp')\">\n Usar código de mi app de autenticación\n </button>\n }\n @if (tipoCodigo() != 'respaldo') {\n <button type=\"button\" class=\"verificar-mfa__link verificar-mfa__link--secundario\"\n (click)=\"usarCodigo('respaldo')\">\n ¿No tienes tu teléfono? Usa un código de respaldo\n </button>\n }\n </div>\n }\n\n <div class=\"verificar-mfa__acciones\">\n @if (modo() == 'push') {\n <button type=\"button\" class=\"auth-btn\" [disabled]=\"isPushEnCurso()\" (click)=\"enviarPush()\">\n <i class=\"fas fa-paper-plane me-1\"></i>\n {{ isPushEnCurso() ? 'Esperando aprobación…' : 'Reenviar notificación' }}\n </button>\n } @else {\n <button type=\"button\" class=\"auth-btn\" [disabled]=\"isEnviando()\" (click)=\"verificar()\">\n <i class=\"fas fa-check me-1\"></i>\n {{ isEnviando() ? 'Verificando…' : 'Verificar' }}\n </button>\n }\n @if (showCancelar()) {\n <button type=\"button\" class=\"auth-btn auth-btn--outline\" (click)=\"cancelar()\">Cancelar</button>\n }\n </div>\n</div>\n","import { NgClass } from '@angular/common';\r\nimport { Component, ElementRef, inject, input, output, signal, viewChild } from '@angular/core';\r\nimport { FormGroup, ReactiveFormsModule } from '@angular/forms';\r\nimport { AuthSender } from '../../models/auth-sender';\r\nimport { fadeInOut } from '../../utils/animations';\r\nimport { LoginEvent } from '../../models/login-event';\r\nimport { AUTH_API } from '../../models/auth-api';\r\nimport { mensajeDe } from '../../utils/mensaje-error';\r\nimport { isMfaChallenge, MfaChallengeResponse } from '../../models/verificar-mfa';\r\nimport { PwaFloatingComponent } from '../pwa-floating/pwa-floating.component';\r\nimport { RefreshFloatingComponent } from '../refresh-floating/refresh-floating.component';\r\nimport { MdVerificarMfaComponent } from '../md-verificar-mfa/md-verificar-mfa.component';\r\n\r\ninterface PasoMfa {\r\n challenge: MfaChallengeResponse\r\n data: AuthSender\r\n}\r\n\r\nconst MENSAJE_ERROR_LOGIN = 'No se pudo iniciar sesión.'\r\nconst CLASE_CERRANDO = 'auth-mfa-dialog--cerrando'\r\nconst MAXIMO_SALIDA_MS = 400\r\n\r\n@Component({\r\n selector: 'lib-auth-tsi',\r\n imports: [NgClass, ReactiveFormsModule, PwaFloatingComponent, RefreshFloatingComponent, MdVerificarMfaComponent],\r\n templateUrl: './auth.component.html',\r\n styleUrls: ['./auth.component.scss', '../auth.scss'],\r\n animations: [fadeInOut]\r\n})\r\nexport class AuthComponent {\r\n\r\n private api = inject(AUTH_API, { optional: true })\r\n\r\n production = input<boolean>(true)\r\n module = input<string>('ERP')\r\n versionApp = input<string>('1.0.0')\r\n product = input<string>()\r\n authForm = input.required<FormGroup>();\r\n\r\n aboutList = input<string[]>([\r\n 'Gestión de compras y logística',\r\n 'Control financiero avanzado',\r\n 'Reportes y análisis en tiempo real',\r\n 'Integración con inteligencia artificial'\r\n ])\r\n\r\n showFloatingApp = input<boolean>(true)\r\n showFloatingUpdate = input<boolean>(true)\r\n\r\n loginEvent = output<LoginEvent>()\r\n beforeInstall = output<void>()\r\n\r\n showPassword = signal<boolean>(false)\r\n isIngresando = signal<boolean>(false)\r\n pasoMfa = signal<PasoMfa | null>(null)\r\n\r\n private dialogMfa = viewChild.required<ElementRef<HTMLDialogElement>>('dialogMfa')\r\n\r\n onBeforeInstall = () => this.beforeInstall.emit()\r\n\r\n recover = () => this.loginEvent.emit({type: \"RECOVER\"})\r\n forget = () => this.loginEvent.emit({type: \"FORGET\"})\r\n\r\n togglePassword = () => this.showPassword.set(!this.showPassword())\r\n\r\n login = async () => {\r\n if (this.isIngresando() || !this.validacionInit()) return\r\n const data = this.armarSender()\r\n if (!this.api) {\r\n this.loginEvent.emit({type: \"LOGIN\", data})\r\n return\r\n }\r\n this.isIngresando.set(true)\r\n try {\r\n const respuesta = await this.api.login(data)\r\n if (isMfaChallenge(respuesta)) {\r\n this.abrirMfa({ challenge: respuesta, data })\r\n return\r\n }\r\n this.loginEvent.emit({type: \"AUTENTICADO\", data})\r\n } catch (err) {\r\n this.returnError(mensajeDe(err, MENSAJE_ERROR_LOGIN))\r\n } finally {\r\n this.isIngresando.set(false)\r\n }\r\n }\r\n\r\n onMfaVerificado = async () => {\r\n const paso = this.pasoMfa()\r\n await this.cerrarMfa()\r\n if (paso) this.loginEvent.emit({type: \"AUTENTICADO\", data: paso.data})\r\n }\r\n\r\n onMfaCancelado = async () => {\r\n await this.cerrarMfa()\r\n this.authForm().patchValue({ clave: '' })\r\n }\r\n\r\n private abrirMfa(paso: PasoMfa) {\r\n const dialog = this.dialogMfa().nativeElement\r\n dialog.classList.remove(CLASE_CERRANDO)\r\n this.pasoMfa.set(paso)\r\n if (!dialog.open) dialog.showModal()\r\n }\r\n\r\n private cerrarMfa() {\r\n const dialog = this.dialogMfa().nativeElement\r\n if (!dialog.open) {\r\n this.pasoMfa.set(null)\r\n return Promise.resolve()\r\n }\r\n return new Promise<void>(resolve => {\r\n let terminado = false\r\n const terminar = () => {\r\n if (terminado) return\r\n terminado = true\r\n clearTimeout(respaldo)\r\n dialog.removeEventListener('animationend', alTerminarAnimacion)\r\n dialog.close()\r\n dialog.classList.remove(CLASE_CERRANDO)\r\n this.pasoMfa.set(null)\r\n resolve()\r\n }\r\n const alTerminarAnimacion = (event: AnimationEvent) => {\r\n if (event.target == dialog) terminar()\r\n }\r\n const respaldo = setTimeout(terminar, MAXIMO_SALIDA_MS)\r\n dialog.addEventListener('animationend', alTerminarAnimacion)\r\n dialog.classList.add(CLASE_CERRANDO)\r\n })\r\n }\r\n\r\n private armarSender(): AuthSender {\r\n const dataForm = this.authForm().value\r\n return {\r\n ruc: dataForm.ruc,\r\n coduser: dataForm.nomuser,\r\n clave: btoa(dataForm.clave),\r\n producto: this.product()\r\n }\r\n }\r\n\r\n validacion(value: string) {\r\n const authForm = this.authForm()\r\n if (authForm.get(value).touched && authForm.get(value).errors) {\r\n return true\r\n }\r\n return false\r\n }\r\n\r\n validacionInit() {\r\n const dataForm = this.authForm().value\r\n const { ruc, nomuser, clave } = dataForm\r\n\r\n if (!ruc) return this.returnError('Debe ingresar un N° de RUC')\r\n if (!nomuser) return this.returnError('Debe ingresar un usuario')\r\n if (!clave) return this.returnError('Debe ingresar una contraseña')\r\n return true\r\n }\r\n\r\n returnError = (message:string) => {\r\n this.loginEvent.emit({type: \"ERROR\", message})\r\n return false\r\n }\r\n}\r\n","<div class=\"auth-wrapper-login\">\r\n @let produccion = production();\r\n <div class=\"auth-panel-left\" [class.auth-panel-left--dev]=\"!produccion\">\r\n <span class=\"auth-blob auth-blob-1\"></span>\r\n <span class=\"auth-blob auth-blob-2\"></span>\r\n <span class=\"auth-blob auth-blob-3\"></span>\r\n <span class=\"auth-blob auth-blob-4\"></span>\r\n\r\n <div class=\"auth-brand-panel\">\r\n <div class=\"auth-brand-logo\">\r\n <img src=\"assets/images/logo-tsi-tres.png\" alt=\"TSI\" />\r\n </div>\r\n <h1 class=\"auth-brand-title\">{{module()}}</h1>\r\n <p class=\"auth-brand-subtitle\">Plataforma integrada de gestión<br>empresarial</p>\r\n\r\n <div class=\"auth-brand-divider\"></div>\r\n\r\n <div class=\"auth-brand-features\">\r\n @for (item of aboutList(); track $index) {\r\n <div class=\"auth-brand-feature\">\r\n <span class=\"feat-dot\"></span> {{item}}\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"auth-panel-right\" [class.auth-panel-right--dev]=\"!produccion\">\r\n <div class=\"auth-panel-bg\">\r\n <span class=\"auth-deco auth-deco-tl\"></span>\r\n <span class=\"auth-deco auth-deco-br\"></span>\r\n </div>\r\n\r\n <div class=\"auth-form-wrapper\">\r\n <div>\r\n @if (!produccion) {\r\n <div>\r\n <span class=\"auth-test-badge\">\r\n <span class=\"badge-dot\"></span> ENTORNO DE PRUEBAS\r\n </span>\r\n </div>\r\n }\r\n\r\n <div class=\"auth-card\">\r\n <h2 class=\"auth-card-title\">Bienvenido de vuelta</h2>\r\n <p class=\"auth-card-subtitle\">Ingresa tus credenciales para continuar</p>\r\n\r\n <form [formGroup]=\"authForm()\" id=\"loginform\">\r\n\r\n <p class=\"auth-hint\">\r\n <i class=\"fas fa-circle-info\"></i>\r\n Si piensas instalar la app, te recomendamos completar el RUC y Usuario antes, estos quedarán guardados y siempre aparecerán completos al abrirla.\r\n </p>\r\n\r\n <div class=\"auth-field\" [class.has-error]=\"validacion('ruc')\">\r\n <span class=\"auth-field-icon\"><i class=\"fas fa-building\"></i></span>\r\n <input type=\"text\" formControlName=\"ruc\" class=\"auth-input\" placeholder=\" \" maxlength=\"11\"\r\n id=\"f-ruc\" autocomplete=\"off\">\r\n <label for=\"f-ruc\" class=\"auth-label\">RUC</label>\r\n </div>\r\n @if (validacion('ruc')) {\r\n <p class=\"auth-error\" @fadeInOut>Ingresar RUC</p>\r\n }\r\n\r\n <div class=\"auth-field\" [class.has-error]=\"validacion('nomuser')\">\r\n <span class=\"auth-field-icon\"><i class=\"fas fa-user\"></i></span>\r\n <input type=\"text\" formControlName=\"nomuser\" class=\"auth-input\" placeholder=\" \" id=\"f-user\"\r\n autocomplete=\"off\">\r\n <label for=\"f-user\" class=\"auth-label\">Usuario</label>\r\n </div>\r\n @if (validacion('nomuser')) {\r\n <p class=\"auth-error\" @fadeInOut>Ingresar usuario</p>\r\n }\r\n\r\n <div class=\"auth-field\" [class.has-error]=\"validacion('clave')\">\r\n <span class=\"auth-field-icon\"><i class=\"fas fa-lock\"></i></span>\r\n <input [type]=\"showPassword() ? 'text' : 'password'\" formControlName=\"clave\"\r\n class=\"auth-input\" placeholder=\" \" id=\"f-clave\" autocomplete=\"off\" autocorrect=\"off\"\r\n autocapitalize=\"off\" spellcheck=\"false\">\r\n <label for=\"f-clave\" class=\"auth-label\">Contraseña</label>\r\n <button type=\"button\" class=\"auth-toggle-pw\" (click)=\"togglePassword()\">\r\n <i [class]=\"showPassword() ? 'fas fa-eye' : 'fas fa-eye-slash'\"></i>\r\n </button>\r\n </div>\r\n @if (validacion('clave')) {\r\n <p class=\"auth-error\" @fadeInOut>Ingresar clave</p>\r\n }\r\n\r\n <button class=\"auth-btn mt-2\" [class.auth-btn--red]=\"!produccion\" [disabled]=\"isIngresando()\"\r\n (click)=\"login()\">\r\n {{ isIngresando() ? 'Ingresando…' : 'Ingresar' }}\r\n </button>\r\n\r\n <div class=\"auth-links\">\r\n <a [ngClass]=\"produccion ? 'blue_contrasena' : 'red_contrasena'\"\r\n (click)=\"recover()\">¿Olvidaste tu contraseña?</a>\r\n <a [ngClass]=\"produccion ? 'blue_contrasena' : 'red_contrasena'\"\r\n (click)=\"forget()\">¿Contraseña vencida?</a>\r\n </div>\r\n\r\n </form>\r\n\r\n <div class=\"auth-version\">\r\n <span>v{{versionApp()}}</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<dialog #dialogMfa class=\"auth-mfa-dialog\" (cancel)=\"$event.preventDefault()\">\r\n @if (pasoMfa(); as paso) {\r\n <lib-md-verificar-mfa [challenge]=\"paso.challenge\" (verificado)=\"onMfaVerificado()\"\r\n (cancelado)=\"onMfaCancelado()\" />\r\n }\r\n</dialog>\r\n\r\n@if (showFloatingApp()) {\r\n<app-pwa-floating [appName]=\"module()\" (beforeInstall)=\"onBeforeInstall()\" />\r\n}\r\n@if (showFloatingUpdate()) {\r\n<app-refresh-floating />\r\n}","import { Component, inject, input, output, signal } from '@angular/core';\r\nimport { AbstractControl, FormBuilder, ReactiveFormsModule, Validators } from '@angular/forms';\r\nimport { AuthSender } from '../../models/auth-sender';\r\nimport { fadeInOut } from '../../utils/animations';\r\nimport { LoginEvent } from '../../models/login-event';\r\n\r\n@Component({\r\n selector: 'lib-expired-password',\r\n imports: [ReactiveFormsModule],\r\n templateUrl: './expired-password.component.html',\r\n styleUrls: ['./expired-password.component.scss', '../auth.scss'],\r\n animations: [fadeInOut]\r\n})\r\nexport class ExpiredPasswordComponent {\r\n\r\n private readonly fb = inject(FormBuilder)\r\n\r\n production = input<boolean>(true)\r\n module = input<string>('ERP') // DEFECTO ERP\r\n\r\n loginEvent = output<LoginEvent>()\r\n\r\n passwordVisibility = signal({\r\n claveAntigua: false,\r\n claveNueva: false,\r\n claveNuevaConfirmar: false\r\n })\r\n\r\n expiredForm = this.fb.group({\r\n ruc: ['', [Validators.required, Validators.minLength(11), Validators.maxLength(11)]],\r\n coduser: ['', Validators.required],\r\n claveAntigua: ['', [Validators.required, Validators.maxLength(20)]],\r\n claveNueva: ['', [\r\n Validators.required,\r\n Validators.minLength(8),\r\n this.regexValidator(/[a-z]/, { minuscula: true }),\r\n this.regexValidator(/[A-Z]/, { mayuscula: true }),\r\n this.regexValidator(/[0-9]/, { numero: true }),\r\n this.regexValidator(/[!@#$%^&*(),.?\":{}|<>]/, { especial: true })\r\n ]],\r\n claveNuevaConfirmar: ['', Validators.required]\r\n }, {\r\n validators: this.validatePassword('claveNueva', 'claveNuevaConfirmar')\r\n })\r\n\r\n regexValidator(regex: RegExp, error: any) {\r\n return (control: AbstractControl) => {\r\n if (!control.value) return null\r\n return regex.test(control.value) ? null : error\r\n }\r\n }\r\n\r\n validatePassword(pass1: string, pass2: string) {\r\n return (formGroup: AbstractControl) => {\r\n const c1 = formGroup.get(pass1)?.value\r\n const c2 = formGroup.get(pass2)?.value\r\n if (c1 != c2) {\r\n formGroup.get(pass2)?.setErrors({ coinciden: true })\r\n return { coinciden: true }\r\n }\r\n return null\r\n }\r\n }\r\n\r\n togglePassword(field: 'claveAntigua' | 'claveNueva' | 'claveNuevaConfirmar') {\r\n this.passwordVisibility.update(vis => ({ ...vis, [field]: !vis[field] }));\r\n }\r\n\r\n recover = () => {\r\n if (this.expiredForm.invalid) {\r\n this.loginEvent.emit({type: \"ERROR\", message: 'Debes completar todos los campos y cumplir los requisitos.'})\r\n return\r\n }\r\n \r\n const values = this.expiredForm.value\r\n const sender: AuthSender = {\r\n ruc: values.ruc!,\r\n coduser: values.coduser!,\r\n clave: values.claveAntigua!,\r\n nuevaclave: values.claveNueva!\r\n }\r\n this.loginEvent.emit({ type: \"FORGET\", data: sender })\r\n }\r\n\r\n back = () => {\r\n this.expiredForm.reset()\r\n this.loginEvent.emit({ type: \"BACK\" })\r\n }\r\n}\r\n","<div class=\"auth-wrapper-login\">\r\n @let produccion = production();\r\n <div class=\"auth-panel-left\" [class.auth-panel-left--dev]=\"!produccion\">\r\n <span class=\"auth-blob auth-blob-1\"></span>\r\n <span class=\"auth-blob auth-blob-2\"></span>\r\n <span class=\"auth-blob auth-blob-3\"></span>\r\n <span class=\"auth-blob auth-blob-4\"></span>\r\n\r\n <div class=\"auth-brand-panel\">\r\n <div class=\"auth-brand-logo\">\r\n <img src=\"assets/images/logo-tsi-tres.png\" alt=\"TSI\" />\r\n </div>\r\n <h1 class=\"auth-brand-title\">{{module()}}</h1>\r\n <p class=\"auth-brand-subtitle\">Renueva tu contraseña y mantén tu cuenta segura</p>\r\n\r\n <div class=\"auth-brand-divider\"></div>\r\n\r\n <div class=\"auth-brand-features\">\r\n <div class=\"auth-brand-feature\">\r\n <span class=\"feat-dot\"></span> Mínimo 8 caracteres\r\n </div>\r\n <div class=\"auth-brand-feature\">\r\n <span class=\"feat-dot\"></span> Letras mayúsculas y minúsculas\r\n </div>\r\n <div class=\"auth-brand-feature\">\r\n <span class=\"feat-dot\"></span> Al menos un número y símbolo\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"auth-panel-right\" [class.auth-panel-right--dev]=\"!produccion\">\r\n <div class=\"auth-panel-bg\">\r\n <span class=\"auth-deco auth-deco-tl\"></span>\r\n <span class=\"auth-deco auth-deco-br\"></span>\r\n </div>\r\n\r\n <div class=\"auth-form-wrapper\">\r\n <div>\r\n @if (!produccion) {\r\n <div>\r\n <span class=\"auth-test-badge\">\r\n <span class=\"badge-dot\"></span> ENTORNO DE PRUEBAS\r\n </span>\r\n </div>\r\n }\r\n\r\n <div class=\"auth-card\">\r\n <h2 class=\"auth-card-title\">Renovar contraseña</h2>\r\n <p class=\"auth-card-subtitle\">Proporciona tus datos y elige una nueva clave</p>\r\n\r\n <form [formGroup]=\"expiredForm\">\r\n\r\n <div class=\"auth-field\"\r\n [class.has-error]=\"expiredForm.get('ruc')?.invalid && expiredForm.get('ruc')?.touched\">\r\n <span class=\"auth-field-icon\"><i class=\"fas fa-building\"></i></span>\r\n <input type=\"text\" class=\"auth-input\" placeholder=\" \" maxlength=\"11\"\r\n formControlName=\"ruc\" id=\"exp-ruc\" onlyNumber autocomplete=\"off\">\r\n <label for=\"exp-ruc\" class=\"auth-label\">RUC</label>\r\n </div>\r\n @if (expiredForm.get('ruc')?.invalid && expiredForm.get('ruc')?.touched) {\r\n <p class=\"auth-error\" @fadeInOut>RUC debe tener 11 dígitos</p>\r\n }\r\n\r\n <div class=\"auth-field\"\r\n [class.has-error]=\"expiredForm.get('coduser')?.invalid && expiredForm.get('coduser')?.touched\">\r\n <span class=\"auth-field-icon\"><i class=\"fas fa-user\"></i></span>\r\n <input type=\"text\" class=\"auth-input\" placeholder=\" \"\r\n formControlName=\"coduser\" id=\"exp-user\" autocomplete=\"off\">\r\n <label for=\"exp-user\" class=\"auth-label\">Usuario</label>\r\n </div>\r\n @if (expiredForm.get('coduser')?.invalid && expiredForm.get('coduser')?.touched) {\r\n <p class=\"auth-error\" @fadeInOut>El usuario es obligatorio</p>\r\n }\r\n\r\n <div class=\"auth-field\">\r\n <span class=\"auth-field-icon\"><i class=\"fas fa-lock-open\"></i></span>\r\n <input [type]=\"passwordVisibility().claveAntigua ? 'text' : 'password'\"\r\n class=\"auth-input\" placeholder=\" \" maxlength=\"20\"\r\n formControlName=\"claveAntigua\" id=\"exp-old-pw\" autocomplete=\"new-password\">\r\n <label for=\"exp-old-pw\" class=\"auth-label\">Contraseña antigua</label>\r\n <button type=\"button\" class=\"auth-toggle-pw\" (click)=\"togglePassword('claveAntigua')\">\r\n <i [class]=\"passwordVisibility().claveAntigua ? 'fas fa-eye' : 'fas fa-eye-slash'\"></i>\r\n </button>\r\n </div>\r\n\r\n <div class=\"auth-field\">\r\n <span class=\"auth-field-icon\"><i class=\"fas fa-lock\"></i></span>\r\n <input [type]=\"passwordVisibility().claveNueva ? 'text' : 'password'\"\r\n class=\"auth-input\" placeholder=\" \" maxlength=\"20\"\r\n formControlName=\"claveNueva\" id=\"exp-new-pw\" autocomplete=\"new-password\">\r\n <label for=\"exp-new-pw\" class=\"auth-label\">Contraseña nueva</label>\r\n <button type=\"button\" class=\"auth-toggle-pw\" (click)=\"togglePassword('claveNueva')\">\r\n <i [class]=\"passwordVisibility().claveNueva ? 'fas fa-eye' : 'fas fa-eye-slash'\"></i>\r\n </button>\r\n </div>\r\n\r\n @if (expiredForm.get('claveNueva')?.value?.length > 0) {\r\n <ul class=\"auth-validation-list\" @fadeInOut>\r\n @if (expiredForm.get('claveNueva')?.errors?.['minlength']) {\r\n <li>Al menos 8 caracteres</li>\r\n }\r\n @if (expiredForm.get('claveNueva')?.errors?.['minuscula']) {\r\n <li>Al menos 1 letra minúscula</li>\r\n }\r\n @if (expiredForm.get('claveNueva')?.errors?.['mayuscula']) {\r\n <li>Al menos 1 letra mayúscula</li>\r\n }\r\n @if (expiredForm.get('claveNueva')?.errors?.['numero']) {\r\n <li>Al menos 1 número</li>\r\n }\r\n @if (expiredForm.get('claveNueva')?.errors?.['especial']) {\r\n <li>Al menos 1 carácter especial</li>\r\n }\r\n </ul>\r\n }\r\n\r\n <div class=\"auth-field\"\r\n [class.has-error]=\"expiredForm.get('claveNuevaConfirmar')?.errors?.['coinciden'] && expiredForm.get('claveNuevaConfirmar')?.touched\">\r\n <span class=\"auth-field-icon\"><i class=\"fas fa-check-circle\"></i></span>\r\n <input [type]=\"passwordVisibility().claveNuevaConfirmar ? 'text' : 'password'\"\r\n class=\"auth-input\" placeholder=\" \" maxlength=\"20\"\r\n formControlName=\"claveNuevaConfirmar\" id=\"exp-confirm-pw\" autocomplete=\"new-password\">\r\n <label for=\"exp-confirm-pw\" class=\"auth-label\">Confirmar contraseña</label>\r\n <button type=\"button\" class=\"auth-toggle-pw\" (click)=\"togglePassword('claveNuevaConfirmar')\">\r\n <i [class]=\"passwordVisibility().claveNuevaConfirmar ? 'fas fa-eye' : 'fas fa-eye-slash'\"></i>\r\n </button>\r\n </div>\r\n @if (expiredForm.get('claveNuevaConfirmar')?.errors?.['coinciden'] && expiredForm.get('claveNuevaConfirmar')?.touched) {\r\n <p class=\"auth-error\" @fadeInOut>Las contraseñas deben coincidir</p>\r\n }\r\n\r\n <button type=\"button\" class=\"auth-btn\" [class.auth-btn--red]=\"!produccion\"\r\n [disabled]=\"expiredForm.invalid\" (click)=\"recover()\">\r\n Renovar contraseña\r\n </button>\r\n\r\n <button type=\"button\" class=\"auth-btn auth-btn--outline\" (click)=\"back()\">\r\n Volver al inicio de sesión\r\n </button>\r\n\r\n </form>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n","import { Component, inject, input, output } from '@angular/core';\r\nimport { FormBuilder, ReactiveFormsModule, Validators } from '@angular/forms';\r\nimport { AuthSender } from '../../models/auth-sender';\r\nimport { fadeInOut } from '../../utils/animations';\r\nimport { LoginEvent } from '../../models/login-event';\r\n\r\n@Component({\r\n selector: 'lib-recover-password',\r\n imports: [ReactiveFormsModule],\r\n templateUrl: './recover-password.component.html',\r\n styleUrls: ['./recover-password.component.scss', '../auth.scss'],\r\n animations: [fadeInOut]\r\n})\r\nexport class RecoverPasswordComponent {\r\n\r\n private fb = inject(FormBuilder)\r\n\r\n production = input<boolean>(true)\r\n module = input<string>('ERP') // DEFECTO ERP\r\n\r\n loginEvent = output<LoginEvent>()\r\n\r\n recoverForm = this.fb.group({\r\n ruc: ['', [Validators.required, Validators.minLength(11), Validators.maxLength(11)]],\r\n usuario: ['', Validators.required]\r\n })\r\n\r\n enviar = () => {\r\n if (this.recoverForm.invalid) {\r\n this.loginEvent.emit({ type: \"ERROR\", message: 'Debes completar todos los campos' })\r\n return\r\n }\r\n\r\n const formValues = this.recoverForm.value\r\n const sender: AuthSender = {\r\n ruc: formValues.ruc!,\r\n coduser: formValues.usuario!\r\n }\r\n\r\n this.loginEvent.emit({ type: \"RECOVER\", data: sender })\r\n }\r\n\r\n back = () => this.loginEvent.emit({ type: \"BACK\" })\r\n \r\n}\r\n","<div class=\"auth-wrapper-login\">\r\n @let produccion = production();\r\n <div class=\"auth-panel-left\" [class.auth-panel-left--dev]=\"!produccion\">\r\n <span class=\"auth-blob auth-blob-1\"></span>\r\n <span class=\"auth-blob auth-blob-2\"></span>\r\n <span class=\"auth-blob auth-blob-3\"></span>\r\n <span class=\"auth-blob auth-blob-4\"></span>\r\n\r\n <div class=\"auth-brand-panel\">\r\n <div class=\"auth-brand-logo\">\r\n <img src=\"assets/images/logo-tsi-tres.png\" alt=\"TSI\" />\r\n </div>\r\n <h1 class=\"auth-brand-title\">{{module()}}</h1>\r\n <p class=\"auth-brand-subtitle\">Recupera el acceso a tu cuenta de forma rápida y segura</p>\r\n\r\n <div class=\"auth-brand-divider\"></div>\r\n\r\n <div class=\"auth-brand-features\">\r\n <div class=\"auth-brand-feature\">\r\n <span class=\"feat-dot\"></span> Verificación por correo electrónico\r\n </div>\r\n <div class=\"auth-brand-feature\">\r\n <span class=\"feat-dot\"></span> Proceso seguro y encriptado\r\n </div>\r\n <div class=\"auth-brand-feature\">\r\n <span class=\"feat-dot\"></span> Nueva clave en minutos\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"auth-panel-right\" [class.auth-panel-right--dev]=\"!produccion\">\r\n <div class=\"auth-panel-bg\">\r\n <span class=\"auth-deco auth-deco-tl\"></span>\r\n <span class=\"auth-deco auth-deco-br\"></span>\r\n </div>\r\n\r\n <div class=\"auth-form-wrapper\">\r\n <div>\r\n @if (!produccion) {\r\n <div>\r\n <span class=\"auth-test-badge\">\r\n <span class=\"badge-dot\"></span> ENTORNO DE PRUEBAS\r\n </span>\r\n </div>\r\n }\r\n\r\n <div class=\"auth-card\">\r\n <h2 class=\"auth-card-title\">Recuperar contraseña</h2>\r\n <p class=\"auth-card-subtitle\">\r\n Confírmanos tu RUC y usuario. Enviaremos a tu correo registrado la nueva contraseña.\r\n </p>\r\n\r\n <form [formGroup]=\"recoverForm\">\r\n\r\n <div class=\"auth-field\">\r\n <span class=\"auth-field-icon\"><i class=\"fas fa-building\"></i></span>\r\n <input type=\"text\" class=\"auth-input\" placeholder=\" \" maxlength=\"11\" formControlName=\"ruc\"\r\n id=\"rec-ruc\" onlyNumber autocomplete=\"off\">\r\n <label for=\"rec-ruc\" class=\"auth-label\">RUC</label>\r\n </div>\r\n\r\n <div class=\"auth-field\">\r\n <span class=\"auth-field-icon\"><i class=\"fas fa-user\"></i></span>\r\n <input type=\"text\" class=\"auth-input\" placeholder=\" \" formControlName=\"usuario\"\r\n id=\"rec-user\" autocomplete=\"off\">\r\n <label for=\"rec-user\" class=\"auth-label\">Usuario</label>\r\n </div>\r\n\r\n <button type=\"button\" class=\"auth-btn\" [class.auth-btn--red]=\"!produccion\"\r\n [disabled]=\"recoverForm.invalid\" (click)=\"enviar()\">\r\n Enviar instrucciones\r\n </button>\r\n\r\n <button type=\"button\" class=\"auth-btn auth-btn--outline\" (click)=\"back()\">\r\n Volver al inicio de sesión\r\n </button>\r\n\r\n </form>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>","import { Component, computed, HostListener, input, model, output } from '@angular/core';\r\nimport { FormsModule } from '@angular/forms';\r\nimport { LoginEvent } from '../../models/login-event';\r\n\r\n@Component({\r\n selector: 'lib-select-branch',\r\n imports: [FormsModule],\r\n templateUrl: './select-branch.component.html',\r\n styleUrls: ['./select-branch.component.scss', '../auth.scss']\r\n})\r\nexport class SelectBranchComponent {\r\n\r\n production = input<boolean>(true)\r\n module = input<string>('ERP') // DEFECTO ERP\r\n title = computed(() => this.production() ? `MÓDULO: ${this.module()}` : `MÓDULO DE PRUEBA: ${this.module()}`)\r\n\r\n codsuc = model<number>(-1)\r\n sucursalesList = input<any[]>([])\r\n\r\n loginEvent = output<LoginEvent>()\r\n\r\n @HostListener('document:keydown', ['$event'])\r\n handleEnter(_event: KeyboardEvent) {\r\n if(_event.key !== 'Enter') return\r\n if (!this.codsuc) {\r\n return\r\n }\r\n this.goMain()\r\n }\r\n\r\n goMain = () => {\r\n this.loginEvent.emit({type: \"BRANCH\", data: { codsuc: this.codsuc() }})\r\n }\r\n}\r\n","<div class=\"auth-wrapper-login\">\r\n @let produccion = production();\r\n <div class=\"auth-panel-left\" [class.auth-panel-left--dev]=\"!produccion\">\r\n <span class=\"auth-blob auth-blob-1\"></span>\r\n <span class=\"auth-blob auth-blob-2\"></span>\r\n <span class=\"auth-blob auth-blob-3\"></span>\r\n <span class=\"auth-blob auth-blob-4\"></span>\r\n\r\n <div class=\"auth-brand-panel\">\r\n <div class=\"auth-brand-logo\">\r\n <img src=\"assets/images/logo-tsi-tres.png\" alt=\"TSI\" />\r\n </div>\r\n <h1 class=\"auth-brand-title\">{{module()}}</h1>\r\n <p class=\"auth-brand-subtitle\">Selecciona la sucursal desde donde vas a operar hoy</p>\r\n\r\n <div class=\"auth-brand-divider\"></div>\r\n\r\n <div class=\"auth-brand-features\">\r\n <div class=\"auth-brand-feature\">\r\n <span class=\"feat-dot\"></span> Acceso segmentado por sucursal\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"auth-panel-right\" [class.auth-panel-right--dev]=\"!produccion\">\r\n <div class=\"auth-panel-bg\">\r\n <span class=\"auth-deco auth-deco-tl\"></span>\r\n <span class=\"auth-deco auth-deco-br\"></span>\r\n </div>\r\n\r\n <div class=\"auth-form-wrapper\">\r\n <div>\r\n @if (!produccion) {\r\n <div>\r\n <span class=\"auth-test-badge\">\r\n <span class=\"badge-dot\"></span> ENTORNO DE PRUEBAS\r\n </span>\r\n </div>\r\n }\r\n\r\n <div class=\"auth-card\">\r\n <h2 class=\"auth-card-title\">Seleccionar sucursal</h2>\r\n <p class=\"auth-card-subtitle\">{{title()}}</p>\r\n\r\n <select class=\"auth-select\" [(ngModel)]=\"codsuc\">\r\n @for (suc of sucursalesList(); track $index) {\r\n <option [value]=\"suc.codsuc\">{{suc.sucursal}}</option>\r\n }\r\n </select>\r\n\r\n <button class=\"auth-btn\" [class.auth-btn--red]=\"!produccion\" (click)=\"goMain()\">\r\n Continuar\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>","export class AuthSender {\r\n ruc?: string\r\n coduser?: string\r\n clave?: string\r\n nuevaclave?: string\r\n producto?: string\r\n codsuc?: number\r\n}","/*\n * Public API Surface of login-tsi\n */\n\nexport * from './lib/components/auth/auth.component';\nexport * from './lib/components/expired-password/expired-password.component';\nexport * from './lib/components/recover-password/recover-password.component';\nexport * from './lib/components/select-branch/select-branch.component';\nexport * from './lib/models/auth-sender';\nexport * from './lib/models/login-event';\nexport * from './lib/models/login-type-event';\n\n// PWA (instalación, guía, actualización/refresh forzado)\nexport * from './lib/components/pwa-floating/pwa-floating.component';\nexport * from './lib/components/refresh-floating/refresh-floating.component';\nexport * from './lib/pwa-install.service';\nexport * from './lib/models/verificar-mfa';\nexport * from './lib/models/auth-api';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
@@ -31,6 +31,7 @@ export declare class MdVerificarMfaComponent {
|
|
|
31
31
|
estadoPush: import("@angular/core").WritableSignal<EstadoPush>;
|
|
32
32
|
isPushEnCurso: import("@angular/core").Signal<boolean>;
|
|
33
33
|
pushError: import("@angular/core").WritableSignal<string>;
|
|
34
|
+
numberMatching: import("@angular/core").WritableSignal<number>;
|
|
34
35
|
private inputCodigo;
|
|
35
36
|
private pushCtrl?;
|
|
36
37
|
constructor();
|
package/lib/models/auth-api.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { InjectionToken, Provider, Type } from '@angular/core';
|
|
2
2
|
import { AuthSender } from './auth-sender';
|
|
3
|
-
import { MfaChallengeResponse, MfaEstadoPush, MfaLoginSender } from './verificar-mfa';
|
|
3
|
+
import { MfaChallengeResponse, MfaEstadoPush, MfaLoginSender, PushSolicitudInicio } from './verificar-mfa';
|
|
4
4
|
export interface AuthApi {
|
|
5
5
|
login(sender: AuthSender): Promise<MfaChallengeResponse | void>;
|
|
6
6
|
verificarCodigo(sender: MfaLoginSender): Promise<void>;
|
|
7
|
-
enviarPush(preauthToken: string): Promise<
|
|
7
|
+
enviarPush(preauthToken: string): Promise<PushSolicitudInicio>;
|
|
8
8
|
estadoPush(sender: MfaLoginSender): Promise<MfaEstadoPush>;
|
|
9
9
|
}
|
|
10
10
|
export declare const AUTH_API: InjectionToken<AuthApi>;
|
|
@@ -11,6 +11,10 @@ export interface MfaLoginSender {
|
|
|
11
11
|
codigo?: string;
|
|
12
12
|
solicitudId?: string;
|
|
13
13
|
}
|
|
14
|
+
export interface PushSolicitudInicio {
|
|
15
|
+
solicitudId: string;
|
|
16
|
+
numberMatching: number;
|
|
17
|
+
}
|
|
14
18
|
export interface MfaPushEstadoPendiente {
|
|
15
19
|
result: 'waiting' | 'deny' | 'expired';
|
|
16
20
|
}
|