1document.addEventListener("DOMContentLoaded", async () => { 2 "use strict"; 3 4 function isPageEditor() { 5 return (!!((typeof Sitecore !== "undefined") && (typeof Sitecore.PageModes !== "undefined") && (typeof Sitecore.PageModes.PageEditor !== "undefined")) || (document.body && document.body.getAttribute("class") === "sc-edit-mode")); 6 } 7 8 var rootElement = $('div.cxa-commerce-account__login-page-component'); 9 if (!rootElement.length) { 10 return false; 11 } 12 13 if (!isPageEditor()) { 14 // Checking if is in experience editor mode? 15 } 16 17 // Fetch all the forms we want to apply custom Bootstrap validation styles to 18 var forms = document.querySelectorAll(".cxa-commerce-account__login-page-component form"); 19 20 const searchParams = new URLSearchParams(window.location.search); 21 if (searchParams.has('ref')) { 22 var tokenReturn = searchParams.get('ref').trim(); 23 if (tokenReturn == "USER_FORGOT_PASSWORD_SUCCESS") { 24 const elementSuccesfullDIV = $(".succesfull-message-login-page"); 25 $(elementSuccesfullDIV).removeClass("d-none"); 26 } 27 } 28 29 if (searchParams.has('loginError')) { 30 const rawLoginError = searchParams.get('loginError') || ''; 31 const loginErrorMessage = decodeURIComponent(rawLoginError.replace(/\+/g, ' ')).trim(); 32 if (loginErrorMessage) { 33 const elementErrorText = $(".form-message-login").find(".error-message-login-text"); 34 const elementErrorTextDIV = $(".form-message-login").find(".error-message-login"); 35 if (elementErrorText.length > 0) { 36 elementErrorTextDIV.removeClass("d-none"); 37 elementErrorText.html(loginErrorMessage); 38 } else { 39 AccountLoginPageComponent_ShowMessage(rootElement, 'danger', loginErrorMessage); 40 } 41 } 42 } 43 44 try { 45 let isLogin = $xa(".js-open-account").data("is-login"); 46 47 if (isLogin) { 48 const language = document.documentElement.lang.toLowerCase(); 49 window.location.href = '/' + language; 50 } 51 else { 52 // Loop over them and prevent submission 53 Array.prototype.slice.call(forms).forEach(function (form) { 54 addEventTypeInput(form); 55 addFormLogin(form); 56 $(form).find("button[type=submit]").prop("disabled", false); 57 }); 58 } 59 } catch (err) { 60 return false; 61 } 62 63}); 64 65 66function beforeSubmit(event) { 67 event && $(event.target).find(":input").each(function () { 68 if ($(this).val() && $(this).attr("type") != "file") { 69 this.value = $(this).val().trim(); 70 } 71 }); 72} 73 74function afterSubmit(form) { 75 var errorElements = form.querySelectorAll( 76 "input.form-control:invalid, input.form-control.is-invalid, textarea.form-control:invalid, select.form-select:invalid, button.btn-add-files.is-invalid" 77 ); 78 79 if (errorElements.length > 0) { 80 $("html, body").animate({ 81 scrollTop: $(errorElements[0]).offset().top, 82 }, 200); 83 } 84} 85 86 87function addEventTypeInput(form) { 88 var inputs = form.getElementsByTagName("input"); 89 for (index = 0; index < inputs.length; ++index) { 90 if (inputs[index].type == "text") { 91 inputs[index].addEventListener("blur", function (item) { 92 item.target.value = item.target.value 93 .replace(/<\/?[^>]+(>|$)/g, "") 94 .trim(); 95 }); 96 } 97 } 98 99 var inputs = form.getElementsByTagName("textarea"); 100 for (index = 0; index < inputs.length; ++index) { 101 inputs[index].addEventListener("blur", function (item) { 102 item.target.value = item.target.value 103 .replace(/<\/?[^>]+(>|$)/g, "") 104 .trim(); 105 }); 106 } 107} 108 109function clearHtmlTagOnBlur(element) { 110 element.value = element.value.replace(/<\/?[^>]+(>|$)/g, "").trim(); 111} 112 113function validatePasswordLogin(form) { 114 let isValidPassword = false; 115 const passwordElement = $(form).find("input[name='Password']"); 116 const regex = /^(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*])(?!.*\s)[A-Za-z\d!@#$%^&*]{10,}$/; 117 118 isValidPassword = validateInput(passwordElement, regex); 119 120 function validateInput(inputElement, regex) { 121 const inputValue = inputElement.val(); 122 if (inputValue != "") { 123 if (!regex.test(inputValue)) { 124 const errorMsg = $("input[name='invalidPasswordFormat']").val(); 125 const elementErrorText = $(".form-message-login").find(".error-message-login-text"); 126 const elementFormHeading = $(".cxa-commerce-account__login-page-component").find(".basic-form-heading"); 127 128 const elementErrorTextDIVForm = $(".form-message-login").find(".error-message-login"); 129 const errorMessage = $(".error-message-login"); 130 const errorMessageText = $(".error-message-login").find(".error-message-login-text"); 131 132 $(elementFormHeading).append(elementErrorTextDIVForm); 133 var description = $(elementFormHeading).find('.description'); 134 if (description != undefined && description.length > 0) { 135 description.addClass('d-none'); 136 } 137 $(elementErrorText).removeClass("d-none"); 138 139 if ($(elementErrorText).length > 0) { 140 $(elementErrorText).html(`${errorMsg}`); 141 } 142 else { 143 $(errorMessage) && $(errorMessageText).html(`${errorMsg}`); 144 } 145 isValidPassword = false; 146 } else { 147 inputElement[0].setCustomValidity(""); 148 let invalidFeedback = inputElement.parent().find(".invali
148d-feedback"); 149 invalidFeedback.css("display", "none"); 150 inputElement.removeClass("is-invalid"); 151 isValidPassword = true; 152 } 153 } 154 155 return isValidPassword; 156 } 157 return isValidPassword; 158} 159 160function addFormLogin(form) { 161 162 form.addEventListener( 163 "submit", 164 function (event) { 165 event.preventDefault(); 166 event.stopPropagation(); 167 168 try { 169 form.classList.add("was-validated"); 170 const isValidForm = form.checkValidity(); 171 var isEmailCheck = validateEmail(form.querySelector('input[name="Email"]').value); 172 let isShowCaptcha = $(form).find('.login-recaptcha').hasClass("d-none"); 173 const isValidRecapcha = isShowCaptcha || validCaptcha(form); 174 175 if (isValidForm && isEmailCheck && isValidRecapcha) { 176 submitLoginFormByAjax(form); 177 } 178 179 180 } catch (err) { 181 event.preventDefault(); 182 event.stopPropagation(); 183 throw err; 184 } 185 }, 186 false 187 ); 188} 189 190function validateEmail(emailEl) { 191 if (!emailEl) { 192 return false; 193 } 194 195 if (validateCharacterEmailCommerce(emailEl)) { 196 return false; 197 } 198 if (validateCharacterDotEmailCommerce(emailEl)) { 199 return false; 200 } 201 if (validateEmailFormatCommerce(emailEl)) { 202 return false; 203 } 204 return true; 205} 206 207 208function AccountLoginComponent_DisableForm(rootElement) { 209 if (rootElement.length) { 210 rootElement.find('input').attr('disabled', 'disabled'); 211 rootElement.find('button').attr('disabled', 'disabled'); 212 rootElement.prepend("<div class='br-loading'></div>"); 213 } 214 return false; 215} 216 217function AccountLoginComponent_EnableForm(rootElement) { 218 if (rootElement.length) { 219 rootElement.find('input').removeAttr('disabled'); 220 rootElement.find('button').removeAttr('disabled'); 221 $('.br-loading', rootElement).remove(); 222 } 223 return false; 224} 225 226function submitLoginFormByAjax(form) { 227 const formData = new FormData(form); 228 const formId = $(form).data('id'); 229 const language = $(form).data('language'); 230 var rootElement = $('div.cxa-commerce-account__login-page-component'); 231 var data = $(form).serializeArray(); 232 233 var anonInfor = JSON.parse(localStorage.getItem('AnonInfor')); 234 235 if (formId) { 236 var cartID = ''; 237 var anonToken = ''; 238 if (anonInfor && anonInfor.length > 0) { 239 cartID = anonInfor[0]; 240 anonToken = anonInfor[1]; 241 242 } 243 const formDataSubmit = serialize({ 244 'Username': data[3].value, 245 'Password': btoa(data[4].value), 246 'CartIDAnon': cartID, 247 'AccessTokenAnon': anonToken 248 }, { 249 indices: true, 250 }, null); 251 252 const API_URL = '/brotherapi/Account/BuyerUserLogin'; 253 var verificationTokenInput = rootElement.find('input[name="__RequestVerificationToken"]'); 254 if (verificationTokenInput.length > 0) { 255 formDataSubmit.append("__RequestVerificationToken", verificationTokenInput.val()); 256 } 257 258 $.ajax({
259 url: API_URL, 260 type: "POST", 261 data: formDataSubmit, 262 cache: false, 263 beforeSend: function () { 264 AccountLoginComponent_DisableForm(rootElement); 265 }, 266 contentType: false, 267 processData: false, 268 statusCode: { 269 200: function (response) { 270 const elementErrorText = $(".form-message-login").find(".error-message-login-text"); 271 const elementErrorTextDIV = $(".form-message-login").find(".error-message-login"); 272 const elementDescription = $(".cxa-commerce-account__login-page-component").find(".description"); 273 const elementFormHeading = $(".cxa-commerce-account__login-page-component").find(".basic-form-heading"); 274 275 const elementErrorTextDIVForm = $(".form-message-login").find(".error-message-login"); 276 const errorMessage = $(".error-message-login"); 277 const errorMessageText = $(".error-message-login").find(".error-message-login-text"); 278 279 if (response && response.IsSuccess) { 280 // Normal flow: mergeCart is true 281 if (response.Data[1].Value) { 282 if (response.Message != undefined && response.Message) { 283 var messageReturn = response.Message.split("|"); 284 localStorage.setItem('MergeCartMessagePopup', messageReturn[0]); 285 if (messageReturn.length >= 2 && messageReturn[1] != "NEW_PRODUCT_WAS_ADDED") { 286 var MergeCartMessageHint = messageReturn[1]; 287 MergeCartMessageHint = MergeCartMessageHint.replace('NEW_PRODUCT_WAS_ADDED', ''); 288 localStorage.setItem('MergeCartMessageHint', MergeCartMessageHint); 289 } 290 } 291 } 292 else { 293 //MergeCart is false and anonInfor is exist 294 //Then check if payment is processing (message is not undefined) 295 const anonInfor = localStorage.getItem('AnonInfor'); 296 if (anonInfor && response.Message != undefined && response.Message) { 297 localStorage.setItem('PaymentProcessingMesssage', response.Message); 298 } 299 } 300 301 localStorage.removeItem('AnonInfor'); 302 if (!$(elementErrorTextDIV).hasClass("d-none")) { 303 $(elementErrorTextDIV).addClass('d-none'); 304 } 305 306 //Remove methodObject if it added by anon before login 307 if (sessionStorage.methodObject) { 308 sessionStorage.removeItem("methodObject"); 309 } 310 if (sessionStorage.SelectedCheckoutAddress) { 311 sessionStorage.removeItem("SelectedCheckoutAddress"); 312 } 313 if (sessionStorage.addressObject) { 314 sessionStorage.removeItem("addressObject"); 315 } 316 317 let loginAttempts = sessionStorage.getItem("login-attempts"); 318 319 if (loginAttempts) { 320 sessionStorage.removeItem("login-attempts"); 321 } 322 323 AddWhishlistAfterLoginAnDoRedirect(); 324 } 325 else { 326 if (response && response.Message) { 327 $(elementFormHeading).append(elementErrorTextDIVForm); 328 var description = $(elementFormHeading).find('.description'); 329 if (description != undefined && description.length > 0) { 330 description.addClass('d-none'); 331 } 332 $(elementErrorText).removeClass("d-none"); 333 334 if ($(elementErrorText).length > 0) { 335 $(elementErrorText).html(`${response.Message}`); 336 } 337 else { 338 $(errorMessage) && $(errorMessageText).html(`${response.Message}`); 339 } 340 341 342 } 343 344 AccountLoginComponent_EnableForm(rootElement); 345 346 if (response.Data != null) { 347 348 var userIsNotExist = response.Data == 101; 349 if (userIsNotExist) { 350 351 let loginAttempts = sessionStorage.getItem("login-attempts"); 352 353 if (loginAttempts) { 354 let loginAttemptsNumber = parseInt(loginAttempts); 355 loginAttemptsNumber++; 356 sessionStorage.setItem("login-attempts", loginAttemptsNumber); 357 358 let failedLoginAttemptsToShowCaptcha = $("input[name=FailedLoginAttemptsToShowCaptcha]").val(); 359 let failedLoginAttemptsToShowCaptchaNumber = parseInt(failedLoginAttemptsToShowCaptcha); 360 361 if (failedLoginAttemptsToShowCaptchaNumber && loginAttemptsNumber >= failedLoginAttemptsToShowCaptchaNumber) { 362 $(form).find('.login-recaptcha').removeClass("d-none"); 363 364 if (!validCaptcha(form)) { 365 $(form).find("button[type=submit]").prop("disabled", true); 366 } 367 } 368 } 369 else { 370 sessionStorage.setItem("login-attempts", 1); 371 } 372 } else { 373 var loginAttemptsToShowCaptcha = response.Data.find(item => item.Key === "LoginAttemptsToShowCaptcha"); 374 if (loginAttemptsToShowCaptcha && loginAttemptsToShowCaptcha.Value === true) { 375 $(".login-recaptcha").removeClass("d-none"); 376 377 if (!validCaptcha(form)) { 378 $(form).find("button[type=submit]").prop("disabled", true); 379 } 380 381 } 382 } 383 } 384 } 385 386 function doRedirect() { 387 const languagePath = '/' + (language || "").toLowerCase(); 388 389 try { 390 const currentUrl = new URL(window.location.href); 391 let finalRedirectUrl = null; 392 393 const redirectUrlParam = currentUrl.searchParams.get("redirect_url"); 394 395 if (redirectUrlParam) { 396 try { 397 finalRedirectUrl = new URL(redirectUrlParam); 398 } catch { 399 finalRedirectUrl = new URL(redirectUrlParam, currentUrl.origin); 400 } 401 402 finalRedirectUrl = finalRedirectUrl.pathname + finalRedirectUrl.search; 403 } 404 405 if (finalRedirectUrl && currentUrl.hash) { 406 finalRedirectUrl += currentUrl.hash; 407 } 408 409 const isInvalidRedirect = 410 !finalRedirectUrl || 411 finalRedirectUrl === "/" || 412 finalRedirectUrl === "?" || 413 finalRedirectUrl === "" || 414 finalRedirectUrl.startsWith("/account/login") || 415 finalRedirectUrl.startsWith("/account/logout") || 416 finalRedirectUrl === currentUrl.pathname + currentUrl.search; 417 418 if (isInvalidRedirect) { 419 finalRedirectUrl = languagePath; 420 } 421 422 window.location.replace(finalRedirectUrl); 423 } 424 catch { 425 window.location.replace(languagePath); 426 } 427 } 428 429 function AddWhishlistAfterLoginAnDoRedirect() { 430 let wishListSave = localStorage.getItem("wishListSave"); 431 432 if (wishListSave) { 433 let { productId, scProductId } = JSON.parse(wishListSave); 434 $.ajax({
435 url: `/brotherapi/catalog/wishlist/AddProductToWishList?ProductID=${productId}&SCProductID=${scProductId}`, 436 type: "POST", 437 data: [], 438 dataType: "json", 439 success: function (data) { 440 localStorage.removeItem("wishListSave"); 441 console.log('add whish list success', data); 442 doRedirect(); 443 }, 444 error: function (request, error) { 445 console.log("Error: " + JSON.stringify(error)); 446 doRedirect(); 447 }, 448 }); 449 } else { 450 doRedirect(); 451 } 452 } 453 }, 454 error: function (response) { 455 AccountLoginComponent_EnableForm(rootElement); 456 AccountLoginPageComponent_ShowMessage(rootElement, 'danger', 'There are probems have been occurred, please try again later !'); 457 }, 458 302: function (response) { 459 const elementErrorText = $(".cxa-commerce-account__login-page-component").find(".error-message-login-text"); 460 const elementErrorTextDIV = $(".cxa-commerce-account__login-page-component").find(".error-message-login"); 461 const elementDescription = $(".cxa-commerce-account__login-page-component").find(".description"); 462 if (response && response.Message && elementErrorText) { 463 $(elementDescription).addClass('d-none'); 464 $(elementErrorTextDIV).removeClass("d-none"); 465 elementErrorText && $(elementErrorText).html(`${response.Message}`); 466 } 467 }, 468 429: function (response) { 469 const elementErrorText = $(".form-message-login").find(".error-message-login-text"); 470 const elementErrorTextDIV = $(".form-message-login").find(".error-message-login"); 471 const elementDescription = $(".cxa-commerce-account__login-page-component").find(".description"); 472 const elementFormHeading = $(".cxa-commerce-account__login-page-component").find(".basic-form-heading"); 473 474 const elementErrorTextDIVForm = $(".form-message-login").find(".error-message-login"); 475 const errorMessage = $(".error-message-login"); 476 const errorMessageText = $(".error-message-login").find(".error-message-login-text"); 477 const errorMsg = $("input[name=rateLimitErrorMessage]").val(); 478 $(elementFormHeading).append(elementErrorTextDIVForm); 479 $(elementErrorText).removeClass("d-none"); 480 if ($(elementErrorText).length > 0) { 481 $(elementErrorText).html(`${errorMsg}`); 482 } 483 else { 484 $(errorMessage) && $(errorMessageText).html(`${errorMsg}`); 485 } 486 487 AccountLoginComponent_EnableForm(rootElement); 488 }, 489 400: function (response) { 490 if (response 491 && response.responseJSON) { 492 const elementErrorText = $(".form-message-login").find(".error-message-login-text"); 493 const elementErrorTextDIV = $(".form-message-login").find(".error-message-login"); 494 const elementDescription = $(".cxa-commerce-account__login-page-component").find(".description"); 495 const elementFormHeading = $(".cxa-commerce-account__login-page-component").find(".basic-form-heading"); 496 497 const elementErrorTextDIVForm = $(".form-message-login").find(".error-message-login"); 498 const errorMessage = $(".error-message-login"); 499 const errorMessageText = $(".error-message-login").find(".error-message-login-text"); 500 501 $(elementFormHeading).append(elementErrorTextDIVForm); 502 var description = $(elementFormHeading).find('.description'); 503 if (description != undefined && description.length > 0) { 504 description.addClass('d-none'); 505 } 506 $(elementErrorText).removeClass("d-none"); 507 508 if ($(elementErrorText).length > 0) { 509 $(elementErrorText).html(`${response.responseJSON.Message}`); 510 } 511 else { 512 $(errorMessage) && $(errorMessageText).html(`${response.responseJSON.Message}`); 513 } 514 } 515 516 AccountLoginComponent_EnableForm(rootElement); 517 } 518 }, 519 }); 520 } 521} 522 523function AccountLoginPageComponent_ClearAllInputValidationFeedback(rootElement) { 524 rootElement.find('input').removeClass('is-valid'); 525 rootElement.find('input').removeClass('is-invalid'); 526 return false; 527} 528 529 530function AccountLoginPageComponent_ShowMessage(rootElement, message_type, message) { 531 if (rootElement.length) { 532 var messageContainer_DivElement = rootElement.find('div.account-login-page__message_container').first();
533 if (messageContainer_DivElement.length) { 534 messageContainer_DivElement.html(`<div class="alert alert-${message_type}" role="alert">${message}</div>`); 535 messageContainer_DivElement.show(); 536 } 537 } 538}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.