UNPKG

ems-web-app-cognito

Version:

This angular.io module includes a component, service and supporting classes that wrap the Amazon Cognito Identity SDK to enable simple username/password authentication.

602 lines 116 kB
import { Component, HostBinding, Input, Output, EventEmitter } from '@angular/core'; import { CognitoUserSession, CognitoIdToken, CognitoAccessToken } from 'amazon-cognito-identity-js'; import { CognitoStrings } from "./cognito.classes"; import { CognitoResponseType, CognitoRequestType, CognitoFormType } from "./cognito.types"; import { unsnake, tick, trim } from "./cognito.utils"; import { startAuthentication, startRegistration } from '@simplewebauthn/browser'; import * as i0 from "@angular/core"; import * as i1 from "./cognito.service"; import * as i2 from "@angular/common"; import * as i3 from "@angular/forms"; import * as i4 from "./cognito.pipes"; export class CognitoComponent { constructor(cognito) { this.cognito = cognito; this.hostStyle = {}; this.showForm = false; this.transitioning = false; this.providerName = "Google"; this.modalBackground = "rgba(255,255,255,0.5)"; this.zIndex = 1000; this.srp = true; this.otp = false; this.sso = false; this.magicLink = false; this.reloadAfterLinkAuthentication = true; this.passkeys = false; this.useLocalStorage = true; this.onReady = new EventEmitter(); this.onConnecting = new EventEmitter(); this.onAuthenticated = new EventEmitter(); this.onResponse = new EventEmitter(); this.onUsernameEntered = new EventEmitter(); this.model = { username: null, password: null }; this.componentStyle = {}; this.formType = null; this.CognitoFormType = CognitoFormType; this.rows = []; this.error = null; this.prompt = null; this.cache = null; this.strings = CognitoStrings; this.showPasswordField = true; this.showEmailSubmitButton = true; this.disableUsername = false; this.session = null; this.user = null; } ngOnInit() { this.cognito.initialize(this.poolId, this.clientId, this.useLocalStorage, this.idToken, this.accessToken, this.refreshToken); this.cognito.form$.subscribe(form => { this.formType = form; this.showCurrentForm(); }); this.cognito.session$.subscribe(session => { this.session = session; }); this.cognito.user$.subscribe(user => { this.user = user; }); this.updateButtons(); } ngAfterViewInit() { setTimeout(() => this.initialize()); } onEnterUsername() { this.showEmailSubmitButton = false; this.onUsernameEntered.emit(this.model.username.replace(/\s+/gim, "")); } updateButtons() { if (this.otp || this.magicLink || this.passkeys) { this.showPasswordField = false; } } async login() { if (!this.srp && this.otp) { return this.getOtp(); } else if (!this.srp && this.magicLink) { return this.getMagicLink(); } else if (!this.srp && this.passkeys) { return this.getPasskey(); } else if (!this.srp) { return this.onEnterUsername(); } let response; this.error = null; this.model.password = trim(this.model.password); if (this.hook) { const proceed = await this.hook({ "state": "before-login", model: this.model }); if (!proceed) return; } try { const username = this.model.username.replace(/\s+/gim, ""); this.onConnecting.emit(true); response = await this.cognito.authenticate(username, this.model.password); } catch (e) { response = e; } finally { this.handleResponse(response); } } async getOtp() { let response; this.error = null; try { this.onConnecting.emit(true); const username = this.model.username.replace(/\s+/gim, ""); const otp = this.model.otp ? trim(this.model.otp) : undefined; this.srp = false; this.magicLink = false; this.passkeys = false; if (this.hook) { const proceed = await this.hook({ "state": "before-otp-request", model: this.model }); if (!proceed) return this.connectionComplete(); } response = await this.cognito.otpAuthenticate(username, otp); if (this.hook) { //@ts-ignore const proceed = await this.hook({ "state": "after-otp-request", model: this.model, sessionId: response.user.Session }); if (!proceed) throw new Error("Unable to proceed"); } } catch (e) { response = e; } finally { this.handleResponse(response); } } async getMagicLink() { let response; this.error = null; try { const username = this.model.username.replace(/\s+/gim, ""); this.onConnecting.emit(true); if (this.hook) { const proceed = await this.hook({ "state": "before-magic-link-request", model: this.model }); if (!proceed) return this.connectionComplete(); } response = await this.cognito.magicLinkAuthenticate(username); if (this.hook) { //@ts-ignore const proceed = await this.hook({ "state": "after-magic-link-request", model: this.model, sessionId: response.user.Session }); if (!proceed) return this.connectionComplete(); } } catch (e) { response = e; } finally { this.connectionComplete(); } } async processMagicLink(email, code, sessionId) { try { this.onConnecting.emit(true); await this.cognito.magicLinkAuthenticate(email, code, sessionId); if (this.reloadAfterLinkAuthentication) { window.location.href = window.location.origin; } else { this.onAuthenticated.emit(this.getUserData()); //connected this.showForm = false; this.connectionComplete(); } } catch (e) { } } async getPasskey() { const username = this.model.username.replace(/\s+/gim, ""); this.passkeyAuthOptions = await this.generateAuthenticationOptions(username); const credentials = this.passkeyAuthOptions?.allowCredentials ?? []; if (!credentials.length && !this.model.passkey) this.sendPasskeyCode(); else if (!credentials.length) this.registerPasskey(); else this.usePasskey(); } async sendPasskeyCode() { const username = this.model.username.replace(/\s+/gim, ""); const token = await this.getUserId(username); this.srp = false; this.otp = false; this.magicLink = false; this.model.showChallengeEntry = true; } async usePasskey() { const username = this.model.username.replace(/\s+/gim, ""); this.onConnecting.emit(true); const authentication = await startAuthentication(this.passkeyAuthOptions); const outcome = await this.verifyAuthentication(authentication); await this.cognito.passkeyAuthenticate(username); if (outcome.verified) { await this.cognito.passkeyAuthenticate(username, outcome.uid); this.onAuthenticated.emit(this.getUserData()); this.showForm = false; this.connectionComplete(); } } async registerPasskey() { const username = this.model.username.replace(/\s+/gim, ""); const code = this.model.passkey.replace(/\s+/gim, ""); this.onConnecting.emit(true); const options = await this.generateRegistrationOptions(code); const registration = await startRegistration(options); const outcome = await this.verifyRegistration(registration, code); await this.cognito.passkeyAuthenticate(username); if (outcome.verified) { await this.cognito.passkeyAuthenticate(username, outcome.uid); this.onAuthenticated.emit(this.getUserData()); this.showForm = false; this.connectionComplete(); } } async onNewUser() { let response; this.error = null; this.model.newPassword = trim(this.model.newPassword); if (this.hook) { const proceed = await this.hook({ "state": "before-registration", model: this.model }); if (!proceed) return; } try { this.onConnecting.emit(true); response = await this.cognito.completePasswordUpdate(this.model.newPassword, this.cache.user, this.getUserAttributes()); } catch (e) { response = e; } finally { this.handleResponse(response); } } async onForcePasswordReset() { this.model.code = trim(this.model.code); this.model.newPassword = trim(this.model.newPassword); this.onConnecting.emit(true); if (this.hook) { const proceed = await this.hook({ "state": "before-force-password-reset", model: this.model }); if (!proceed) return; } try { const response = await this.cognito.confirmPassword(this.cache.user, this.model.code, this.model.newPassword); this.error = null; this.transitioning = true; await tick(250); this.formType = CognitoFormType.Login; this.setMessaging(response, CognitoStrings.onUserPasswordChangeSuccessful); await tick(0); this.transitioning = false; } catch (e) { this.setMessaging(e); } finally { this.onConnecting.emit(false); } } async onUserPasswordReset() { this.error = null; this.onConnecting.emit(true); this.model.password = trim(this.model.password); this.model.newPassword = trim(this.model.newPassword); if (this.hook) { const proceed = await this.hook({ "state": "before-user-password-reset", model: this.model }); if (!proceed) return; } try { const response = await this.cognito.resetPassword(this.user, this.model.password, this.model.newPassword); this.transitioning = true; await tick(250); this.formType = CognitoFormType.PasswordUpdateSuccessful; this.prompt = CognitoStrings.onPasswordUpdated; this.error = null; await tick(); this.transitioning = false; } catch (e) { this.setMessaging(e); } finally { this.onConnecting.emit(false); } } async onForgotPassword($event) { $event.preventDefault(); $event.stopImmediatePropagation(); this.transitioning = true; await tick(250); this.formType = CognitoFormType.UserVerificationRequest; this.prompt = CognitoStrings.onVerificationCodeSent; this.error = null; await tick(); this.transitioning = false; } async onRequestVerificationCode() { const username = this.model.username.replace(/\s+/gim, ""); const model = { username }; if (this.hook) { const proceed = await this.hook({ "state": "request-verification-code", "username": username, model }); if (!proceed) return; this.model.username = model.username; } this.onConnecting.emit(true); this.error = null; try { const response = await this.cognito.requestVerificationCode(model.username); this.transitioning = true; await tick(250); this.setMessaging(response, CognitoStrings.onNewPasswordRequired); this.showPasswordResetForm(response, false); } catch (e) { this.setMessaging(e); } finally { this.connectionComplete(); } } newUserFormDisabled() { let disabled = false; this.cache?.requiredAttributes?.forEach(key => { if (!this.model[key]) disabled = true; }); if (!this.model.newPassword || !this.model.newPasswordConfirm) { disabled = true; } if (this.model.newPassword !== this.model.newPasswordConfirm) { disabled = true; } return disabled; } async initialize() { try { if (this.cognitoUrl && localStorage.getItem("ems_access_token")) { const info = await this.cognito.getUserInfo(this.cognitoUrl); //emulate cognito user/session for federated login this.session = new CognitoUserSession({ IdToken: new CognitoIdToken({ IdToken: info.idToken }), AccessToken: new CognitoAccessToken({ AccessToken: info.accessToken }), }); this.cognito.createFederatedSession(info.idToken, info.accessToken); } } catch (error) { } finally { if (this.session) { this.onAuthenticated.emit(this.getUserData()); } } } async handleResponse(response) { this.transitioning = true; await tick(250); this.setMessaging(response); this.cache = response.userAttributes ? response : this.cache; if (response.error?.code === CognitoResponseType.NotAuthorized && response.request === CognitoRequestType.Authentication) { this.connectionComplete(); //likely bad password or too many attempts } else if (response.error?.code === CognitoResponseType.ForcePasswordReset && response.request === CognitoRequestType.Authentication) { this.initiatePasswordReset(response); //admin has forced user password reset } else if (response.type === CognitoResponseType.OtpChallenge) { this.model.showChallengeEntry = true; this.connectionComplete(); } else if (response.type === CognitoResponseType.PasswordReset && response.request === CognitoRequestType.Authentication) { this.prompt = CognitoStrings.onFirstLogin; this.showPasswordResetForm(response); //new user } else if (!response.error?.code && (response.request === CognitoRequestType.Authentication || response.type === CognitoResponseType.Authenticated)) { this.onAuthenticated.emit(this.getUserData()); //connected this.showForm = false; this.connectionComplete(); } else { this.connectionComplete(); //unsupported response -- hopefully described in messaging } this.onResponse.emit({ response, model: this.model }); } async initiatePasswordReset(response) { this.error = null; try { const result = await this.cognito.forgotPassword(response.user); this.setMessaging(result, CognitoStrings.onNewPasswordRequired); await tick(250); this.showPasswordResetForm(response, false); } catch (e) { this.setMessaging(e); } finally { this.connectionComplete(); } } setMessaging(response, prompt = null) { if (response.error?.code === CognitoResponseType.LimitExceededException) { this.error = CognitoStrings.onTooManyAttempts; } else { this.error = response.error?.message ?? null; } this.prompt = prompt; } async connectionComplete() { await tick(); this.transitioning = false; this.onConnecting.emit(false); } async showCurrentForm() { if (!this.formType) return; if (this.formType === CognitoFormType.GoogleSignIn) { return this.signInWithGoogle(); } this.hostStyle = { "background": this.modalBackground, "z-index": this.zIndex }; await tick(); this.showForm = true; this.onReady.emit(); } async showPasswordResetForm(result, isNewUser = true) { this.cache = result; this.rows = []; this.formType = isNewUser ? CognitoFormType.NewUser : CognitoFormType.ForcePasswordReset; //bubble first and last name fields to the top of the attributes list result.requiredAttributes?.sort((a, b) => { if (a === "given_name" && b === "family_name") return -1; if (b === "given_name" && a === "family_name") return 1; if (a === "given_name") return -1; if (a === "family_name") return -1; if (b === "given_name") return 1; if (b === "family_name") return 1; return a > b ? 1 : -1; }); //inject formrows for required attributes result.requiredAttributes?.forEach(key => { if (key.match(/^email/)) return; const value = result.userAttributes[key]; this.rows.push({ label: unsnake(key), key }); this.model[key] = value && value.length ? value : undefined; }); await tick(); this.connectionComplete(); } getUserAttributes() { const attributes = {}; if (!this.cache?.requiredAttributes) return attributes; this.cache.requiredAttributes.forEach(key => attributes[key] = this.model[key]); return attributes; } signInWithGoogle() { const url = `${this.cognitoUrl}/oauth2/authorize?identity_provider=${this.providerName}&redirect_uri=${window.location.origin}&response_type=TOKEN&client_id=${this.clientId}&scope=email openid profile aws.cognito.signin.user.admin`; window.location.href = url; } getUserData() { return { email: this.session.getIdToken().payload["email"], username: this.session.getIdToken().payload["cognito:username"], sub: this.session.getIdToken().payload["sub"], firstName: this.session.getIdToken().payload["given_name"], lastName: this.session.getIdToken().payload["family_name"], idToken: this.session.getIdToken().getJwtToken(), accessToken: this.session.getAccessToken().getJwtToken(), }; } } CognitoComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: CognitoComponent, deps: [{ token: i1.CognitoService }], target: i0.ɵɵFactoryTarget.Component }); CognitoComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.7", type: CognitoComponent, selector: "cognito", inputs: { poolId: ["pool-id", "poolId"], providerName: ["provider-name", "providerName"], clientId: ["client-id", "clientId"], cognitoUrl: ["cognito-signin-url", "cognitoUrl"], region: "region", modalBackground: ["modal-background", "modalBackground"], zIndex: ["z-index", "zIndex"], hook: "hook", srp: "srp", otp: "otp", sso: "sso", magicLink: ["magic-link", "magicLink"], magicLinkGenerator: ["magic-link-generator", "magicLinkGenerator"], reloadAfterLinkAuthentication: ["reload-after-link-authentication", "reloadAfterLinkAuthentication"], passkeys: "passkeys", useLocalStorage: "useLocalStorage", idToken: "idToken", accessToken: "accessToken", refreshToken: "refreshToken", ssoLink: ["sso-link", "ssoLink"], getUserId: ["passkeys-get-user-id", "getUserId"], generateAuthenticationOptions: ["passkeys-generate-authentication-options", "generateAuthenticationOptions"], generateRegistrationOptions: ["passkeys-generate-registration-options", "generateRegistrationOptions"], verifyRegistration: ["passkeys-verify-registration", "verifyRegistration"], verifyAuthentication: ["passkeys-verify-authentication", "verifyAuthentication"] }, outputs: { onReady: "ready", onConnecting: "connecting", onAuthenticated: "authenticated", onResponse: "response", onUsernameEntered: "usernameEntered" }, host: { properties: { "style": "this.hostStyle", "class.render": "this.showForm", "class.transitioning": "this.transitioning" } }, ngImport: i0, template: "<form *ngIf=\"showForm && formType === CognitoFormType.Login\" class=\"cognito-form\" (submit)=\"login()\">\n\t<button class=\"button close\" (click)=\"showForm=false\" type=\"button\"><span class=\"buttontext\">{{ strings.labelClose }}</span></button>\n\t<div *ngIf=\"prompt\" class=\"prompt\" [innerHtml]=\"prompt\"></div>\n\t<div class=\"cognito-formrow\">\n\t\t<label class=\"cognito-label\" for=\"username\">{{ strings.labelEmail }}</label>\n\t\t<input id=\"username\" class=\"cognito-input cognito-text\" type=\"text\" name=\"username\" [(ngModel)]=\"model.username\" [disabled]=\"disableUsername\"/>\n\t</div>\n\t<div *ngIf=\"!srp && !otp && !passkeys && !magicLink && showEmailSubmitButton\" class=\"cognito-buttons\">\n\t\t<button class=\"cognito-input cognito-submit cognito-button\" type=\"button\" (click)=\"onEnterUsername()\" [disabled]=\"!model.username\">{{ strings.labelSubmit }}</button>\n\t</div>\n\t<div *ngIf=\"srp && !showPasswordField\" class=\"cognito-buttons\">\n\t\t<button class=\"cognito-input cognito-submit cognito-button\" type=\"button\" (click)=\"showPasswordField = true; otp = false; magicLink = false; passkeys = false; sso = false;\" [disabled]=\"!model.username\">{{ strings.labelUseRegularPassword }}</button>\n\t</div>\n\t<div *ngIf=\"srp && showPasswordField\" class=\"cognito-formrow\">\n\t\t<label class=\"cognito-label\" for=\"password\">{{ strings.labelPassword }}</label>\n\t\t<input id=\"password\" autocomplete=\"off\" class=\"cognito-input cognito-text\" type=\"password\" name=\"password\" [(ngModel)]=\"model.password\"/>\n\t</div>\n\t<div *ngIf=\"srp && showPasswordField\" class=\"cognito-buttons\">\n\t\t<button type=\"button\" class=\"a\" (click)=\"onForgotPassword($event)\">{{ strings.labelForgotPassword }}</button>\n\t\t<input class=\"cognito-input cognito-submit cognito-button\" type=\"submit\" [value]=\"strings.labelSubmit\"/>\n\t</div>\n\t<div *ngIf=\"otp && model.showChallengeEntry\" class=\"cognito-formrow\">\n\t\t<label class=\"cognito-label\" for=\"otp\">{{ strings.labelOtpEnter }}</label>\n\t\t<input id=\"otp\" autocomplete=\"off\" class=\"cognito-input cognito-text\" type=\"text\" name=\"otp\" [(ngModel)]=\"model.otp\"/>\n\t</div>\n\t<div *ngIf=\"passkeys && model.showChallengeEntry\" class=\"cognito-formrow\">\n\t\t<label class=\"cognito-label\" for=\"passkey-reg\">{{ strings.labelPasskeyEnter }}</label>\n\t\t<textarea id=\"passkey-reg\" autocomplete=\"off\" class=\"cognito-input cognito-text\" name=\"passkey-reg\" [(ngModel)]=\"model.passkey\"></textarea>\n\t</div>\n\t<div *ngIf=\"otp\" class=\"cognito-buttons\">\n\t\t<button class=\"cognito-input cognito-submit cognito-button\" type=\"button\" (click)=\"getOtp()\" [disabled]=\"!model.username\">{{ model.showChallengeEntry ? strings.labelSubmit : strings.labelOtp }}</button>\n\t</div>\t\n\t<div *ngIf=\"magicLink\" class=\"cognito-buttons\">\n\t\t<button class=\"cognito-input cognito-submit cognito-button\" type=\"button\" (click)=\"getMagicLink()\" [disabled]=\"!model.username\">{{ strings.labelMagicLink }}</button>\n\t</div>\t\n\t<div *ngIf=\"passkeys\" class=\"cognito-buttons\">\n\t\t<button class=\"cognito-input cognito-submit cognito-button\" type=\"button\" (click)=\"getPasskey()\" [disabled]=\"!model.username\">{{ model.showChallengeEntry ? strings.labelSubmit : strings.labelPasskeys }}</button>\n\t</div>\t\n\t<div *ngIf=\"sso && ssoLink\" class=\"cognito-buttons\">\n\t\t<a class=\"cognito-input cognito-submit cognito-button\" type=\"button\" [href]=\"ssoLink\">{{ strings.labelSso }}</a>\n\t</div>\t\n\t<div *ngIf=\"error\" class=\"error\" [innerHtml]=\"error\"></div>\n</form>\n<form *ngIf=\"showForm && formType === CognitoFormType.NewUser\" class=\"cognito-form\" (submit)=\"onNewUser()\">\n\t<button class=\"button close\" (click)=\"showForm=false\" type=\"button\"><span class=\"buttontext\">{{ strings.labelClose }}</span></button>\n\t<div class=\"cognito-formrow\">\n\t\t<label class=\"cognito-label\" for=\"username\">{{ strings.labelEmail }}</label>\n\t\t<input id=\"username\" class=\"cognito-input cognito-text\" type=\"text\" name=\"username\" [(ngModel)]=\"model.username\" disabled />\n\t</div>\n\t<div class=\"cognito-formrow\">\n\t\t<label class=\"cognito-label no-mb\" for=\"new-password\">{{ strings.labelNewPassword }}</label>\n\t\t<p class=\"cognito-sublabel\">{{ strings.labelPasswordRequirement }}</p>\n\t\t<input id=\"new-password\" autocomplete=\"off\" class=\"cognito-input cognito-text\" type=\"password\" name=\"password-new\" [(ngModel)]=\"model.newPassword\"/>\n\t</div>\n\t<div class=\"cognito-formrow\">\n\t\t<label class=\"cognito-label\" for=\"password-confirm\">{{ strings.labelConfirmNewPassword }}</label>\n\t\t<input id=\"password-confirm\" autocomplete=\"off\" class=\"cognito-input cognito-text\" type=\"password\" name=\"password-confirm\" [(ngModel)]=\"model.newPasswordConfirm\"/>\n\t</div>\n\t<div class=\"cognito-formrow\" *ngFor=\"let row of rows\">\n\t\t<label class=\"cognito-label\" for=\"username\">{{ row.label|labeler }}</label>\n\t\t<input [id]=\"row.key\" class=\"cognito-input cognito-text\" type=\"text\" [name]=\"row.key\" [(ngModel)]=\"model[row.key]\"/>\n\t</div>\n\t<div class=\"cognito-buttons\">\n\t\t<input class=\"cognito-input cognito-submit cognito-button\" type=\"submit\" [disabled]=\"newUserFormDisabled()\" [value]=\"strings.labelSubmit\"/>\n\t</div>\t\n\t<div *ngIf=\"error\" class=\"error\" [innerHtml]=\"error\"></div>\n</form>\n<form *ngIf=\"showForm && formType === CognitoFormType.ForcePasswordReset\" class=\"cognito-form\" (submit)=\"onForcePasswordReset()\">\n\t<button class=\"button close\" (click)=\"showForm=false\" type=\"button\"><span class=\"buttontext\">{{ strings.labelClose }}</span></button>\n\t<div *ngIf=\"prompt\" class=\"prompt\" [innerHtml]=\"prompt\"></div>\n\t<div class=\"cognito-formrow\">\n\t\t<label class=\"cognito-label\" for=\"username\">{{ strings.labelEmail }}</label>\n\t\t<input id=\"username\" class=\"cognito-input cognito-text\" type=\"text\" name=\"username\" [(ngModel)]=\"model.username\" disabled />\n\t</div>\n\t<div class=\"cognito-formrow\">\n\t\t<label class=\"cognito-label\" for=\"code\">{{ strings.labelCode }}</label>\n\t\t<input id=\"code\" autocomplete=\"off\" class=\"cognito-input cognito-text\" type=\"text\" name=\"code\" [(ngModel)]=\"model.code\"/>\n\t</div>\n\t<div class=\"cognito-formrow\">\n\t\t<label class=\"cognito-label\" for=\"new-password\">{{ strings.labelNewPassword }}</label>\n\t\t<p class=\"cognito-sublabel\">{{ strings.labelPasswordRequirement }}</p>\n\t\t<input id=\"new-password\" autocomplete=\"off\" class=\"cognito-input cognito-text\" type=\"password\" name=\"password-new\" [(ngModel)]=\"model.newPassword\"/>\n\t</div>\n\t<div class=\"cognito-formrow\">\n\t\t<label class=\"cognito-label\" for=\"password-confirm\">{{ strings.labelConfirmNewPassword }}</label>\n\t\t<input id=\"password-confirm\" autocomplete=\"off\" class=\"cognito-input cognito-text\" type=\"password\" name=\"password-confirm\" [(ngModel)]=\"model.newPasswordConfirm\"/>\n\t</div>\n\t<div class=\"cognito-buttons\">\n\t\t<input class=\"cognito-input cognito-submit cognito-button\" type=\"submit\" [disabled]=\"newUserFormDisabled()\" [value]=\"strings.labelSubmit\"/>\n\t</div>\t\n\t<div *ngIf=\"error\" class=\"error\" [innerHtml]=\"error\"></div>\n</form>\n<form *ngIf=\"showForm && formType === CognitoFormType.UserVerificationRequest\" class=\"cognito-form\" (submit)=\"onRequestVerificationCode()\">\n\t<button class=\"button close\" (click)=\"showForm=false\" type=\"button\"><span class=\"buttontext\">{{ strings.labelClose }}</span></button>\n\t<div *ngIf=\"prompt\" class=\"prompt\" [innerHtml]=\"prompt\"></div>\n\t<div class=\"cognito-formrow\">\n\t\t<label class=\"cognito-label\" for=\"username\">{{ strings.labelEmail }}</label>\n\t\t<input id=\"username\" class=\"cognito-input cognito-text\" type=\"text\" name=\"username\" [(ngModel)]=\"model.username\"/>\n\t</div>\n\t<div class=\"cognito-buttons\">\n\t\t<input class=\"cognito-input cognito-submit cognito-button\" type=\"submit\" [disabled]=\"!model.username\" [value]=\"strings.labelSubmit\"/>\n\t</div>\t\n\t<div *ngIf=\"error\" class=\"error\" [innerHtml]=\"error\"></div>\n</form>\n<form *ngIf=\"showForm && formType === CognitoFormType.UserPasswordReset\" class=\"cognito-form\" (submit)=\"onUserPasswordReset()\">\n\t<button class=\"button close\" (click)=\"showForm=false\" type=\"button\"><span class=\"buttontext\">{{ strings.labelClose }}</span></button>\n\t<div *ngIf=\"prompt\" class=\"prompt\" [innerHtml]=\"prompt\"></div>\n\t<div class=\"cognito-formrow\">\n\t\t<label class=\"cognito-label\" for=\"current-password\">{{ strings.labelCurrentPassword }}</label>\n\t\t<input id=\"current-password\" autocomplete=\"off\" class=\"cognito-input cognito-text\" type=\"password\" name=\"password\" [(ngModel)]=\"model.password\"/>\n\t</div>\n\t<div class=\"cognito-formrow\">\n\t\t<label class=\"cognito-label\" for=\"new-password\">{{ strings.labelNewPassword }}</label>\n\t\t<p class=\"cognito-sublabel\">{{ strings.labelPasswordRequirement }}</p>\n\t\t<input id=\"new-password\" autocomplete=\"off\" class=\"cognito-input cognito-text\" type=\"password\" name=\"password-new\" [(ngModel)]=\"model.newPassword\"/>\n\t</div>\n\t<div class=\"cognito-formrow\">\n\t\t<label class=\"cognito-label\" for=\"password-confirm\">{{ strings.labelConfirmNewPassword }}</label>\n\t\t<input id=\"password-confirm\" autocomplete=\"off\" class=\"cognito-input cognito-text\" type=\"password\" name=\"password-confirm\" [(ngModel)]=\"model.newPasswordConfirm\"/>\n\t</div>\n\t<div class=\"cognito-buttons\">\n\t\t<input class=\"cognito-input cognito-submit cognito-button\" type=\"submit\" [disabled]=\"newUserFormDisabled()\" [value]=\"strings.labelSubmit\"/>\n\t</div>\t\n\t<div *ngIf=\"error\" class=\"error\" [innerHtml]=\"error\"></div>\n</form>\n<form *ngIf=\"showForm && formType === CognitoFormType.PasswordUpdateSuccessful\" class=\"cognito-form\" (submit)=\"showForm = false\">\n\t<div class=\"prompt\" [innerHtml]=\"prompt\"></div>\n\t<div class=\"cognito-buttons\">\n\t\t<input class=\"cognito-input cognito-submit cognito-button\" type=\"submit\" [value]=\"strings.labelClose\"/>\n\t</div>\t\n</form>", styles: [":host{position:fixed;top:0;left:0;right:0;bottom:0;display:flex;z-index:0;opacity:0;justify-content:center;align-items:center;pointer-events:none;color:#4d4d4d}:host p{margin:0;padding:0}:host.render{opacity:1;transition:opacity 1s;pointer-events:auto}.cognito-form{position:relative;background:white;transition:all .25s;box-sizing:border-box;padding:2rem 1rem;width:calc(100% - 2rem);max-height:calc(100% - 2rem);max-width:30rem;overflow:auto;border:solid 1px #ccc;box-shadow:0 0 8px 2px #0000000d}:host.transitioning .cognito-form{opacity:0;transition:all .25s;pointer-events:none}.cognito-form .button.close{position:absolute;right:1rem;top:1rem;width:1rem;height:1rem;overflow:hidden;cursor:pointer;display:flex;align-items:center;justify-content:center;-webkit-appearance:none;appearance:none;background:none;border:solid 1px #ccc}.cognito-form .button.close .buttontext{position:absolute;opacity:0}.cognito-form .button.close:after{content:\"x\"}.cognito-form .prompt{font-weight:700;font-style:italic;margin-bottom:1rem;text-align:center}.cognito-form .error{font-style:italic;color:red;text-align:center;margin-top:1rem}.cognito-label{display:block;text-transform:uppercase;font-family:inherit;font-size:.875rem;font-weight:700}:host p.cognito-sublabel{font-size:14px;font-style:italic;margin-left:1rem}.cognito-text{display:block;width:100%;font-size:1.125rem;padding:.25rem;box-sizing:border-box;color:inherit;font-family:inherit;margin-top:.5rem}.cognito-formrow+.cognito-formrow{margin-top:1.25rem}.cognito-buttons{margin-top:2rem;text-align:center}.cognito-buttons button+button,.cognito-buttons button+input{margin-left:2rem}.cognito-buttons button.a{-webkit-appearance:none;appearance:none;background:none;border:0;text-decoration:underline;cursor:pointer}#passkey-reg{resize:none;height:8rem}\n"], directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i3.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], pipes: { "labeler": i4.LabelerPipe } }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: CognitoComponent, decorators: [{ type: Component, args: [{ selector: 'cognito', template: "<form *ngIf=\"showForm && formType === CognitoFormType.Login\" class=\"cognito-form\" (submit)=\"login()\">\n\t<button class=\"button close\" (click)=\"showForm=false\" type=\"button\"><span class=\"buttontext\">{{ strings.labelClose }}</span></button>\n\t<div *ngIf=\"prompt\" class=\"prompt\" [innerHtml]=\"prompt\"></div>\n\t<div class=\"cognito-formrow\">\n\t\t<label class=\"cognito-label\" for=\"username\">{{ strings.labelEmail }}</label>\n\t\t<input id=\"username\" class=\"cognito-input cognito-text\" type=\"text\" name=\"username\" [(ngModel)]=\"model.username\" [disabled]=\"disableUsername\"/>\n\t</div>\n\t<div *ngIf=\"!srp && !otp && !passkeys && !magicLink && showEmailSubmitButton\" class=\"cognito-buttons\">\n\t\t<button class=\"cognito-input cognito-submit cognito-button\" type=\"button\" (click)=\"onEnterUsername()\" [disabled]=\"!model.username\">{{ strings.labelSubmit }}</button>\n\t</div>\n\t<div *ngIf=\"srp && !showPasswordField\" class=\"cognito-buttons\">\n\t\t<button class=\"cognito-input cognito-submit cognito-button\" type=\"button\" (click)=\"showPasswordField = true; otp = false; magicLink = false; passkeys = false; sso = false;\" [disabled]=\"!model.username\">{{ strings.labelUseRegularPassword }}</button>\n\t</div>\n\t<div *ngIf=\"srp && showPasswordField\" class=\"cognito-formrow\">\n\t\t<label class=\"cognito-label\" for=\"password\">{{ strings.labelPassword }}</label>\n\t\t<input id=\"password\" autocomplete=\"off\" class=\"cognito-input cognito-text\" type=\"password\" name=\"password\" [(ngModel)]=\"model.password\"/>\n\t</div>\n\t<div *ngIf=\"srp && showPasswordField\" class=\"cognito-buttons\">\n\t\t<button type=\"button\" class=\"a\" (click)=\"onForgotPassword($event)\">{{ strings.labelForgotPassword }}</button>\n\t\t<input class=\"cognito-input cognito-submit cognito-button\" type=\"submit\" [value]=\"strings.labelSubmit\"/>\n\t</div>\n\t<div *ngIf=\"otp && model.showChallengeEntry\" class=\"cognito-formrow\">\n\t\t<label class=\"cognito-label\" for=\"otp\">{{ strings.labelOtpEnter }}</label>\n\t\t<input id=\"otp\" autocomplete=\"off\" class=\"cognito-input cognito-text\" type=\"text\" name=\"otp\" [(ngModel)]=\"model.otp\"/>\n\t</div>\n\t<div *ngIf=\"passkeys && model.showChallengeEntry\" class=\"cognito-formrow\">\n\t\t<label class=\"cognito-label\" for=\"passkey-reg\">{{ strings.labelPasskeyEnter }}</label>\n\t\t<textarea id=\"passkey-reg\" autocomplete=\"off\" class=\"cognito-input cognito-text\" name=\"passkey-reg\" [(ngModel)]=\"model.passkey\"></textarea>\n\t</div>\n\t<div *ngIf=\"otp\" class=\"cognito-buttons\">\n\t\t<button class=\"cognito-input cognito-submit cognito-button\" type=\"button\" (click)=\"getOtp()\" [disabled]=\"!model.username\">{{ model.showChallengeEntry ? strings.labelSubmit : strings.labelOtp }}</button>\n\t</div>\t\n\t<div *ngIf=\"magicLink\" class=\"cognito-buttons\">\n\t\t<button class=\"cognito-input cognito-submit cognito-button\" type=\"button\" (click)=\"getMagicLink()\" [disabled]=\"!model.username\">{{ strings.labelMagicLink }}</button>\n\t</div>\t\n\t<div *ngIf=\"passkeys\" class=\"cognito-buttons\">\n\t\t<button class=\"cognito-input cognito-submit cognito-button\" type=\"button\" (click)=\"getPasskey()\" [disabled]=\"!model.username\">{{ model.showChallengeEntry ? strings.labelSubmit : strings.labelPasskeys }}</button>\n\t</div>\t\n\t<div *ngIf=\"sso && ssoLink\" class=\"cognito-buttons\">\n\t\t<a class=\"cognito-input cognito-submit cognito-button\" type=\"button\" [href]=\"ssoLink\">{{ strings.labelSso }}</a>\n\t</div>\t\n\t<div *ngIf=\"error\" class=\"error\" [innerHtml]=\"error\"></div>\n</form>\n<form *ngIf=\"showForm && formType === CognitoFormType.NewUser\" class=\"cognito-form\" (submit)=\"onNewUser()\">\n\t<button class=\"button close\" (click)=\"showForm=false\" type=\"button\"><span class=\"buttontext\">{{ strings.labelClose }}</span></button>\n\t<div class=\"cognito-formrow\">\n\t\t<label class=\"cognito-label\" for=\"username\">{{ strings.labelEmail }}</label>\n\t\t<input id=\"username\" class=\"cognito-input cognito-text\" type=\"text\" name=\"username\" [(ngModel)]=\"model.username\" disabled />\n\t</div>\n\t<div class=\"cognito-formrow\">\n\t\t<label class=\"cognito-label no-mb\" for=\"new-password\">{{ strings.labelNewPassword }}</label>\n\t\t<p class=\"cognito-sublabel\">{{ strings.labelPasswordRequirement }}</p>\n\t\t<input id=\"new-password\" autocomplete=\"off\" class=\"cognito-input cognito-text\" type=\"password\" name=\"password-new\" [(ngModel)]=\"model.newPassword\"/>\n\t</div>\n\t<div class=\"cognito-formrow\">\n\t\t<label class=\"cognito-label\" for=\"password-confirm\">{{ strings.labelConfirmNewPassword }}</label>\n\t\t<input id=\"password-confirm\" autocomplete=\"off\" class=\"cognito-input cognito-text\" type=\"password\" name=\"password-confirm\" [(ngModel)]=\"model.newPasswordConfirm\"/>\n\t</div>\n\t<div class=\"cognito-formrow\" *ngFor=\"let row of rows\">\n\t\t<label class=\"cognito-label\" for=\"username\">{{ row.label|labeler }}</label>\n\t\t<input [id]=\"row.key\" class=\"cognito-input cognito-text\" type=\"text\" [name]=\"row.key\" [(ngModel)]=\"model[row.key]\"/>\n\t</div>\n\t<div class=\"cognito-buttons\">\n\t\t<input class=\"cognito-input cognito-submit cognito-button\" type=\"submit\" [disabled]=\"newUserFormDisabled()\" [value]=\"strings.labelSubmit\"/>\n\t</div>\t\n\t<div *ngIf=\"error\" class=\"error\" [innerHtml]=\"error\"></div>\n</form>\n<form *ngIf=\"showForm && formType === CognitoFormType.ForcePasswordReset\" class=\"cognito-form\" (submit)=\"onForcePasswordReset()\">\n\t<button class=\"button close\" (click)=\"showForm=false\" type=\"button\"><span class=\"buttontext\">{{ strings.labelClose }}</span></button>\n\t<div *ngIf=\"prompt\" class=\"prompt\" [innerHtml]=\"prompt\"></div>\n\t<div class=\"cognito-formrow\">\n\t\t<label class=\"cognito-label\" for=\"username\">{{ strings.labelEmail }}</label>\n\t\t<input id=\"username\" class=\"cognito-input cognito-text\" type=\"text\" name=\"username\" [(ngModel)]=\"model.username\" disabled />\n\t</div>\n\t<div class=\"cognito-formrow\">\n\t\t<label class=\"cognito-label\" for=\"code\">{{ strings.labelCode }}</label>\n\t\t<input id=\"code\" autocomplete=\"off\" class=\"cognito-input cognito-text\" type=\"text\" name=\"code\" [(ngModel)]=\"model.code\"/>\n\t</div>\n\t<div class=\"cognito-formrow\">\n\t\t<label class=\"cognito-label\" for=\"new-password\">{{ strings.labelNewPassword }}</label>\n\t\t<p class=\"cognito-sublabel\">{{ strings.labelPasswordRequirement }}</p>\n\t\t<input id=\"new-password\" autocomplete=\"off\" class=\"cognito-input cognito-text\" type=\"password\" name=\"password-new\" [(ngModel)]=\"model.newPassword\"/>\n\t</div>\n\t<div class=\"cognito-formrow\">\n\t\t<label class=\"cognito-label\" for=\"password-confirm\">{{ strings.labelConfirmNewPassword }}</label>\n\t\t<input id=\"password-confirm\" autocomplete=\"off\" class=\"cognito-input cognito-text\" type=\"password\" name=\"password-confirm\" [(ngModel)]=\"model.newPasswordConfirm\"/>\n\t</div>\n\t<div class=\"cognito-buttons\">\n\t\t<input class=\"cognito-input cognito-submit cognito-button\" type=\"submit\" [disabled]=\"newUserFormDisabled()\" [value]=\"strings.labelSubmit\"/>\n\t</div>\t\n\t<div *ngIf=\"error\" class=\"error\" [innerHtml]=\"error\"></div>\n</form>\n<form *ngIf=\"showForm && formType === CognitoFormType.UserVerificationRequest\" class=\"cognito-form\" (submit)=\"onRequestVerificationCode()\">\n\t<button class=\"button close\" (click)=\"showForm=false\" type=\"button\"><span class=\"buttontext\">{{ strings.labelClose }}</span></button>\n\t<div *ngIf=\"prompt\" class=\"prompt\" [innerHtml]=\"prompt\"></div>\n\t<div class=\"cognito-formrow\">\n\t\t<label class=\"cognito-label\" for=\"username\">{{ strings.labelEmail }}</label>\n\t\t<input id=\"username\" class=\"cognito-input cognito-text\" type=\"text\" name=\"username\" [(ngModel)]=\"model.username\"/>\n\t</div>\n\t<div class=\"cognito-buttons\">\n\t\t<input class=\"cognito-input cognito-submit cognito-button\" type=\"submit\" [disabled]=\"!model.username\" [value]=\"strings.labelSubmit\"/>\n\t</div>\t\n\t<div *ngIf=\"error\" class=\"error\" [innerHtml]=\"error\"></div>\n</form>\n<form *ngIf=\"showForm && formType === CognitoFormType.UserPasswordReset\" class=\"cognito-form\" (submit)=\"onUserPasswordReset()\">\n\t<button class=\"button close\" (click)=\"showForm=false\" type=\"button\"><span class=\"buttontext\">{{ strings.labelClose }}</span></button>\n\t<div *ngIf=\"prompt\" class=\"prompt\" [innerHtml]=\"prompt\"></div>\n\t<div class=\"cognito-formrow\">\n\t\t<label class=\"cognito-label\" for=\"current-password\">{{ strings.labelCurrentPassword }}</label>\n\t\t<input id=\"current-password\" autocomplete=\"off\" class=\"cognito-input cognito-text\" type=\"password\" name=\"password\" [(ngModel)]=\"model.password\"/>\n\t</div>\n\t<div class=\"cognito-formrow\">\n\t\t<label class=\"cognito-label\" for=\"new-password\">{{ strings.labelNewPassword }}</label>\n\t\t<p class=\"cognito-sublabel\">{{ strings.labelPasswordRequirement }}</p>\n\t\t<input id=\"new-password\" autocomplete=\"off\" class=\"cognito-input cognito-text\" type=\"password\" name=\"password-new\" [(ngModel)]=\"model.newPassword\"/>\n\t</div>\n\t<div class=\"cognito-formrow\">\n\t\t<label class=\"cognito-label\" for=\"password-confirm\">{{ strings.labelConfirmNewPassword }}</label>\n\t\t<input id=\"password-confirm\" autocomplete=\"off\" class=\"cognito-input cognito-text\" type=\"password\" name=\"password-confirm\" [(ngModel)]=\"model.newPasswordConfirm\"/>\n\t</div>\n\t<div class=\"cognito-buttons\">\n\t\t<input class=\"cognito-input cognito-submit cognito-button\" type=\"submit\" [disabled]=\"newUserFormDisabled()\" [value]=\"strings.labelSubmit\"/>\n\t</div>\t\n\t<div *ngIf=\"error\" class=\"error\" [innerHtml]=\"error\"></div>\n</form>\n<form *ngIf=\"showForm && formType === CognitoFormType.PasswordUpdateSuccessful\" class=\"cognito-form\" (submit)=\"showForm = false\">\n\t<div class=\"prompt\" [innerHtml]=\"prompt\"></div>\n\t<div class=\"cognito-buttons\">\n\t\t<input class=\"cognito-input cognito-submit cognito-button\" type=\"submit\" [value]=\"strings.labelClose\"/>\n\t</div>\t\n</form>", styles: [":host{position:fixed;top:0;left:0;right:0;bottom:0;display:flex;z-index:0;opacity:0;justify-content:center;align-items:center;pointer-events:none;color:#4d4d4d}:host p{margin:0;padding:0}:host.render{opacity:1;transition:opacity 1s;pointer-events:auto}.cognito-form{position:relative;background:white;transition:all .25s;box-sizing:border-box;padding:2rem 1rem;width:calc(100% - 2rem);max-height:calc(100% - 2rem);max-width:30rem;overflow:auto;border:solid 1px #ccc;box-shadow:0 0 8px 2px #0000000d}:host.transitioning .cognito-form{opacity:0;transition:all .25s;pointer-events:none}.cognito-form .button.close{position:absolute;right:1rem;top:1rem;width:1rem;height:1rem;overflow:hidden;cursor:pointer;display:flex;align-items:center;justify-content:center;-webkit-appearance:none;appearance:none;background:none;border:solid 1px #ccc}.cognito-form .button.close .buttontext{position:absolute;opacity:0}.cognito-form .button.close:after{content:\"x\"}.cognito-form .prompt{font-weight:700;font-style:italic;margin-bottom:1rem;text-align:center}.cognito-form .error{font-style:italic;color:red;text-align:center;margin-top:1rem}.cognito-label{display:block;text-transform:uppercase;font-family:inherit;font-size:.875rem;font-weight:700}:host p.cognito-sublabel{font-size:14px;font-style:italic;margin-left:1rem}.cognito-text{display:block;width:100%;font-size:1.125rem;padding:.25rem;box-sizing:border-box;color:inherit;font-family:inherit;margin-top:.5rem}.cognito-formrow+.cognito-formrow{margin-top:1.25rem}.cognito-buttons{margin-top:2rem;text-align:center}.cognito-buttons button+button,.cognito-buttons button+input{margin-left:2rem}.cognito-buttons button.a{-webkit-appearance:none;appearance:none;background:none;border:0;text-decoration:underline;cursor:pointer}#passkey-reg{resize:none;height:8rem}\n"] }] }], ctorParameters: function () { return [{ type: i1.CognitoService }]; }, propDecorators: { hostStyle: [{ type: HostBinding, args: ["style"] }], showForm: [{ type: HostBinding, args: ["class.render"] }], transitioning: [{ type: HostBinding, args: ["class.transitioning"] }], poolId: [{ type: Input, args: ["pool-id"] }], providerName: [{ type: Input, args: ["provider-name"] }], clientId: [{ type: Input, args: ["client-id"] }], cognitoUrl: [{ type: Input, args: ["cognito-signin-url"] }], region: [{ type: Input, args: ["region"] }], modalBackground: [{ type: Input, args: ["modal-background"] }], zIndex: [{ type: Input, args: ["z-index"] }], hook: [{ type: Input, args: ["hook"] }], srp: [{ type: Input, args: ["srp"] }], otp: [{ type: Input, args: ["otp"] }], sso: [{ type: Input, args: ["sso"] }], magicLink: [{ type: Input, args: ["magic-link"] }], magicLinkGenerator: [{ type: Input, args: ["magic-link-generator"] }], reloadAfterLinkAuthentication: [{ type: Input, args: ["reload-after-link-authentication"] }], passkeys: [{ type: Input, args: ["passkeys"] }], useLocalStorage: [{ type: Input, args: ["useLocalStorage"] }], idToken: [{ type: Input, args: ["idToken"] }], accessToken: [{ type: Input, args: ["accessToken"] }], refreshToken: [{ type: Input, args: ["refreshToken"] }], ssoLink: [{ type: Input, args: ["sso-link"] }], getUserId: [{ type: Input, args: ["passkeys-get-user-id"] }], generateAuthenticationOptions: [{ type: Input, args: ["passkeys-generate-authentication-options"] }], generateRegistrationOptions: [{ type: Input, args: ["passkeys-generate-registration-options"] }], verifyRegistration: [{ type: Input, args: ["passkeys-verify-registration"] }], verifyAuthentication: [{ type: Input, args: ["passkeys-verify-authentication"] }], onReady: [{ type: Output, args: ["ready"] }], onConnecting: [{ type: Output, args: ["connecting"] }], onAuthenticated: [{ type: Output, args: ["authenticated"] }], onResponse: [{ type: Output, args: ["response"] }], onUsernameEntered: [{ type: Output, args: ["usernameEntered"] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29nbml0by5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcm