import { Directive , Input , NgZone , OnInit } from "@angular/core" ; import { Router } from "@angular/router" ; import { take } from "rxjs/operators" ; import { AuthResult } from "jslib-common/models/domain/authResult" ; import { AuthService } from "jslib-common/abstractions/auth.service" ; import { CryptoFunctionService } from "jslib-common/abstractions/cryptoFunction.service" ; import { EnvironmentService } from "jslib-common/abstractions/environment.service" ; import { I18nService } from "jslib-common/abstractions/i18n.service" ; import { LogService } from "jslib-common/abstractions/log.service" ; import { PasswordGenerationService } from "jslib-common/abstractions/passwordGeneration.service" ; import { PlatformUtilsService } from "jslib-common/abstractions/platformUtils.service" ; import { StateService } from "jslib-common/abstractions/state.service" ; import { Utils } from "jslib-common/misc/utils" ; import { CaptchaProtectedComponent } from "./captchaProtected.component" ; @ Directive ( ) export class LoginComponent extends CaptchaProtectedComponent implements OnInit { @ Input ( ) email : string = "" ; @ Input ( ) rememberEmail = true ; masterPassword : string = "" ; showPassword : boolean = false ; formPromise : Promise < AuthResult > ; onSuccessfulLogin : ( ) => Promise < any > ; onSuccessfulLoginNavigate : ( ) => Promise < any > ; onSuccessfulLoginTwoFactorNavigate : ( ) => Promise < any > ; onSuccessfulLoginForceResetNavigate : ( ) => Promise < any > ; protected twoFactorRoute = "2fa" ; protected successRoute = "vault" ; protected forcePasswordResetRoute = "update-temp-password" ; constructor ( protected authService , protected router , platformUtilsService , i18nService , protected stateService , environmentService , protected passwordGenerationService , protected cryptoFunctionService , protected logService , protected ngZone ) { super ( environmentService , i18nService , platformUtilsService ) ; } async ngOnInit ( ) { if ( this . email == null || this . email === "" ) { this . email = await this . stateService . getRememberedEmail ( ) ; if ( this . email == null ) { this . email = "" ; } } this . rememberEmail = ( await this . stateService . getRememberedEmail ( ) ) != null ; if ( Utils . isBrowser && ! Utils . isNode ) { this . focusInput ( ) ; } } async submit ( ) { await this . setupCaptcha ( ) ; if ( this . email == null || this . email === "" ) { this . platformUtilsService . showToast ( "error" , this . i18nService . t ( "errorOccurred" ) , this . i18nService . t ( "emailRequired" ) ) ; return ; } if ( this . email . indexOf ( "@" ) === - 1 ) { this . platformUtilsService . showToast ( "error" , this . i18nService . t ( "errorOccurred" ) , this . i18nService . t ( "invalidEmail" ) ) ; return ; } if ( this . masterPassword == null || this . masterPassword === "" ) { this . platformUtilsService . showToast ( "error" , this . i18nService . t ( "errorOccurred" ) , this . i18nService . t ( "masterPassRequired" ) ) ; return ; } try { this . formPromise = this . authService . logIn ( this . email , this . masterPassword , this . captchaToken ) ; const response = await this . formPromise ; if ( this . rememberEmail ) { await this . stateService . setRememberedEmail ( this . email ) ; } else { await this . stateService . setRememberedEmail ( null ) ; } if ( this . handleCaptchaRequired ( response ) ) { return ; } else if ( response . twoFactor ) { if ( this . onSuccessfulLoginTwoFactorNavigate != null ) { this . onSuccessfulLoginTwoFactorNavigate ( ) ; } else { this . router . navigate ( [ this . twoFactorRoute ] ) ; } } else if ( response . forcePasswordReset ) { if ( this . onSuccessfulLoginForceResetNavigate != null ) { this . onSuccessfulLoginForceResetNavigate ( ) ; } else { this . router . navigate ( [ this . forcePasswordResetRoute ] ) ; } } else { const disableFavicon = await this . stateService . getDisableFavicon ( ) ; await this . stateService . setDisableFavicon ( ! ! disableFavicon ) ; if ( this . onSuccessfulLogin != null ) { this . onSuccessfulLogin ( ) ; } if ( this . onSuccessfulLoginNavigate != null ) { this . onSuccessfulLoginNavigate ( ) ; } else { this . router . navigate ( [ this . successRoute ] ) ; } } } catch ( e ) { this . logService . error ( e ) ; } } togglePassword ( ) { this . showPassword = ! this . showPassword ; if ( this . ngZone . isStable ) { document . getElementById ( "masterPassword" ) . focus ( ) ; } else { this . ngZone . onStable . pipe ( take ( 1 ) ) . subscribe ( ( ) => document . getElementById ( "masterPassword" ) . focus ( ) ) ; } } async launchSsoBrowser ( clientId , ssoRedirectUri ) { const passwordOptions = { type : "password" , length : 64 , uppercase : true , lowercase : true , numbers : true , special : false , } ; const state = await this . passwordGenerationService . generatePassword ( passwordOptions ) ; const ssoCodeVerifier = await this . passwordGenerationService . generatePassword ( passwordOptions ) ; const codeVerifierHash = await this . cryptoFunctionService . hash ( ssoCodeVerifier , "sha256" ) ; const codeChallenge = Utils . fromBufferToUrlB64 ( codeVerifierHash ) ; await this . stateService . setSsoState ( state ) ; await this . stateService . setSsoCodeVerifier ( ssoCodeVerifier ) ; const webUrl = this . environmentService . getWebVaultUrl ( ) ; this . platformUtilsService . launchUri ( webUrl + "/#/sso?clientId=" + clientId + "&redirectUri=" + encodeURIComponent ( ssoRedirectUri ) + "&state=" + state + "&codeChallenge=" + codeChallenge ) ; } protected focusInput ( ) { document . getElementById ( this . email == null || this . email === "" ? "email" : "masterPassword" ) . focus ( ) ; } }