UNPKG

@schukai/monster

Version:

Monster is a simple library for creating fast, robust and lightweight websites.

1,353 lines (1,249 loc) 73.7 kB
/** * Copyright © schukai GmbH and all contributing authors, {{copyRightYear}}. All rights reserved. * Node module: @schukai/monster * * This source code is licensed under the GNU Affero General Public License version 3 (AGPLv3). * The full text of the license can be found at: https://www.gnu.org/licenses/agpl-3.0.en.html * * For those who do not wish to adhere to the AGPLv3, a commercial license is available. * Acquiring a commercial license allows you to use this software without complying with the AGPLv3 terms. * For more information about purchasing a commercial license, please contact schukai GmbH. */ import { instanceSymbol } from "../../constants.mjs"; import { addAttributeToken } from "../../dom/attributes.mjs"; import { ATTRIBUTE_ERRORMESSAGE, ATTRIBUTE_ROLE, } from "../../dom/constants.mjs"; import { CustomElement } from "../../dom/customelement.mjs"; import { assembleMethodSymbol, registerCustomElement, } from "../../dom/customelement.mjs"; import { findTargetElementFromEvent, fireEvent } from "../../dom/events.mjs"; import { isFunction } from "../../types/is.mjs"; import { LoginStyleSheet } from "./stylesheet/login.mjs"; import { fireCustomEvent } from "../../dom/events.mjs"; import "./form.mjs"; import "./field-set.mjs"; import "./password.mjs"; import "./message-state-button.mjs"; import "./digits.mjs"; import "../layout/collapse.mjs"; import "../datatable/datasource/rest.mjs"; import { InvalidStyleSheet } from "./stylesheet/invalid.mjs"; import { getLocaleOfDocument } from "../../dom/locale.mjs"; import { getWindow } from "../../dom/util.mjs"; export { Login }; /** * @private * @type {symbol} */ const loginElementSymbol = Symbol("loginElement"); /** * @private * @type {symbol} */ const forgotPasswordLinkSymbol = Symbol("forgotPasswordLink"); /** * @private * @type {symbol} */ const forgotPasswordCollapseSymbol = Symbol("forgotPasswordCollapse"); /** * @private * @type {symbol} */ const loginCollapseSymbol = Symbol("loginCollapse"); /** * @private * @type {symbol} */ const loginLinkSymbol = Symbol("loginLink"); /** * @private * @type {symbol} */ const secondFactorCollapseSymbol = Symbol("secondFactorCollapse"); /** * @private * @type {symbol} */ const resetLoginProcessLinksSymbol = Symbol("resetLoginProcessLink"); /** * @private * @type {symbol} */ const loggedInCollapseSymbol = Symbol("loggedInCollapse"); /** * @private * @type {symbol} */ const loginButtonSymbol = Symbol("loginButton"); /** * @private * @type {symbol} */ const requestLinkButtonSymbol = Symbol("requestLinkButton"); /** * @private * @type {symbol} */ const digitsButtonSymbol = Symbol("digitsButton"); /** * @private * @type {symbol} */ const secondFactorButtonSymbol = Symbol("secondFactorButton"); /** * @private * @type {symbol} */ const digitsCollapseSymbol = Symbol("digitsCollapse"); /** * A Login * * @fragments /fragments/components/form/login/ * * @example /examples/components/form/login-simple * * @since 3.113.0 * @copyright schukai GmbH * @summary A beautiful Login that can make your life easier and also looks good. It supports a lot of features. * * @fires login-success * @fires redirect-to-first-success-url * @fires second-factor-success * @fires digits-success * @fires monster-login-clicked */ class Login extends CustomElement { /** * This method is called by the `instanceof` operator. * @returns {symbol} */ static get [instanceSymbol]() { return Symbol.for("@schukai/monster/components/form/login@@instance"); } /** * @return {void} */ [assembleMethodSymbol]() { super[assembleMethodSymbol](); setTimeout(() => { initControlReferences.call(this); initEventHandler.call(this); setTimeout(() => { this.shadowRoot.querySelector("input[name='username']").focus(); }, 100); }, 0); } /** * To set the options via the HTML Tag, the attribute `data-monster-options` must be used. * @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control} * * The individual configuration values can be found in the table. * * @property {Object} templates Template definitions * @property {string} templates.main The main HTML template used for rendering the login form * @property {Object} labels Label definitions used for localization and form messages * @property {string} labels.username Label for the username or email field * @property {string} labels.password Label for the password field * @property {string} labels.login Label for the login button * @property {string} labels.forgotPasswordLink Text for the "forgot password" link * @property {string} labels.mailAddress Label for the email input in password reset flow * @property {string} labels.requestLink Label for the button that sends a password reset code * @property {string} labels.digits Label for the digits input field * @property {string} labels.loginLink Label for the back-to-login link * @property {string} labels.secondFactor Label for the second factor authentication input * @property {string} labels.sendDigits Label for the button that submits the digits input * @property {string} labels.sendSecondFactorDigits Label for the button that submits the second factor code * @property {string} labels.resetLoginProcess Label for the link to return to the login form * @property {string} labels.messageEmptyUserName Message shown when username is empty * @property {string} labels.messageEmptyPassword Message shown when password is empty * @property {string} labels.messageEmptyBoth Message shown when both username and password are empty * @property {string} labels.messageEmptyEmail Message shown when email field is empty * @property {string} labels.messageInvalidEmail Message shown when an invalid email address is entered * @property {string} labels.digitsEmpty Message shown when digits field is empty * @property {string} labels.digitsInvalid Message shown when digits input is invalid * @property {string} labels.messageLoginFailed Message shown on failed login attempt * @property {string} labels.messageForbidden Message shown on successful login with insufficient permissions * @property {string} labels.messageSomethingWentWrong Fallback error message * @property {string} labels.messageThisFormIsNotConfigured Message shown if no backend URL is configured * @property {string} labels.messagePasswordResetDisabled Message shown if password reset is disabled due to 2FA * @property {Object} classes Class definitions for visual styling * @property {string} classes.usernameInvalid CSS class applied when username is invalid * @property {string} classes.passwordInvalid CSS class applied when password is invalid * @property {string} classes.emailInvalid CSS class applied when email input is invalid * @property {string} classes.button CSS class applied to all form buttons * @property {boolean} disabled If true, disables interaction with the component * @property {Object} features Feature flags to toggle optional behavior * @property {boolean} features.forgotPassword Enables the forgot password flow * @property {boolean} features.redirectToFirstSuccessUrl If true, redirects to the first success URL after login * @property {Object} actions Action definitions for custom event handling * @property {Function} actions.click Callback function for generic click actions within the login component * @property {Object} callbacks Optional callback hooks for modifying internal behavior * @property {Function} callbacks.username A function that receives and can transform the entered username before submission * @property {Function} callbacks.forgotPassword A function that receives and can transform the entered email before submission * @property {number} digits Number of digits required for second factor or password reset code input * @property {Object[]} successUrls List of URLs shown after successful login (e.g., home or logout) * @property {string} successUrls.label Label for the success URL (displayed) * @property {string} successUrls.url Actual target URL * @property {number} timeoutForMessage Duration in milliseconds to show error messages * @property {number} timeoutForSuccess Duration in milliseconds before triggering the post-login success state * @property {Object} accessKeys Keyboard access keys for accessibility and shortcuts * @property {string} accessKeys.loginLink Access key for switching to login form * @property {string} accessKeys.username Access key for focusing the username field * @property {string} accessKeys.password Access key for focusing the password field * @property {Object} fetch Definitions for backend requests to support login workflows * @property {Object} placeholder Placeholder text for input fields * @property {string} placeholder.username Placeholder for the username field * @property {string} placeholder.password Placeholder for the password field * @property {string} placeholder.email Placeholder for the email field * @property {Object} fetch.login Fetch config for login request * @property {string} fetch.login.url Endpoint to post login credentials to * @property {string} fetch.login.method HTTP method for login (e.g., "POST") * @property {string} fetch.login.mode Fetch mode (e.g., "same-origin") * @property {Object} fetch.login.headers HTTP headers to be sent with the login request * @property {string} fetch.login.headers.accept Accept header value * @property {string} fetch.login.headers.Content-Type Content-Type header value * @property {string} fetch.login.credentials Credential mode (e.g., "same-origin") * @property {Object} fetch.forgotPassword Fetch config for password reset code request * @property {string} fetch.forgotPassword.url Endpoint to request a reset link/code * @property {string} fetch.forgotPassword.method HTTP method * @property {string} fetch.forgotPassword.mode Fetch mode * @property {Object} fetch.forgotPassword.headers Headers * @property {string} fetch.forgotPassword.headers.accept Accept header * @property {string} fetch.forgotPassword.headers.Content-Type Content-Type header * @property {string} fetch.forgotPassword.credentials Credential mode * @property {Object} fetch.digits Fetch config for submitting password reset code * @property {string} fetch.digits.url Endpoint for validating the code * @property {string} fetch.digits.method HTTP method * @property {string} fetch.digits.mode Fetch mode * @property {Object} fetch.digits.headers Headers * @property {string} fetch.digits.headers.accept Accept header * @property {string} fetch.digits.headers.Content-Type Content-Type header * @property {string} fetch.digits.credentials Credential mode * @property {Object} fetch.secondFactor Fetch config for submitting second factor code * @property {string} fetch.secondFactor.url Endpoint to validate second factor code * @property {string} fetch.secondFactor.method HTTP method * @property {string} fetch.secondFactor.mode Fetch mode * @property {Object} fetch.secondFactor.headers Headers * @property {string} fetch.secondFactor.headers.accept Accept header * @property {string} fetch.secondFactor.headers.Content-Type Content-Type header * @property {string} fetch.secondFactor.credentials Credential mode */ get defaults() { return Object.assign({}, super.defaults, { templates: { main: getTemplate(), }, labels: getTranslations(), classes: { usernameInvalid: "", passwordInvalid: "", emailInvalid: "", button: "monster-button-outline-primary", }, disabled: false, features: { forgotPassword: true, redirectToFirstSuccessUrl: false, }, actions: {}, callbacks: { username: null, forgotPassword: null, }, digits: 6, successUrls: [ { label: "Home", url: "/", }, { label: "Logout", url: "/logout", }, ], timeoutForMessage: 3500, timeoutForSuccess: 1000, accessKeys: { loginLink: "x", username: "u", password: "p", }, placeholder: { username: "", password: "", email: "", }, fetch: { login: { url: "", method: "POST", mode: "same-origin", headers: { Accept: "application/json", "Content-Type": "application/json; charset=utf-8", }, credentials: "same-origin", }, forgotPassword: { url: "", method: "POST", mode: "same-origin", headers: { Accept: "application/json", "Content-Type": "application/json; charset=utf-8", }, credentials: "same-origin", }, digits: { url: "", method: "POST", mode: "same-origin", headers: { Accept: "application/json", "Content-Type": "application/json; charset=utf-8", }, credentials: "same-origin", }, secondFactor: { url: "", method: "POST", mode: "same-origin", headers: { Accept: "application/json", "Content-Type": "application/json; charset=utf-8", }, credentials: "same-origin", }, }, }); } /** * Opens the login collapse and focuses the username control. * * @returns {Login} */ openLogin() { this[loginCollapseSymbol].open(); this.shadowRoot.querySelector("input[name='username']").focus(); return this; } /** * Opens the forgot password collapse. If the feature `forgotPassword` is not enabled, an error will be thrown. * * @returns {Login} * @throws {Error} If the feature is not enabled */ openForgotPassword() { if (!this.getOption("features.forgotPassword")) { throw new Error("Forgot Password is not enabled"); } this[forgotPasswordCollapseSymbol].open(); return this; } /** * Opens the second factor collapse and focuses the second factor control. * @returns {Login} */ openSecondFactor() { this[secondFactorCollapseSymbol].open(); this.shadowRoot.getElementById("secondFactorButton").focus(); return this; } /** * Opens the digits collapse and focuses the digit control. * @returns {Login} */ openDigits() { this[digitsCollapseSymbol].open(); this.shadowRoot.getElementById("digitsControl").focus(); return this; } /** * Opens the logged in collapse. If the feature `redirectToFirstSuccessUrl` is enabled, the user will be redirected to the first success URL. * * @returns {Login} */ openLoggedIn() { fireEvent(this, "login-success"); if (this.getOption("features.redirectToFirstSuccessUrl")) { setTimeout(() => { fireEvent(this, "redirect-to-first-success-url"); const successUrl = this.getOption("successUrls"); if (successUrl.length > 0) { const success = successUrl[0].url; if (success) { getWindow().location.href = success; } } }, this.getOption("timeoutForSuccess")); return; } this[loggedInCollapseSymbol].open(); return this; } /** * @return {string} */ static getTag() { return "monster-login"; } /** * @return {CSSStyleSheet[]} */ static getCSSStyleSheet() { return [LoginStyleSheet, InvalidStyleSheet]; } } function getTranslations() { const locale = getLocaleOfDocument(); switch (locale.language) { case "de": return { username: "Benutzername oder E-Mail", password: "Passwort", login: "Anmelden", forgotPasswordLink: "Passwort vergessen?", mailAddress: "E-Mail-Adresse", requestLink: "Code anfordern", digits: "Code", loginLink: "Anmelden", secondFactor: "Zweiter Faktor Code", sendDigits: "Code senden", sendSecondFactorDigits: "Code senden", resetLoginProcess: "Zurück zum Login", messageEmptyUserName: "Bitte geben Sie Ihren Benutzernamen ein", messageEmptyPassword: "Bitte geben Sie Ihr Passwort ein", messageEmptyBoth: "Bitte geben Sie Ihren Benutzernamen und Ihr Passwort ein", messageEmptyEmail: "Bitte geben Sie Ihre E-Mail-Adresse ein", messageInvalidEmail: "Bitte geben Sie eine gültige E-Mail-Adresse ein", digitsEmpty: "Bitte geben Sie Ihren Code ein", digitsInvalid: "Bitte geben Sie einen gültigen Code ein", messageLoginFailed: "Anmeldung fehlgeschlagen, bitte überprüfen Sie Ihre Eingaben.", messageForbidden: "Die Anmeldung war erfolgreich, aber Sie haben keine Berechtigung. Sie können sich <b>nicht</b> anmelden.<br>Sie können einen anderen Benutzer auswählen oder sich an den Administrator wenden.", messageSomethingWentWrong: "Etwas ist schief gelaufen, bitte versuchen Sie es später erneut", messageThisFormIsNotConfigured: "Dieses Formular ist nicht konfiguriert.", messagePasswordResetDisabled: "Sie können keinen Code anfordern, da die<br>Zwei-Faktor-Authentifizierung bei Ihrem Konto aktiviert ist.<br>Bitte kontaktieren Sie den Administrator.", }; case "es": return { username: "Nombre de usuario o correo electrónico", password: "Contraseña", login: "Iniciar sesión", forgotPasswordLink: "¿Olvidaste tu contraseña?", mailAddress: "Dirección de correo electrónico", requestLink: "Solicitar enlace", digits: "Código", loginLink: "Iniciar sesión", secondFactor: "Código de segundo factor", sendDigits: "Enviar código", sendSecondFactorDigits: "Enviar código", resetLoginProcess: "Volver al inicio de sesión", messageEmptyUserName: "Por favor ingrese su nombre de usuario", messageEmptyPassword: "Por favor ingrese su contraseña", messageEmptyBoth: "Por favor ingrese su nombre de usuario y contraseña", messageEmptyEmail: "Por favor ingrese su dirección de correo electrónico", messageInvalidEmail: "Por favor ingrese una dirección de correo electrónico válida", digitsEmpty: "Por favor ingrese su código", digitsInvalid: "Por favor ingrese un código válido", messageLoginFailed: "Error al iniciar sesión, por favor verifique sus datos.", messageForbidden: "El inicio de sesión fue exitoso, pero no tienes permisos. <b>No puedes</b> iniciar sesión.<br>Puedes seleccionar otro usuario o contactar al administrador.", messageSomethingWentWrong: "Algo salió mal, por favor intenta de nuevo más tarde.", messageThisFormIsNotConfigured: "Este formulario no está configurado.", messagePasswordResetDisabled: "Esta función no funciona porque la autenticación de dos factores está activada en su cuenta. Por favor, póngase en contacto con el administrador.", }; case "zh": return { username: "用户名或电子邮箱", password: "密码", login: "登录", forgotPasswordLink: "忘记密码?", mailAddress: "电子邮件地址", requestLink: "请求链接", digits: "验证码", loginLink: "登录", secondFactor: "二次验证码", sendDigits: "发送验证码", sendSecondFactorDigits: "发送验证码", resetLoginProcess: "返回登录", messageEmptyUserName: "请输入用户名", messageEmptyPassword: "请输入密码", messageEmptyBoth: "请输入用户名和密码", messageEmptyEmail: "请输入电子邮件地址", messageInvalidEmail: "请输入有效的电子邮件地址", digitsEmpty: "请输入验证码", digitsInvalid: "请输入有效的验证码", messageLoginFailed: "登录失败,请检查您的输入。", messageForbidden: "登录成功,但您没有权限。您<b>不能</b>登录。<br>您可以选择其他用户或联系管理员。", messageSomethingWentWrong: "出了点问题,请稍后再试。", messageThisFormIsNotConfigured: "此表单尚未配置。", messagePasswordResetDisabled: "此功能无法使用,因为您的帐户启用了双因素身份验证。请联系管理员。", }; case "hi": return { username: "उपयगकर नम य ई-मल", password: "पसवर", login: "लग इन कर", forgotPasswordLink: "पसवर भल गए?", mailAddress: "ई-मल पत", requestLink: "लक क अनरध कर", digits: "कड", loginLink: "लग इन कर", secondFactor: "दसर फकर कड", sendDigits: "कड भज", sendSecondFactorDigits: "कड भज", resetLoginProcess: "लगन पर वपस जए", messageEmptyUserName: "कपय अपन उपयगकर नम दर कर", messageEmptyPassword: "कपय अपन पसवर दर कर", messageEmptyBoth: "कपय अपन उपयगकर नम और पसवर दर कर", messageEmptyEmail: "कपय अपन ई-मल पत दर कर", messageInvalidEmail: "कपय एक वध ई-मल पत दर कर", digitsEmpty: "कपय अपन कड दर कर", digitsInvalid: "कपय एक वध कड दर कर", messageLoginFailed: "लगन वफल हआ, कपय अपन जनकर क जच कर।", messageForbidden: "लगन सफल रह लकन आपक पस अनमत नह ह। आप <b>लगन नह</b> कर सकत।<br>आप दसर उपयगकर चन सकत ह य पशसक स सपर कर सकत ह।", messageSomethingWentWrong: "कछ गलत हआ, कपय बद म पन पयस कर।", messageThisFormIsNotConfigured: "यह फर कनगर नह ह।", messagePasswordResetDisabled: "यह सवध कम नह करत कक आपक खत म द घटक पमणकरण सकम ह। कपय पशसक स सपर कर।", }; case "bn": return { username: "ইউজরনম ব ই-মইল", password: "পসওযর", login: "লগইন করন", forgotPasswordLink: "পসওযর ভল গছন?", mailAddress: "ই-মইল ঠকন", requestLink: "লক অনরধ করন", digits: "কড", loginLink: "লগইন করন", secondFactor: "দতয ফকর কড", sendDigits: "কড পঠন", sendSecondFactorDigits: "কড পঠন", resetLoginProcess: "লগইন ফর যন", messageEmptyUserName: "দয কর আপনর ইউজরনম লখন", messageEmptyPassword: "দয কর আপনর পসওযর লখন", messageEmptyBoth: "দয কর আপনর ইউজরনম এব পসওযর লখন", messageEmptyEmail: "দয কর আপনর ই-মইল ঠকন লখন", messageInvalidEmail: "দয কর একট বধ ই-মইল ঠকন লখন", digitsEmpty: "দয কর আপনর কড লখন", digitsInvalid: "দয কর একট বধ কড লখন", messageLoginFailed: "লগইন বর হযছ, দয কর আপনর ইনপট পরক করন।", messageForbidden: "লগইন সফল হযছ, কন আপনর অনমত নই। আপন <b>লগইন করত পরবন ন</b>।<br>আপন অন ইউজর নরচন করত পরন অথব অযডমনসটরর সথ যগযগ করত পরন।", messageSomethingWentWrong: "কছ ভল হযছ, দয কর পর আবর চষ করন।", messageThisFormIsNotConfigured: "এই ফরট কনফগর কর হযন।", messagePasswordResetDisabled: "এই ফশনট করকর নয করণ আপনর অযকউন দট ফকর পমণকরণ সকয কর আছ। দয কর পশসকর সথ যগযগ করন।", }; case "pt": // Portuguese return { username: "Nome de usuário ou e-mail", password: "Senha", login: "Entrar", forgotPasswordLink: "Esqueceu a senha?", mailAddress: "Endereço de e-mail", requestLink: "Solicitar link", digits: "Código", loginLink: "Entrar", secondFactor: "Código do segundo fator", sendDigits: "Enviar código", sendSecondFactorDigits: "Enviar código", resetLoginProcess: "Voltar ao login", messageEmptyUserName: "Por favor, insira seu nome de usuário", messageEmptyPassword: "Por favor, insira sua senha", messageEmptyBoth: "Por favor, insira seu nome de usuário e senha", messageEmptyEmail: "Por favor, insira seu endereço de e-mail", messageInvalidEmail: "Por favor, insira um endereço de e-mail válido", digitsEmpty: "Por favor, insira seu código", digitsInvalid: "Por favor, insira um código válido", messageLoginFailed: "Falha no login, verifique suas informações.", messageForbidden: "Login foi bem-sucedido, mas você não tem permissão. Você <b>não pode</b> entrar.<br>Você pode escolher outro usuário ou entrar em contato com o administrador.", messageSomethingWentWrong: "Algo deu errado, tente novamente mais tarde.", messageThisFormIsNotConfigured: "Este formulário não está configurado.", messagePasswordResetDisabled: "Esta função não funciona porque a autenticação de dois fatores<br>está ativada em sua conta. Por favor, entre em contato com o administrador.", }; case "ru": // Russian return { username: "Имя пользователя или электронная почта", password: "Пароль", login: "Войти", forgotPasswordLink: "Забыли пароль?", mailAddress: "Адрес электронной почты", requestLink: "Запросить ссылку", digits: "Код", loginLink: "Войти", secondFactor: "Код второго фактора", sendDigits: "Отправить код", sendSecondFactorDigits: "Отправить код", resetLoginProcess: "Вернуться к входу", messageEmptyUserName: "Пожалуйста, введите имя пользователя", messageEmptyPassword: "Пожалуйста, введите пароль", messageEmptyBoth: "Пожалуйста, введите имя пользователя и пароль", messageEmptyEmail: "Пожалуйста, введите адрес электронной почты", messageInvalidEmail: "Пожалуйста, введите действительный адрес электронной почты", digitsEmpty: "Пожалуйста, введите код", digitsInvalid: "Пожалуйста, введите действительный код", messageLoginFailed: "Ошибка входа, проверьте введенные данные.", messageForbidden: "Вход выполнен, но у вас нет прав. Вы <b>не можете</b> войти.<br>Вы можете выбрать другого пользователя или связаться с администратором.", messageSomethingWentWrong: "Что-то пошло не так, попробуйте позже.", messageThisFormIsNotConfigured: "Эта форма не настроена.", messagePasswordResetDisabled: "Эта функция не работает, потому что двухфакторная аутентификация<br> включена в вашей учетной записи. Пожалуйста, свяжитесь с администратором.", }; case "ja": // Japanese return { username: "ユーザー名またはメールアドレス", password: "パスワード", login: "ログイン", forgotPasswordLink: "パスワードを忘れましたか?", mailAddress: "メールアドレス", requestLink: "リンクをリクエスト", digits: "コード", loginLink: "ログイン", secondFactor: "二要素コード", sendDigits: "コードを送信", sendSecondFactorDigits: "コードを送信", resetLoginProcess: "ログインに戻る", messageEmptyUserName: "ユーザー名を入力してください", messageEmptyPassword: "パスワードを入力してください", messageEmptyBoth: "ユーザー名とパスワードを入力してください", messageEmptyEmail: "メールアドレスを入力してください", messageInvalidEmail: "有効なメールアドレスを入力してください", digitsEmpty: "コードを入力してください", digitsInvalid: "有効なコードを入力してください", messageLoginFailed: "ログインに失敗しました。入力内容をご確認ください。", messageForbidden: "ログイン成功しましたが、権限がありません。<b>ログインできません</b>。<br>他のユーザーを選択するか、管理者に連絡してください。", messageSomethingWentWrong: "問題が発生しました。後でもう一度お試しください。", messageThisFormIsNotConfigured: "このフォームは設定されていません。", messagePasswordResetDisabled: "この機能は使用できません。アカウントで二要素認証が有効になっているため、管理者に連絡してください。", }; case "pa": // Western Punjabi return { username: "ਵਰਤਕਰ ਨਮ ਜ ਈ-ਮਲ", password: "ਪਸਵਰਡ", login: "ਲਗਨ ਕਰ", forgotPasswordLink: "ਪਸਵਰਡ ਭਲ ਗਏ?", mailAddress: "ਈ-ਮਲ ਪਤ", requestLink: "ਲਕ ਦ ਬਨਤ ਕਰ", digits: "ਕਡ", loginLink: "ਲਗਨ ਕਰ", secondFactor: "ਦਜ ਫਕਟਰ ਕਡ", sendDigits: "ਕਡ ਭਜ", sendSecondFactorDigits: "ਕਡ ਭਜ", resetLoginProcess: "ਲਗਨ 'ਤ ਵਪਸ ਜਓ", messageEmptyUserName: "ਕਰਪ ਕਰਕ ਆਪਣ ਵਰਤਕਰ ਨਮ ਦਰਜ ਕਰ", messageEmptyPassword: "ਕਰਪ ਕਰਕ ਆਪਣ ਪਸਵਰਡ ਦਰਜ ਕਰ", messageEmptyBoth: "ਕਰਪ ਕਰਕ ਆਪਣ ਵਰਤਕਰ ਨਮ ਤ ਪਸਵਰਡ ਦਰਜ ਕਰ", messageEmptyEmail: "ਕਰਪ ਕਰਕ ਆਪਣ ਈ-ਮਲ ਪਤ ਦਰਜ ਕਰ", messageInvalidEmail: "ਕਰਪ ਕਰਕ ਇਕ ਵਧ ਈ-ਮਲ ਪਤ ਦਰਜ ਕਰ", digitsEmpty: "ਕਰਪ ਕਰਕ ਆਪਣ ਕਡ ਦਰਜ ਕਰ", digitsInvalid: "ਕਰਪ ਕਰਕ ਇਕ ਵਧ ਕਡ ਦਰਜ ਕਰ", messageLoginFailed: "ਲਗਨ ਅਸਫਲ ਹਇਆ, ਕਰਪ ਕਰਕ ਆਪਣ ਜਣਕਰ ਦ ਜਚ ਕਰ।", messageForbidden: "ਲਗਨ ਸਫਲ ਹਇਆ, ਪਰ ਤਹਡ ਕਲ ਅਧਕਰ ਨਹ ਹਨ। ਤਸ <b>ਲਗਨ ਨਹ</b> ਕਰ ਸਕਦ।<br>ਤਸ ਹਰ ਵਰਤਕਰ ਚਣ सकत ਹ ਜ ਪਰਬਧਕ ਨਲ ਸਪਰਕ ਕਰ ਸਕਦ ਹ।", messageSomethingWentWrong: "ਕਝ ਗਲਤ ਹ ਗਆ, ਕਰਪ ਕਰਕ ਬਅਦ ਵਚ ਮੜ ਕਸਸ ਕਰ।", messageThisFormIsNotConfigured: "ਇਸ ਫਰਮ ਨ ਸਰਚਤ ਨਹ ਕਤ ਗਆ ਹ।", messagePasswordResetDisabled: "ਇਹ ਫਕਸਨ ਕਮ ਨਹ ਕਰਦ ਕਉਕ ਤਹਡ ਖਤ ਵਚ ਦ ਫਕਟਰ ਪਰਮਣਕਰਣ ਸਰਗਰਮ ਹ। ਕਰਪ ਕਰਕ ਪਰਬਧਕ ਨਲ ਸਪਰਕ ਕਰ।", }; case "mr": // Marathi return { username: "वपरकरनव कव ईमल", password: "सकतशब", login: "पवश कर", forgotPasswordLink: "सकतशब वसरलत क?", mailAddress: "ईमल पत", requestLink: "लकच वनत कर", digits: "कड", loginLink: "पवश कर", secondFactor: "दसर घटक कड", sendDigits: "कड पठव", sendSecondFactorDigits: "कड पठव", resetLoginProcess: "पवशवर परत ज", messageEmptyUserName: "कपय आपल वपरकरनव पवष कर", messageEmptyPassword: "कपय आपल सकतशब पवष कर", messageEmptyBoth: "कपय आपल वपरकरनव आण सकतशब पवष कर", messageEmptyEmail: "कपय आपल ईमल पत पवष कर", messageInvalidEmail: "कपय वध ईमल पत पवष कर", digitsEmpty: "कपय आपल कड पवष कर", digitsInvalid: "कपय वध कड पवष कर", messageLoginFailed: "पवश अयशस, कपय आपल महत तपस.", messageForbidden: "पवश यशस झल, परत आपलकड परवन नह. आपण <b>पवश कर शकत नह</b>.<br>आपण दसर वपरकर नवड शकत कव ववसपकश सपर सध शकत.", messageSomethingWentWrong: "कहतर चकल, कपय नतर पन पयत कर.", messageThisFormIsNotConfigured: "ह फर सरचत कलल नह.", messagePasswordResetDisabled: "य करच कमगर करत नह करण आपल खतत दन घटक पमणकरण सकय कल आह. कपय ववसपकश सपर सध.", }; case "fr": // French return { username: "Nom d'utilisateur ou e-mail", password: "Mot de passe", login: "Connexion", forgotPasswordLink: "Mot de passe oublié ?", mailAddress: "Adresse e-mail", requestLink: "Demander un lien", digits: "Code", loginLink: "Connexion", secondFactor: "Code du deuxième facteur", sendDigits: "Envoyer le code", sendSecondFactorDigits: "Envoyer le code", resetLoginProcess: "Retour à la connexion", messageEmptyUserName: "Veuillez entrer votre nom d'utilisateur", messageEmptyPassword: "Veuillez entrer votre mot de passe", messageEmptyBoth: "Veuillez entrer votre nom d'utilisateur et votre mot de passe", messageEmptyEmail: "Veuillez entrer votre adresse e-mail", messageInvalidEmail: "Veuillez entrer une adresse e-mail valide", digitsEmpty: "Veuillez entrer votre code", digitsInvalid: "Veuillez entrer un code valide", messageLoginFailed: "Échec de la connexion, veuillez vérifier vos informations.", messageForbidden: "La connexion a réussi, mais vous n'avez pas les permissions. Vous <b>ne pouvez pas</b> vous connecter.<br>Vous pouvez choisir un autre utilisateur ou contacter l'administrateur.", messageSomethingWentWrong: "Une erreur s'est produite, veuillez réessayer plus tard.", messageThisFormIsNotConfigured: "Ce formulaire n'est pas configuré.", messagePasswordResetDisabled: "Cette fonctionnalité ne fonctionne pas car l'authentification à deux facteurs est activée sur<br>votre compte. Veuillez contacter l'administrateur.", }; case "it": // Italian return { username: "Nome utente o e-mail", password: "Password", login: "Accedi", forgotPasswordLink: "Password dimenticata?", mailAddress: "Indirizzo e-mail", requestLink: "Richiedi link", digits: "Codice", loginLink: "Accedi", secondFactor: "Codice a due fattori", sendDigits: "Invia codice", sendSecondFactorDigits: "Invia codice", resetLoginProcess: "Torna al login", messageEmptyUserName: "Per favore, inserisci il tuo nome utente", messageEmptyPassword: "Per favore, inserisci la tua password", messageEmptyBoth: "Per favore, inserisci il tuo nome utente e la tua password", messageEmptyEmail: "Per favore, inserisci il tuo indirizzo e-mail", messageInvalidEmail: "Per favore, inserisci un indirizzo e-mail valido", digitsEmpty: "Per favore, inserisci il tuo codice", digitsInvalid: "Per favore, inserisci un codice valido", messageLoginFailed: "Accesso fallito, verifica i tuoi dati.", messageForbidden: "Accesso riuscito, ma non hai i permessi. Non puoi accedere.<br>Puoi scegliere un altro account o contattare l'amministratore.", messageSomethingWentWrong: "Qualcosa è andato storto, riprova più tardi.", messageThisFormIsNotConfigured: "Questo modulo non è configurato.", messagePasswordResetDisabled: "Questa funzione non funziona perché l'autenticazione a due<br>fattori è attiva sul tuo account. Contatta l'amministratore.", }; case "nl": // Dutch return { username: "Gebruikersnaam of e-mail", password: "Wachtwoord", login: "Inloggen", forgotPasswordLink: "Wachtwoord vergeten?", mailAddress: "E-mailadres", requestLink: "Link aanvragen", digits: "Code", loginLink: "Inloggen", secondFactor: "Tweede factor code", sendDigits: "Code verzenden", sendSecondFactorDigits: "Code verzenden", resetLoginProcess: "Terug naar inloggen", messageEmptyUserName: "Voer uw gebruikersnaam in", messageEmptyPassword: "Voer uw wachtwoord in", messageEmptyBoth: "Voer uw gebruikersnaam en wachtwoord in", messageEmptyEmail: "Voer uw e-mailadres in", messageInvalidEmail: "Voer een geldig e-mailadres in", digitsEmpty: "Voer uw code in", digitsInvalid: "Voer een geldige code in", messageLoginFailed: "Inloggen mislukt, controleer uw gegevens.", messageForbidden: "Inloggen geslaagd, maar u heeft geen permissies. U <b>kunt niet</b> inloggen.<br>U kunt een andere gebruiker selecteren of de beheerder contacteren.", messageSomethingWentWrong: "Er is iets fout gegaan, probeer het later opnieuw.", messageThisFormIsNotConfigured: "Dit formulier is niet geconfigureerd.", messagePasswordResetDisabled: "Deze functie werkt niet omdat tweefactorauthenticatie is<br>ingeschakeld op uw account. Neem contact op met de beheerder.", }; case "sv": // Swedish return { username: "Användarnamn eller e-post", password: "Lösenord", login: "Logga in", forgotPasswordLink: "Glömt lösenord?", mailAddress: "E-postadress", requestLink: "Begär länk", digits: "Kod", loginLink: "Logga in", secondFactor: "Tvåfaktorkod", sendDigits: "Skicka kod", sendSecondFactorDigits: "Skicka kod", resetLoginProcess: "Tillbaka till inloggning", messageEmptyUserName: "Ange ditt användarnamn", messageEmptyPassword: "Ange ditt lösenord", messageEmptyBoth: "Ange ditt användarnamn och lösenord", messageEmptyEmail: "Ange din e-postadress", messageInvalidEmail: "Ange en giltig e-postadress", digitsEmpty: "Ange din kod", digitsInvalid: "Ange en giltig kod", messageLoginFailed: "Inloggning misslyckades, kontrollera dina uppgifter.", messageForbidden: "Inloggningen lyckades, men du har inte behörighet. Du <b>kan inte</b> logga in.<br>Du kan välja en annan användare eller kontakta administratören.", messageSomethingWentWrong: "Något gick fel, försök igen senare.", messageThisFormIsNotConfigured: "Detta formulär är inte konfigurerat.", messagePasswordResetDisabled: "Denna funktion fungerar inte eftersom tvåfaktorsautentisering är aktiverad på ditt konto. Kontakta administratören.", }; case "pl": // Polish return { username: "Nazwa użytkownika lub e-mail", password: "Hasło", login: "Zaloguj się", forgotPasswordLink: "Zapomniałeś hasła?", mailAddress: "Adres e-mail", requestLink: "Zażądaj linku", digits: "Kod", loginLink: "Zaloguj się", secondFactor: "Kod drugiego czynnika", sendDigits: "Wyślij kod", sendSecondFactorDigits: "Wyślij kod", resetLoginProcess: "Powrót do logowania", messageEmptyUserName: "Wprowadź swoją nazwę użytkownika", messageEmptyPassword: "Wprowadź swoje hasło", messageEmptyBoth: "Wprowadź swoją nazwę użytkownika i hasło", messageEmptyEmail: "Wprowadź swój adres e-mail", messageInvalidEmail: "Wprowadź prawidłowy adres e-mail", digitsEmpty: "Wprowadź swój kod", digitsInvalid: "Wprowadź prawidłowy kod", messageLoginFailed: "Logowanie nie powiodło się, sprawdź swoje dane.", messageForbidden: "Logowanie powiodło się, ale nie masz uprawnień. <b>Nie możesz</b> się zalogować.<br>Możesz wybrać innego użytkownika lub skontaktować się z administratorem.", messageSomethingWentWrong: "Coś poszło nie tak, spróbuj ponownie później.", messageThisFormIsNotConfigured: "Ten formularz nie jest skonfigurowany.", messagePasswordResetDisabled: "Ta funkcja nie działa, ponieważ włączona jest autoryzacja dwuetapowa na twoim koncie. Skontaktuj się z administratorem.", }; case "da": // Danish return { username: "Brugernavn eller e-mail", password: "Adgangskode", login: "Log ind", forgotPasswordLink: "Glemt adgangskode?", mailAddress: "E-mail-adresse", requestLink: "Anmod om link", digits: "Kode", loginLink: "Log ind", secondFactor: "Tofaktorkode", sendDigits: "Send kode", sendSecondFactorDigits: "Send kode", resetLoginProcess: "Tilbage til log ind", messageEmptyUserName: "Indtast dit brugernavn", messageEmptyPassword: "Indtast din adgangskode", messageEmptyBoth: "Indtast dit brugernavn og din adgangskode", messageEmptyEmail: "Indtast din e-mail-adresse", messageInvalidEmail: "Indtast en gyldig e-mail-adresse", digitsEmpty: "Indtast din kode", digitsInvalid: "Indtast en gyldig kode", messageLoginFailed: "Login mislykkedes, kontrollér dine oplysninger.", messageForbidden: "Login lykkedes, men du har ikke tilladelse. Du <b>kan ikke</b> logge ind.<br>Du kan vælge en anden bruger eller kontakte administratoren.", messageSomethingWentWrong: "Noget gik galt, prøv igen senere.", messageThisFormIsNotConfigured: "Denne formular er ikke konfigureret.", messagePasswordResetDisabled: "Denne funktion fungerer ikke, fordi tofaktorautentificering<br>er aktiveret på din konto. Kontakt administratoren.", }; case "no": // Norwegian return { username: "Brukernavn eller e-post", password: "Passord", login: "Logg inn", forgotPasswordLink: "Glemt passord?", mailAddress: "E-postadresse", requestLink: "Be om lenke", digits: "Kode", loginLink: "Logg inn", secondFactor: "Tofaktorkode", sendDigits: "Send kode", sendSecondFactorDigits: "Send kode", resetLoginProcess: "Tilbake til innlogging", messageEmptyUserName: "Vennligst skriv inn brukernavnet ditt", messageEmptyPassword: "Vennligst skriv inn passordet ditt", messageEmptyBoth: "Vennligst skriv inn brukernavn og passord", messageEmptyEmail: "Vennligst skriv inn e-postadressen din", messageInvalidEmail: "Vennligst skriv inn en gyldig e-postadresse", digitsEmpty: "Vennligst skriv inn koden din", digitsInvalid: "Vennligst skriv inn en gyldig kode", messageLoginFailed: "Innlogging mislyktes, vennligst sjekk informasjonen din.", messageForbidden: "Innloggingen var vellykket, men du har ikke tillatelse. Du <b>kan ikke</b> logge inn.<br>Du kan velge en annen bruker eller kontakte administratoren.", messageSomethingWentWrong: "Noe gikk galt, vennligst prøv igjen senere.", messageThisFormIsNotConfigured: "Dette skjemaet er ikke konfigurert.", messagePasswordResetDisabled: "Denne funksjonen fungerer ikke fordi<br>tofaktorautentisering er aktivert på kontoen din. Kontakt administratoren.", }; case "cs": // Czech return { username: "Uživatelské jméno nebo e-mail", password: "Heslo", login: "Přihlásit se", forgotPasswordLink: "Zapomněli jste heslo?", mailAddress: "E-mailová adresa", requestLink: "Požádat o odkaz", digits: "Kód", loginLink: "Přihlásit se", secondFactor: "Dvoufázový kód", sendDigits: "Odeslat kód", sendSecondFactorDigits: "Odeslat kód", resetLoginProcess: "Zpět na přihlášení", messageEmptyUserName: "Zadejte své uživatelské jméno", messageEmptyPassword: "Zadejte své heslo", messageEmptyBoth: "Zadejte své uživatelské jméno a heslo", messageEmptyEmail: "Zadejte svou e-mailovou adresu", messageInvalidEmail: "Zadejte platnou e-mailovou adresu", digitsEmpty: "Zadejte svůj kód", digitsInvalid: "Zadejte platný kód", messageLoginFailed: "Přihlášení se nezdařilo, zkontrolujte své údaje.", messageForbidden: "Přihlášení bylo úspěšné, ale nemáte oprávnění. Nemůžete se přihlásit.<br>Vyberte jiného uživatele nebo kontaktujte správce.", messageSomethingWentWrong: "Něco se pokazilo, zkuste to později.", messageThisFormIsNotConfigured: "Tento formulář není nakonfigurován.", messagePasswordResetDisabled: "Tato funkce nefunguje, protože je na vašem<br>účtu aktivováno dvoufaktorové ověřování. Kontaktujte správce.", }; default: return { username: "Username or E-Mail", password: "Password", login: "Login", forgotPasswordLink: "Forgot Password?", mailAddress: "E-Mail-Address", requestLink: "Request Link", digits: "Code", loginLink: "Login", secondFactor: "Second Factor Code", sendDigits: "Send Code", sendSecondFactorDigits: "Send Code", resetLoginProcess: "Back to Login", messageEmptyUserName: "Please enter your username", messageEmptyPassword: "Please enter your password", messageEmptyBoth: "Please enter your username and password", messageEmptyEmail: "Please enter your email address", messageInvalidEmail: "Please enter a valid email address", digitsEmpty: "Please enter your code", digitsInvalid: "Please enter a valid code", messageLoginFailed: "Login failed, please check your input.", messageForbidden: "Login was successful, but you have no permission. You <b>cannot</b> login.<br>You can select another user or contact the administrator.", messageSomethingWentWrong: "Something went wrong, please try again later.", messageThisFormIsNotConfigured: "This form is not configured.", messagePasswordResetDisabled: "This function does not work because two-factor<br>authentication is enabled on your account.<br>Please contact the administrator.", }; } } /** * @private * @return {initEventHandler} */ function initEventHandler() { const self = this; const element = this[loginElementSymbol]; const type = "click"; element.addEventListener(type, function (event) { const callback = self.getOption("actions.click"); fireCustomEvent(self, "monster-login-clicked", { element: self, }); if (!isFunction(callback)) { return; } const element = findTargetElementFromEvent( event, ATTRIBUTE_ROLE, "control", ); if (!(element instanceof Node && self.hasNode(element))) { return; } callback.call(self, event); }); this[forgotPasswordLinkSymbol].addEventListener(type, (event) => { event.preventDefault(); this[forgotPasswordCollapseSymbol].open(); setTimeout(() => { this.shadowRoot.querySelector("input[name='email']").focus(); }, 0); }); this[loginLinkSymbol].addEventListener(type, (event) => { event.preventDefault(); this[loginCollapseSymbol].open(); setTimeout(() => { this.shadowRoot.querySelector("input[name='username']").focus(); }, 0); }); for (const e of this[resetLoginProcessLinksSymbol]) { e.addEventListener(type, (event) => { event.preventDefault(); this[loginCollapseSymbol].open(); setTimeout(() => { this.shadowRoot.querySelector("input[name='username']").focus(); }, 0); }); } this[loginCollapseSymbol].addEventListener("keydown", (event) => { if (event.key === "Enter") { this[loginButtonSymbol].click(); } }); this[secondFactorCollapseSymbol].addEventListener("keydown", (event) => { if (event.key === "Enter") { this[secondFactorButtonSymbol].click(); } }); this[forgotPasswordCollapseSymbol].addEventListener("keydown", (event) => { if (event.key === "Enter") { this[requestLinkButtonSymbol].click(); } }); this[digitsCollapseSymbol].addEventListener("keydown", (event) => { if (event.key === "Enter") { this[digitsButtonSymbol].click(); } }); this[loginButtonSymbol].setOption("actions.click", (event) => { let username = this.shadowRoot.querySelector( "input[name='username']", ).value; const userCallback = this.getOption("callbacks.username"); if (isFunction(userCallback)) { const userCallbackResult = userCallback.call(this, username); if (userCallbackResult !== undefined) { username = userCallbackResult; } } const password = this.shadowRoot.querySelector("monster-password").value; let missingBits = 0; if (username === "" || username === null) { this.setOption("classes.usernameInvalid", "invalid"); missingBits |= 1; // Set bit 1 for username } else { this.setOption("classes.usernameInvalid", ""); } if (password === "" || password === null) { this.setOption("classes.passwordInvalid", "invalid"); missingBits |= 2; // Set bit 2 for password } else { this.setOption("classes.passwordInvalid", ""); } let msg = null; if (missingBits === 1) { // missing username msg = this.getOption("labels.messageEmptyUserName"); setTimeout(() => { this.shadowRoot.querySelector("input[name='username']").focus(); }, 0); } else if (missingBits === 2) { // missing password msg = this.getOption("labels.messageEmptyPassword"); setTimeout(() => { this.shadowRoot.querySelector("monster-password").focus(); }); } else if (missingBits === 3) { msg = this.getOption("labels.messageEmptyBoth"); setTimeout(() => { this.shadowRoot.querySelector("input[name='username']").focus(); }, 0); } const timeout = this.getOption("timeoutForMessage"); if (msg !== null && msg !== undefined) { this[loginButtonSymbol].setMessage(msg); this[loginButtonSymbol].showMessage(timeout); this[loginButtonSymbol].setState("failed", timeout); return; } const url = this.getOption("fetch.login.url"); if (url === "" || url === null || url === undefined) { this[loginButtonSymbol].setMessage( this.getOption("labels.messageThisFormIsNotConfigured"), ); this[loginButtonSymbol].showMessage(timeout); this[loginButtonSymbol].setState("failed", timeout); return; } const options = { method: this.getOption("fetch.login.method"), mode: this.getOption("fetch.login.mode"), headers: this.getOption("fetch.login.headers"), credentials: this.getOption("fetch.login.credentials"), body: JSON.stringify({ username, password }), }; getWindow() .fetch(url, options) .then((response) => { if (response.ok) { this[loginButtonSymbol].setState("successful", timeout); setTimeout(() => { this.openLoggedIn(); }, 1200); } else { if (response.status === 403) { this[loginButtonSymbol].setMessage( this.getOption("labels.messageForbidden"), ); } else if (response.status === 401) { const wwwAuthenticateHeader = response.headers.get("www-authenticate"); if (wwwAuthenticateHeader) { const wwwAuthenticateParts = wwwAuthenticateHeader .split(/,\s*/) .map((part) => { const [key, value] = part.split("="); return { key: key.trim(), value: value ? value.trim().replace(/^"|"$/g, "") : null, }; }); const filteredParts = wwwAuthenticateParts.filter( (part) => part.key.toLowerCase() === "2fa", ); if (filteredParts.length > 0) { const timeout = this.getOption("timeoutForSuccess"); this[loginButtonSymbol].setState("successful", timeout); setTimeout(() => { this.openSecondFactor(); const digitsElement = this.shadowRoot.getElementById( "secondFactorControl", ); digitsElement.focus(); }, timeout); return; } } this[loginButtonSymbol].setMessage( this.getOption("labels.messageLoginFailed"), ); } else { this[loginButtonSymbol].setMessage( this.getOption("labels.messageSomethingWentWrong"), ); } this[loginButtonSymbol].showMessage(timeout); this[loginButtonSymbol].setState("failed", timeout); setTimeout(() => { this.shadowRoot.querySelector("input[name='username']").focus(); }, 0); } }) .catch((error) => { this[loginButtonSymbol].setMessage( this.getOption("labels.messageSomethingWentWrong"), ); this[loginButtonSymbol].showMessage(timeout); this[loginButtonSymbol].setState("failed", timeout); setTimeout(() => { this.shadowRoot.querySelector("input[name='username']").focus(); }, 0); }); }); this[requestLinkButtonSymbol].setOption("actions.click", (event) => { const emailElement = this.shadowRoot.querySelector("input[name='email']"); // get username and password let mail = emailElement.value; let valid = emailElement.checkValidity(); const mailCallback = this.getOption("callbacks.forgotPassword"); if (isFunction(mailCallback)) { const mailCallbackResult = mailCallback.call(this, mail); if (mailCallbackResult !== undefined) { mail = mailCallbackResult; valid = true; } } let msg = null; if (mail === "" || mail === null) { this.setOption("classes.emailInvalid", "invalid"); msg = this.getOption("labels.messageEmptyEmail"); } else if (!valid) { this.setOption("classes.emailInvalid", "invalid"); msg = this.getOption("labels.messageInvalidEmail"); } else { this.setOption("classes.emailInvalid", ""); } const timeout = this.getOption("timeoutForMessage"); if (msg !== null && msg !== undefined) { this[requestLinkButtonSymbol].setMessage(msg); this[requestLinkButtonSymbol].showMessage(timeout); this[requestLinkButtonSymbol].setState("failed", timeout); return; } const url = this.getOption("fetch.forgotPassword.url"); if (url === "" || url === null || url === undefined) { this[requestLinkButtonSymbol].setMessage( this.getOption("labels.messageThisFormIsNotConfigured"), ); this[requestLinkButtonSymbol].showMessage(timeout); this[requestLinkButtonSymbol].setState("failed", timeout); return; } const options = { method: this.getOption("fetch.forgotPassword.method"), mode: this.getOption("fetch.forgotPassword.mode"), headers: this.getOption("fetch.forgotPassword.headers"), credentials: this.getOption("fetch.forgotPassword.credentials"), body: JSON.stringify({ mail }), }; getWindow() .fetch(url, options) .then((response) => { if (response.ok) { const timeout = this.getOption("timeoutForSuccess"); this[requestLinkButtonSymbol].setState("successful", timeout); setTimeout(() => { this.openDigits(); }, timeout); } else { if (response.status === 403) { this[requestLinkButtonSymbol].setMessage( this.getOption("labels.messageForbidden"), ); } else if (response.status === 401) { if ( response.headers.has("x-password-reset") && response.headers.get("x-password-reset").includes("dis