Buy Hair Removal Cream for Women & Men Online at Best Price | O3+ (2024)

` const otherLoginMethodsHTML = `

` const googleLoginDiv = `

Buy Hair Removal Cream for Women & Men Online at Best Price | O3+ (1) ${SIGN_IN_WITH_GOOGLE}

` const fbLoginDiv = `

Buy Hair Removal Cream for Women & Men Online at Best Price | O3+ (2) ${SIGN_IN_WITH_FACEBOOK}

` const orContinueWithHTML = `

${CONTINUE_WITH_TEXT}

` signInForm.after(spinnerHTML) signInForm.prepend(phoneInputBoxHTML) signInForm.prepend($('#mobileOTPLoginSection')) signInForm.append(orContinueWithHTML) const mobileOTPLoginSection = $('#mobileOTPLoginSection', signInForm) const getOTPButton = $('#getOTPButton', signInForm) const mobileCountryCodeDropdown = $('#mobileCountryCodeDropdown', signInForm) const phoneNumberInput = $('#phoneNumberInput', signInForm) const iti_flag = $('.iti__flag-container', signInForm) const phoneNumberDiv = $('#phoneNumberDiv', signInForm) const emailDiv = $('#emailDiv', signInForm) const errorBox = $('#loginError', signInForm) const successBox = $('#loginSuccess', signInForm) const submitOTPButton = $('#submitOTPButton', signInForm) const otpInput = $('#otpInput', signInForm) const otpInputSixDigit = $('#otpInputSixDigit', signInForm) const submitEmailOTPButton = $('#submitEmailOTPButton', signInForm) const emailOtpInput = $('#emailOtpInput', signInForm) const userEmailInput = $('#userEmailInput', signInForm) const userPasswordInput = $('#userPasswordInput', signInForm) const registerUserButton = $('#registerUserButton', signInForm) const backToLoginButton = $('#backToLoginButton', signInForm) const backToLoginButtonEmailOtp = $('#backToLoginButtonEmailOtp', signInForm) const resendOTPButton = $('#resendOTPButton') const resendEmailOTPButton = $('#resendEmailOTPButton', signInForm) const userFirstNameInput = $('#userFirstNameInput', signInForm) const userLastNameInput = $('#userLastNameInput', signInForm) const resendCountdownTimer = $('#countdown', signInForm) const termsAndConditionsDiv = $('#termsAndConditionsDiv', signInForm) const termsAndConditionsCheckbox = $('#termsAndConditionsCheckbox', signInForm) const termsAndConditionsText = $('#termsAndConditionsText', signInForm) if (google_login_enabled) { signInForm.append(googleLoginDiv) const redirectToGoogle = $('#googleLogin', signInForm) redirectToGoogle.click(() => { SHOP = encodeURIComponent(SHOP) let queryParams = window.location.search if (queryParams && queryParams.startsWith('?')) { queryParams = queryParams.substring(1) } redirect_to = "https://" + SERVER_DOMAIN + "/account/google?shop=" + SHOP + "&actualShopUrl=" + encodeURIComponent(window.location.hostname) + "&params=" + encodeURIComponent(queryParams) window.location.assign(redirect_to) }) } if (fb_login_enabled) { signInForm.append(fbLoginDiv) const redirectToFB = $('#fbLogin', signInForm) redirectToFB.click(() => { SHOP = encodeURIComponent(SHOP) let queryParams = window.location.search if (queryParams && queryParams.startsWith('?')) { queryParams = queryParams.substring(1) } redirect_to = "https://" + SERVER_DOMAIN + "/account/fb?shop=" + SHOP + "&actualShopUrl=" + encodeURIComponent(window.location.hostname) + "&params=" + encodeURIComponent(queryParams) window.location.assign(redirect_to) }) } signInForm.append(otherLoginMethodsHTML) const loginWithEmailButton = $("#loginWithEmailButton", signInForm) const loginWithBiometricButton = $('#loginWithBiometricButton', signInForm) const loginWithPhoneNumberButton = $("#loginWithPhoneNumberButton", signInForm) const otherLoginMethodsDiv = $('#otherLoginMethodsDiv', signInForm) const continue_text = $('.continue_text', signInForm) loginWithEmailButton.click(async () => { await selectLoginMethodScreen("EMAIL_PASSWORD") }) loginWithPhoneNumberButton.click(async () => { await selectLoginMethodScreen("PHONE_OTP") }) const displaySpinner = (shouldDisplay) => { if (shouldDisplay) { signInForm.hide() $('#spinner').show(); } else { signInForm.show() $('#spinner').hide(); } } loginWithBiometricButton.click(async () => { let webauthnCred = localStorage.getItem(CRED_KEY_STRING); console.log("Found cred id in local: ", webauthnCred) if (!webauthnCred) { console.error("No cred id found, this should never happen") return } webauthnCred = JSON.parse(webauthnCred)[0] const opts = await $.ajax({ type: 'POST', url: '/apps/sml/wan/init-auth', contentType: "application/json", dataType: 'json', data: JSON.stringify({ actual_shop_url: window.location.hostname, cred_id: webauthnCred.credId, reqtimestamp: Date.now() }) }) console.log("init auth resp", opts) if (opts.allowCredentials.length === 0) { console.error('No registered credentials found., this should never happen'); return } const { startAuthentication } = SimpleWebAuthnBrowser; let authInitResp; try { authInitResp = await startAuthentication(opts); } catch (err) { console.error("Error in starting webauthn", err); return } console.log("authInitResp is: ", authInitResp) displaySpinner(true) let verificationResp try { verificationResp = await $.ajax({ type: 'POST', url: '/apps/sml/wan/complete-auth', contentType: "application/json", dataType: 'json', data: JSON.stringify({ auth_credential: authInitResp, actual_shop_url: window.location.hostname, cred_id: webauthnCred.credId, first_name: webauthnCred.firstName, last_name: webauthnCred.last_name, reqtimestamp: Date.now() }) }) } catch (ex) { displaySpinner(false) console.error("Error in getting verificationResp", ex) errorBox.html("Error in logging in with device") return } console.log("verificationResp", verificationResp) emailInputBox.val(verificationResp.email) passwordInputBox.val(verificationResp.xattr) await runOnSMLEventInternal("LOGIN_SUCCESSFUL", {"email": verificationResp.email}) signInButton.click() setTimeout(() => { displaySpinner(false) }, 3000) }) const selectLoginMethodScreen = async (screenType) => { localStorage.setItem("SML_LOGIN_METHOD_SCREEN", screenType) if (screenType == "PHONE_OTP") { resendCountdownTimer.show() mobileOTPLoginSection.show() loginWithPhoneNumberButton.hide() if (allowedLoginMethod == "EMAIL_AND_PHONE") { loginWithEmailButton.show() } emailInputBox.hide() passwordInputBox.hide() emailInputBoxLabel.hide() passwordInputBoxLabel.hide() signInButton.hide() forgotPasswordLink.hide() if (emailInputBox.parent().attr('id') != signInForm.attr('id')) { emailInputBox.parent().hide() } if (passwordInputBox.parent().attr('id') != signInForm.attr('id')) { passwordInputBox.parent().hide() } //dont' do this for https://dev-shantibanaras.myshopify.com/password as asked by them over email // if (SHOP.indexOf("shantibanaras") == -1 && SHOP != "doro-fashions.myshopify.com") { // $('a[href$="/account/register"]').attr('style', 'display:none !important') // createAccountLink.hide() // } //https://leccygenesis.com/account/login if (SHOP.indexOf("leccygenesis") > -1) { $('.login-form-container').hide() } $(':contains("Forgot your password?"):last').hide() $('label[for="CustomerPassword"]').hide() $('label[for="CustomerEmail"]').hide() $('a[href="#recover-form"]').hide() //remove original login text if ($('#login').length == 1 && $('#login').text() == '\n Login\n ') { $('#login').hide() } if ($('#CustomerLoginForm').length == 1 && $('h2', '#CustomerLoginForm').text() == "Login") { $('h2', '#CustomerLoginForm').hide() } if (SHOP.indexOf("suta") > -1) { $('header.Form__Header').hide() $('div.Form__Hint').hide() $('button.Form__ItemHelp').hide() } if (SHOPIFY_THEME.indexOf("Riode") > -1) { $('ul.nav.nav-tabs.align-items-center').hide() } if (SHOP == "thesovereignsectprebook.myshopify.com") { $("#simplify-login-sign-up-text").insertBefore("#mobileOTPLoginSection") otherLoginMethodsDiv.insertBefore("#mobileOTPLoginSection") $("#troubleLoggingInDiv").show() continue_text.hide() } if (SHOP == "app99.myshopify.com") { $('header.form__header', signInForm).hide() $('div.form__secondary-action', signInForm).hide() } if (SHOP == "doro-fashions.myshopify.com") { $('#otherLoginMethodsDiv').insertAfter('#mobileOTPLoginSection') } $('h2.form__message', signInForm).hide() $('div.errors', signInForm).hide() } if (screenType == "EMAIL_PASSWORD") { resendCountdownTimer.hide() mobileOTPLoginSection.hide() loginWithEmailButton.hide() if (allowedLoginMethod == "EMAIL_AND_PHONE") { loginWithPhoneNumberButton.show() } emailInputBox.show() passwordInputBox.show() emailInputBoxLabel.show() passwordInputBoxLabel.show() signInButton.show() forgotPasswordLink.show() if (emailInputBox.parent().attr('id') != signInForm.attr('id')) { emailInputBox.parent().show() } if (passwordInputBox.parent().attr('id') != signInForm.attr('id')) { passwordInputBox.parent().show() } // hide forgot your password link on https://www.casivly.com/account/login $('.additional-links').show() $('.tt-required').show() //https://tikitoro.com/account/login $('#RecoverPasswordForm').show() $('div.title_block').show() $('div.bank_register').show() //https://leccygenesis.com/account/login if (SHOP.indexOf("leccygenesis") > -1) { $('.login-form-container').show() } //remove original login text if ($('#login').length == 1 && $('#login').text() == '\n Login\n ') { $('#login').show() } if ($('#CustomerLoginForm').length == 1 && $('h2', '#CustomerLoginForm').text() == "Login") { $('h2', '#CustomerLoginForm').show() } //https://flourish.shop/account/login?return_url=%2Faccount $('header.section-header').show() //https://mauli-india.myshopify.com/account/login $('h1.h3.mb-3:contains("Login")').show() // https://floryo.com/ $('a[href$="#recover"]').attr('style', 'display:block !important') if (SHOP.indexOf("shantibanaras") == -1) { $('a[href$="/account/register"]').attr('style', 'display:block !important') createAccountLink.show() } $('label[for="CustomerPassword"]').show() $('label[for="CustomerEmail"]').show() $('a[href="#recover-form"]').show() // https://darbeauty.com/account/login $('h2:contains("تسجيل الدخول")').show() //https://www.fionadiamonds.com/account/login $('h2.main-heading:contains("Customer Login")').show() //https://houseofzelena.com/ $('button:contains("Forgot your password?")').show() $('h1.login__heading:contains("Login")').show() if (SHOP.indexOf("suta") > -1) { $('header.Form__Header').show() $('div.Form__Hint').show() $('button.Form__ItemHelp').show() } if (SHOPIFY_THEME.indexOf("Riode") > -1) { $('ul.nav.nav-tabs.align-items-center').show() } if (SHOP == "thesovereignsectprebook.myshopify.com") { continue_text.show() otherLoginMethodsDiv.insertAfter(continue_text) } if (SHOP == "app99.myshopify.com") { $('header.form__header', signInForm).show() $('div.form__secondary-action', signInForm).show() } if (SHOP == "doro-fashions.myshopify.com") { $('#otherLoginMethodsDiv').insertAfter(signInButton) } $('h2.form__message', signInForm).show() $('div.errors', signInForm).show() } await runOnSMLEventInternal("SCREEN_TYPE_CHANGE", {"screen_type": screenType}) } let sessionInfoToken = "" let sendOTPInProgress = false const sendOTP = async (mobileNumber, recaptchaToken) => { if (sendOTPInProgress) { console.log("sendOTP already in progress, return") return } sendOTPInProgress = true let gtoken = null if (!recaptchaToken) { try { gtoken = await grecaptcha.execute('6Lf5M7sjAAAAAN6cj5PtXrtkjvSd82YlvW0MEXVK', { action: 'submit' }) } catch (ex) { console.error("Error in gtoken", ex) } } try { const data = await $.ajax({ type: 'POST', url: "/apps/sml/client/send_otp", contentType: "application/json", dataType: 'json', data: JSON.stringify({ mobile: mobileNumber, shop: SHOP, modifiedShopURL: window.location.hostname, type: "LOGIN", exp: LOGIN_EXP, reqtimestamp: Date.now(), gtoken: gtoken, recaptchaToken: recaptchaToken }) }) if (RESEND_OTP_TIMER_ENABLED) { getResendOTPTimer() } console.log('send otp data: ', data); if (recaptchaToken) { sessionInfoToken = data.session_info } if (data.type == "OTP_SENT_ON_EMAIL_AND_PHONE") { successBox.html(`${OTP_SENT_SUCCESS_MESSAGE} ${data.email}, ${ENTER_IT_BELOW_TEXT}`); errorBox.html("") getOTPButton.hide() } else { successBox.html(OTP_SENT_SUCCESSFULLY_TEXT); errorBox.html("") } //We can wait for sometime before allowing user to send otp again setTimeout(() => { sendOTPInProgress = false }, 8000) return true } catch (error) { console.error("error in send otp api ", error) if (error && error.responseJSON && error.responseJSON["msg"]) { errorBox.html(`${OTP_SEND_UNABLE}` + ` ` + error.responseJSON["msg"]) } else { errorBox.html(OTP_SENT_UNSUCCESSFULLY_ERROR_TEXT); } successBox.html("") sendOTPInProgress = false } return false } let sendOTPEmailInProgress = false const sendOTPEmail = async (email) => { if (sendOTPEmailInProgress) { console.log("sendOTPEmail already in progress, return") return } sendOTPEmailInProgress = true let send_otp_email_url = "https://" + SERVER_DOMAIN + "/send_otp_email" if (useProxiedUrl) { send_otp_email_url = "/apps/sml/client/send_otp_email" } try { const data = await $.ajax({ type: 'POST', url: send_otp_email_url, contentType: "application/json", dataType: 'json', data: JSON.stringify({ email: email, shop: SHOP, modifiedShopURL: window.location.hostname, reqtimestamp: Date.now() }), }) console.log('send_email_otp data: ', data); successBox.show() successBox.html(OTP_SENT_SUCCESSFULLY_TEXT_EMAIL); errorBox.html("") //We can wait for sometime before allowing user to send otp again setTimeout(() => { sendOTPEmailInProgress = false }, 8000) return true } catch (error) { console.error("error in send email otp api ", error) if (error && error.responseJSON && error.responseJSON["msg"]) { errorBox.html(`${OTP_SEND_UNABLE} ${error.responseJSON["msg"]}`) } else { errorBox.html(OTP_SENT_UNSUCCESSFULLY_ERROR_TEXT); } successBox.html("") sendOTPEmailInProgress = false } return false } const selectOTPScreen = (screenType, fullPhoneNumber) => { if (screenType == "ENTER_PHONE") { //show the screen where user enters phone number and clicks get otp getOTPButton.show() phoneNumberInput.show() mobileCountryCodeDropdown.show() //hide ENTER_OTP screen phoneNumberDiv.html("") phoneNumberDiv.hide() emailDiv.html("") emailDiv.hide() otpInput.hide() otpInputSixDigit.hide() emailOtpInput.hide() submitOTPButton.hide() submitEmailOTPButton.hide() resendOTPButton.hide() resendEmailOTPButton.hide() backToLoginButton.hide() termsAndConditionsDiv.hide() resendCountdownTimer.hide() resetFirebase() //todo: hide 3rd screen } if (screenType == "ENTER_OTP") { //hide screen ENTER_PHONE getOTPButton.hide() phoneNumberInput.hide() iti_flag.hide() mobileCountryCodeDropdown.hide() //show screen which has option to enter OTP phoneNumberDiv.show() resendCountdownTimer.show() //otpInput.show() - this sometimes add display: inline-block; so add display: block explicitly if (shouldUseFirebase(fullPhoneNumber)) { otpInputSixDigit.css("display", "block") } else { otpInput.css("display", "block") } emailOtpInput.hide() submitOTPButton.show() submitEmailOTPButton.hide() // resendOTPButton.show() resendOTPButton.css("display", "block") resendEmailOTPButton.hide() backToLoginButton.show() if (showTermsAndConditions) { termsAndConditionsDiv.show() submitOTPButton.attr("disabled", true); } //todo: hide ENTER_EMAIL screen } if (screenType == "ENTER_EMAIL") { //hide screen ENTER_PHONE getOTPButton.hide() phoneNumberInput.hide() mobileCountryCodeDropdown.hide() resendCountdownTimer.hide() submitOTPButton.hide() submitEmailOTPButton.hide() resendOTPButton.hide() resendEmailOTPButton.hide() backToLoginButton.hide() otpInput.hide() otpInputSixDigit.hide() emailOtpInput.hide() phoneNumberDiv.show() userEmailInput.show() registerUserButton.show() emailDiv.hide() backToLoginButtonEmailOtp.hide() termsAndConditionsDiv.hide() if (fields_during_signup == "EMAIL_AND_NAME") { userFirstNameInput.show() userLastNameInput.show() if (SHOP == "testsimplifyloginembed.myshopify.com" || SHOP == "revamp-moto.myshopify.com") { $('#userBirthdayInputDiv').show() $('#userGenderInputDiv').show() } } if (ASK_PASSWORD_DURING_SIGNUP) { userPasswordInput.show() } } if (screenType == "ENTER_OTP_EMAIL_EXISTS") { getOTPButton.hide() phoneNumberInput.hide() mobileCountryCodeDropdown.hide() userFirstNameInput.hide() userLastNameInput.hide() userPasswordInput.hide() resendCountdownTimer.hide() phoneNumberDiv.hide() otpInput.hide() otpInputSixDigit.hide() emailOtpInput.val("") // emailOtpInput.show() emailOtpInput.css("display", "block") submitOTPButton.hide() submitEmailOTPButton.show() resendOTPButton.hide() // resendEmailOTPButton.show() resendEmailOTPButton.css("display", "block") backToLoginButton.hide() backToLoginButtonEmailOtp.show() registerUserButton.hide() emailDiv.show() userEmailInput.hide() termsAndConditionsDiv.hide() $('#userBirthdayInputDiv').hide() $('#userGenderInputDiv').hide() } } const sanitizePhoneNumber = (phoneNumber) => { if (phoneNumber) { //handling for phoneNumber input like 7411 71 3971 phoneNumber = phoneNumber.replace(/ /g, '') } if (phoneNumber && phoneNumber.startsWith('0')) { phoneNumber = phoneNumber.substring(1) } return phoneNumber } const shouldUseFirebase = (phoneNumber) => { return (FIREBASE_LEVEL == "ALL_NUMBERS" || (FIREBASE_LEVEL == "ONLY_INTERNATIONAL_NUMBERS" && !phoneNumber.startsWith("+91"))) } const sanitizeEmail = (email) => { if (email) { //handling for user email input thamizhvasanthi@gmail. Com email = email.replace(/ /g, '') } return email } const getOtpButtonClickHandler = async () => { successBox.html("") successBox.show() let phoneNumber = phoneNumberInput.val() phoneNumber = sanitizePhoneNumber(phoneNumber) const phoneCodeSelected = mobileCountryCodeDropdown.val() const fullPhoneNumber = phoneCodeSelected + phoneNumber if (!validatePhoneNumber(fullPhoneNumber)) { errorBox.html(ENTER_VALID_NUMBER); return; } if (SHOP == "opatra-5041.myshopify.com") { otpInput.val("1234") submitOTPButton.click() return } phoneNumberDiv.html(phoneCodeSelected + " " + phoneNumber) successBox.html(OTP_SENT_SUCCESSFULLY_TEXT); errorBox.html("") selectOTPScreen("ENTER_OTP", fullPhoneNumber) let recapchaToken if (shouldUseFirebase(fullPhoneNumber)) { recapchaToken = await recaptchaVerifier.verify() console.log("token", recapchaToken) } const result = await sendOTP(fullPhoneNumber, recapchaToken) if (!result) { successBox.hide() selectOTPScreen("ENTER_PHONE") return } } getOTPButton.click(() => { grecaptcha.ready(getOtpButtonClickHandler) }) backToLoginButton.click(() => { successBox.hide() selectOTPScreen("ENTER_PHONE") }) backToLoginButtonEmailOtp.click(() => { successBox.hide() selectOTPScreen("ENTER_EMAIL") }) const resendOTPButtonClickHandler = async () => { otpInput.val("") otpInputSixDigit.val("") successBox.html("") let phoneNumber = phoneNumberInput.val() phoneNumber = sanitizePhoneNumber(phoneNumber) const phoneCodeSelected = mobileCountryCodeDropdown.val() const fullPhoneNumber = phoneCodeSelected + phoneNumber if (!validatePhoneNumber(fullPhoneNumber)) { errorBox.html(ENTER_VALID_NUMBER); successBox.html(""); return; } let recapchaToken if (shouldUseFirebase(fullPhoneNumber)) { recapchaToken = await recaptchaVerifierResendOTPButton.verify() console.log("resend token", recapchaToken) } const result = await sendOTP(fullPhoneNumber, recapchaToken) if (!result) { return } } resendOTPButton.click(() => { grecaptcha.ready(resendOTPButtonClickHandler) }) resendEmailOTPButton.click(async () => { otpInput.val("") otpInputSixDigit.val("") successBox.html("") let email = userEmailInput.val() email = sanitizeEmail(email) if (!validateEmail(email)) { errorBox.html(ENTER_VALID_EMAIL); return; } const result = await sendOTPEmail(email) if (!result) { return } }) let registerUserInProgress = false const registerUser = async (mobile, email, firstName, lastName, customerNote, password) => { if (registerUserInProgress) { console.log("registerUserInProgress already in progress, return") return } registerUserInProgress = true let register_url = "https://" + SERVER_DOMAIN + "/register" if (useProxiedUrl) { register_url = "/apps/sml/client/register" } try { const data = await $.ajax({ type: 'POST', url: register_url, data: JSON.stringify({ mobile: mobile, shop: SHOP, email: email, first_name: firstName, last_name: lastName, note: customerNote, password: password, reqtimestamp: Date.now() }), contentType: "application/json", dataType: 'json' }) console.log('registerUser data: ', data); if (data.type == "EXISTING_USER_WITH_EMAIL_FOUND") { registerUserInProgress = false successBox.html("") return { "type": data.type } } else { successBox.html(SUCCESSFULLY_REGISTERED_USER) errorBox.html("") emailInputBox.val(data.email) passwordInputBox.val(data.xattr) //As Shopify login takes time user tends to press register button multiple times, causing multiple backend calls //We can wait for sometime to let succesful Shopify login complete setTimeout(() => { registerUserInProgress = false }, 8000) return { "type": "USER_REGISTERED_SUCCESSFULLY" } } } catch (error) { console.error("error in registerUser otp api ", error) if (error && error.responseJSON && error.responseJSON["msg"]) { let errorMessage = error.responseJSON["msg"] errorBox.html("Error: " + errorMessage) } else { errorBox.html(USER_REGISTRATION_UNABLED); } successBox.html("") registerUserInProgress = false return { "error": error } } } let validateOTPInProgress = false const validateOTP = async (mobileNumber, otp) => { if (validateOTPInProgress) { console.log("validateOTP already in progress, return") return } validateOTPInProgress = true let validate_otp_email_url = "https://" + SERVER_DOMAIN + "/validate_otp" if (useProxiedUrl) { validate_otp_email_url = "/apps/sml/client/validate_otp" } try { const data = await $.ajax({ type: 'POST', url: validate_otp_email_url, data: JSON.stringify({ mobile: mobileNumber, shop: SHOP, otp: otp, type: "LOGIN", exp: LOGIN_EXP, reqtimestamp: Date.now(), sessionInfoToken: sessionInfoToken }), contentType: "application/json", dataType: 'json' }) console.log('data: ', data); if (data.type == "LOGIN") { successBox.html(OTP_SUCCESSFULLY_VERIFIED) errorBox.html("") emailInputBox.val(data.email) passwordInputBox.val(data.xattr) //As Shopify login takes time user tends to press register button multiple times, causing multiple backend calls //We can wait for sometime to let succesful Shopify login complete setTimeout(() => { validateOTPInProgress = false }, 8000) return { "type": "LOGIN_SUCCESSFUL" } } if (data.type == 'REGISTER') { validateOTPInProgress = false successBox.html(ENTER_EMAIL_REGISTER_LOGIN) //successBox.html('

Your number is not registered

'); errorBox.html(""); //$('#phoneNumberAndEditDiv,#emailAndEditDiv,#otpInput,#submitOTPButton,#resendOTPButton,#resendEmailOTPButton').hide(); selectOTPScreen("ENTER_EMAIL") //return flase; return { "type": "NEW_USER" } } validateOTPInProgress = false console.log("validateOTP: user should never reach here") } catch (error) { console.error("error in validate otp api ", error) otpInput.val("") otpInputSixDigit.val("") if (error && error.responseJSON && error.responseJSON["msg"]) { errorBox.html("Error: " + error.responseJSON["msg"]) } else { errorBox.html(OTP_VALIDATION_UNABLED); } successBox.html("") validateOTPInProgress = false return { "error": error } } return false } let validateOTPEmailInProgress = false const validateOTPEmail = async (email, phone, otp, firstName, lastName, customerNote) => { if (validateOTPEmailInProgress) { console.log("validateOTPEmail already in progress, return") return } validateOTPEmailInProgress = true let validate_otp_existing_email_url = "https://" + SERVER_DOMAIN + "/validate_otp_existing_email" if (useProxiedUrl) { validate_otp_existing_email_url = "/apps/sml/client/validate_otp_existing_email" } try { const validateOtpEmailExistingData = await $.ajax({ type: 'POST', url: validate_otp_existing_email_url, data: JSON.stringify({ mobile: phone, email: email, shop: SHOP, otp: otp, first_name: firstName, last_name: lastName, note: customerNote, reqtimestamp: Date.now() }), contentType: "application/json", dataType: 'json' }) console.log('data: ', validateOtpEmailExistingData); if (validateOtpEmailExistingData.type == "USER_UPDATED_SUCCESSFULLY") { successBox.html(OTP_SUCCESSFULLY_VERIFIED) errorBox.html("") emailInputBox.val(validateOtpEmailExistingData.email) passwordInputBox.val(validateOtpEmailExistingData.xattr) //As Shopify login takes time user tends to press register button multiple times, causing multiple backend calls //We can wait for sometime to let succesful Shopify login complete setTimeout(() => { validateOTPEmailInProgress = false }, 8000) return true } validateOTPEmailInProgress = false console.log("validateOTPEmail: This should never get called") } catch (error) { console.error("error in validate email otp api ", error) if (error && error.responseJSON && error.responseJSON["msg"]) { errorBox.html("Error: " + error.responseJSON["msg"]) } else { errorBox.html(OTP_VALIDATION_UNABLED); } successBox.html("") validateOTPEmailInProgress = false } return false } registerUserButton.click(async () => { let phoneNumber = phoneNumberInput.val() phoneNumber = sanitizePhoneNumber(phoneNumber) const phoneCodeSelected = mobileCountryCodeDropdown.val() const fullPhoneNumber = phoneCodeSelected + phoneNumber let email = userEmailInput.val() email = sanitizeEmail(email) const firstName = userFirstNameInput.val() const lastName = userLastNameInput.val() let password = userPasswordInput.val() if (fields_during_signup == "EMAIL_AND_NAME") { if (!firstName) { successBox.html("") errorBox.html(ENTER_VALID_FIRST_NAME) return } if (!lastName) { successBox.html("") errorBox.html(ENTER_VALID_LAST_NAME) return } } if (ASK_PASSWORD_DURING_SIGNUP) { if (!validatePassword(password)) { successBox.html("") errorBox.html("Please enter valid password") return } } else { // Sometimes browser will auto fill password input box, especially for dev sites // where we enter password for entering the Shopify dev site password = null } //check if email valid if (!IS_EMAIL_MANDATORY && !email) { email = fullPhoneNumber + '@' + window.location.hostname console.log("User has not provided email id and IS_EMAIL_MANDATORY is false, setting email as: ", email) } else if (!validateEmail(email)) { errorBox.html(ENTER_VALID_EMAIL); return; } const customerNote = getCustomerNoteValue() console.log("Value of customer note is: ", customerNote) const result = await registerUser(fullPhoneNumber, email, firstName, lastName, customerNote, password) if (result.error) { return } if (result.type == "EXISTING_USER_WITH_EMAIL_FOUND") { const emailSent = await sendOTPEmail(email) if (!emailSent) { return } emailDiv.html(email) selectOTPScreen("ENTER_OTP_EMAIL_EXISTS") return } if (result.type == "USER_REGISTERED_SUCCESSFULLY") { await runOnSMLEventInternal("USER_REGISTERED_SUCCESSFULLY", {"email": email, "phone": fullPhoneNumber}) signInButton.click() return } }) const getCustomerNoteValue = () => { const customerNoteInputBox = $('input[name=customer\\[note\\]]') let customerNote = customerNoteInputBox.val() let gender = null let birthday = null if (SHOP == "revamp-moto.myshopify.com" || SHOP == "testsimplifyloginembed.myshopify.com") { gender = $('[name="userGenderInput"]:checked').val() birthday = $('#userBirthdayInput').val() if (!customerNote) { customerNote = "" } if (birthday) { customerNote += ` [Birthday]: ${birthday}` } if (gender) { customerNote += ` [Gender]: ${gender}` } } console.log("Value of customer note is: ", customerNote) return customerNote } const showButtonLoadingAnimation = (btn) => { btn.addClass('otp-btn-loading') btn.text('') } const buttonRemoveLoadingAnimation = (btn, btnText) => { btn.removeClass('otp-btn-loading') btn.text(btnText) } submitOTPButton.click(async () => { let phoneNumber = phoneNumberInput.val() phoneNumber = sanitizePhoneNumber(phoneNumber) const phoneCodeSelected = mobileCountryCodeDropdown.val() const fullPhoneNumber = phoneCodeSelected + phoneNumber let otp if (shouldUseFirebase(fullPhoneNumber)) { otp = otpInputSixDigit.val() if (!otp || otp.length != 6) { successBox.html("") errorBox.html(ENTER_VALID_SIX_DIGIT_OTP) return } } else { otp = otpInput.val() if (!otp || otp.length != 4) { successBox.html("") errorBox.html(ENTER_VALID_OTP) return } } showButtonLoadingAnimation(submitOTPButton) const result = await validateOTP(fullPhoneNumber, otp) if (result.type == "LOGIN_SUCCESSFUL") { await runOnSMLEventInternal("LOGIN_SUCCESSFUL", {"phone": fullPhoneNumber}) signInButton.click() return } if (result.type == "NEW_USER") { buttonRemoveLoadingAnimation(submitOTPButton, SUBMIT_OTP_TEXT) return } if (result.error) { buttonRemoveLoadingAnimation(submitOTPButton, SUBMIT_OTP_TEXT) return } console.log("submitOTPButton.click => We should never reach here") }) submitEmailOTPButton.click(async () => { let phoneNumber = phoneNumberInput.val() phoneNumber = sanitizePhoneNumber(phoneNumber) const phoneCodeSelected = mobileCountryCodeDropdown.val() const fullPhoneNumber = phoneCodeSelected + phoneNumber let email = userEmailInput.val() email = sanitizeEmail(email) if (!validateEmail(email)) { errorBox.html(ENTER_VALID_EMAIL); return; } const otp = emailOtpInput.val() if (!otp || otp.length != 4) { successBox.html("") errorBox.html(ENTER_VALID_OTP) return } const firstName = userFirstNameInput.val() const lastName = userLastNameInput.val() const customerNote = getCustomerNoteValue() showButtonLoadingAnimation(submitEmailOTPButton) const result = await validateOTPEmail(email, fullPhoneNumber.replace(" ", ""), otp, firstName, lastName, customerNote) if (result) { await runOnSMLEventInternal("LOGIN_SUCCESSFUL", {"email": email, "phone": fullPhoneNumber}) signInButton.click() } else { buttonRemoveLoadingAnimation(submitEmailOTPButton, SUBMIT_OTP_TEXT) } }) otpInput.keyup(async () => { const otp = otpInput.val() if (otp.length != 4) { return } otpInput.trigger('blur'); if (showTermsAndConditions && !termsAndConditionsCheckbox.is(":checked")) { return; } submitOTPButton.click() }) otpInputSixDigit.keyup(async () => { const otp = otpInputSixDigit.val() if (otp.length != 6) { return } otpInputSixDigit.trigger('blur'); if (showTermsAndConditions && !termsAndConditionsCheckbox.is(":checked")) { return; } submitOTPButton.click() }) emailOtpInput.keyup(async () => { const otp = emailOtpInput.val() if (otp.length != 4) { return } emailOtpInput.trigger('blur'); submitEmailOTPButton.click() }) //disable form submit on pressing enter key signInForm.on('keyup keypress', function(e) { var keyCode = e.keyCode || e.which if (keyCode === 13) { e.preventDefault() if (getOTPButton.css('display') != 'none') { //getOtpButton is present, let's click it getOTPButton.click() } return false } }) let resendOTPTimerTimeLeft = 60 let resendButtonTimer const getResendOTPTimer = () => { resendOTPTimerTimeLeft = 60; if (resendButtonTimer) { return } resendButtonTimer = setInterval(() => { resendOTPTimerTimeLeft -= 1; if (resendOTPTimerTimeLeft <= 0) { resendCountdownTimer.html("Press button to re-send OTP"); resendOTPButton.prop('disabled', false) } else { resendOTPButton.prop('disabled', true) resendCountdownTimer.html("Please wait " + resendOTPTimerTimeLeft + "&nbsp" + "seconds to re-send OTP"); } }, 1000); } const initAutoOTPFill = () => { if ('OTPCredential' in window) { const ac = new AbortController(); // signInForm.submit('submit', e => { // ac.abort(); // }); navigator.credentials.get({ otp: { transport: ['sms'] }, signal: ac.signal }).then(otp => { console.log("OTP IS: ", otp) const otpCode = otp.code if (otpCode && otpCode.length == 4 && !isNaN(otpCode)) { otpInput.val(otpCode) submitOTPButton.click() } }).catch(err => { console.error(err) }) } } const loginUsingSocialToken = () => { const queryString = window.location.search; const urlParams = new URLSearchParams(queryString); if (urlParams.has('simplysocialtoken') && urlParams.get('email')) { const simplysocialtoken = urlParams.get('simplysocialtoken'); const email = urlParams.get('email'); let validate_social_auth_token_url = "https://" + SERVER_DOMAIN + "/validate_social_auth_token" if (useProxiedUrl) { validate_social_auth_token_url = "/apps/sml/client/validate_social_auth_token" } $.ajax({ type: 'POST', url: validate_social_auth_token_url, data: JSON.stringify({ simplysocialtoken: simplysocialtoken, email: email, shop: SHOP, reqtimestamp: Date.now() }), beforeSend: function() { displaySpinner(true) }, success: async function(data) { console.log('data here is: ', data); emailInputBox.val(data.email) passwordInputBox.val(data.xattr) await runOnSMLEventInternal("LOGIN_SUCCESSFUL", {"email": email}) signInButton.click() setTimeout(() => { displaySpinner(false) }, 5000) }, error: function(xhr, status, errorMessage) { displaySpinner(false) console.error("error in validate social login api ", xhr.responseJSON) if (xhr && xhr.responseJSON && xhr.responseJSON["msg"]) { errorBox.html("Error in logging in " + xhr.responseJSON["msg"]) } else { errorBox.html("Error in logging in") } successBox.html("") }, contentType: "application/json", dataType: 'json' }); } return } let recaptchaVerifier let recaptchaVerifierResendOTPButton let recaptchaVerifierWidgetId let recaptchaVerifierResendOTPButtonWidgetId const initFirebase = () => { if (FIREBASE_LEVEL == "DISABLED") { return } const app = initializeApp(FIREBASE_CONFIG); const googleRecaptchaAuth = getAuth(); recaptchaVerifier = new RecaptchaVerifier('getOTPButton', { 'size': 'invisible', 'callback': (recapchaToken) => { console.log("recapcha called") }, 'expired-callback': () => { console.error("expired callback, reload page??") // Response expired. Ask user to solve reCAPTCHA again. // ... } }, googleRecaptchaAuth); recaptchaVerifier.render().then(function(widgetId) { // console.log("Rendered recaptchaVerifier, widget id: ", widgetId) recaptchaVerifierWidgetId = widgetId }); recaptchaVerifierResendOTPButton = new RecaptchaVerifier('resendOTPButton', { 'size': 'invisible', 'callback': (recapchaToken) => { console.log("recapcha called") }, 'expired-callback': () => { console.error("expired callback, reload page??") // Response expired. Ask user to solve reCAPTCHA again. // ... } }, googleRecaptchaAuth); recaptchaVerifierResendOTPButton.render().then(function(widgetId) { // console.log("Rendered recaptchaVerifierResendOTPButton, widget id: ", widgetId) recaptchaVerifierResendOTPButtonWidgetId = widgetId }); } const resetFirebase = () => { if (recaptchaVerifierWidgetId != null) { grecaptcha.reset(recaptchaVerifierWidgetId) } if (recaptchaVerifierResendOTPButtonWidgetId != null) { grecaptcha.reset(recaptchaVerifierResendOTPButtonWidgetId) } } const initMobileOTPLoginSection = () => { $('#simplify-login-sign-up-text').text(LOGIN_SIGN_UP_TEXT) mobileCountryCodeDropdown.html(createPhoneOptions()) phoneNumberInput.attr('placeholder', PHONE_NUMBER_TEXT) getOTPButton.text(GET_OTP_TEXT) submitOTPButton.text(SUBMIT_OTP_TEXT) submitEmailOTPButton.text(SUBMIT_OTP_TEXT) resendOTPButton.text(RESEND_OTP_TEXT) resendEmailOTPButton.text(RESEND_OTP_TEXT) userFirstNameInput.attr('placeholder', FIRST_NAME_TEXT + "*") userLastNameInput.attr('placeholder', LAST_NAME_TEXT + "*") if (IS_EMAIL_MANDATORY) { userEmailInput.attr('placeholder', EMAIL_TEXT + "*") } else { userEmailInput.attr('placeholder', EMAIL_TEXT) } userPasswordInput.attr('placeholder', PASSWORD_TEXT + "*") registerUserButton.text(REGISTER_AND_LOGIN_TEXT) } const runOnSMLEventInternal = async (event, data) => { if (window.runOnSMLEvent && typeof window.runOnSMLEvent === 'function') { try { await window.runOnSMLEvent(event, data) console.log("Successfully executed window.runOnSMLEvent with event", event, "data ", data) } catch (ex) { console.error("Exception when executing window.runOnSMLEvent with event " + event, ex) } } else { console.log("You can add runOnSMLEvent(event, data) function to run on Simplify My Login app events") } } const initPage = async () => { //saw on http://ustarmmcosmetics.myshopify.com/ initMobileOTPLoginSection() const pageWidth = (window.innerWidth > 0) ? window.innerWidth : screen.width; if (pageWidth && pageWidth > 749) { signInForm.css("min-width", "400px") } const otpInputDirection = $('#otpInput').css("direction") if (pageWidth && otpInputDirection && otpInputDirection == "rtl") { if (pageWidth > 749) { $('#otpInput')[0].style.setProperty("letter-spacing", "70px", "important") $('#otpInputSixDigit')[0].style.setProperty("letter-spacing", "45px", "important") } else { $('#otpInput')[0].style.setProperty("letter-spacing", "45px", "important") $('#otpInputSixDigit')[0].style.setProperty("letter-spacing", "30px", "important") } } if (selected_country_code == "All") { const ipInfoInterval = setInterval(() => { if (!isIpInfoRequestPending) { mobileCountryCodeDropdown.val(PHONE_CODE) clearInterval(ipInfoInterval) } }, 100) } if (selected_country_code != "All") { mobileCountryCodeDropdown.prop('disabled', true); mobileCountryCodeDropdown.css('-webkit-appearance', 'none'); mobileCountryCodeDropdown.css('-moz-appearance', 'none'); } if (fb_login_enabled || google_login_enabled) { loginUsingSocialToken() } if (autoFillOTPEnabled) { initAutoOTPFill() } if (localStorage.getItem(CRED_KEY_STRING) && isBiometricLoginEnabled) { loginWithBiometricButton.show() const userCreds = JSON.parse(localStorage.getItem(CRED_KEY_STRING))[0] loginWithBiometricButton.text(loginWithBiometricButton.text() + " as " + userCreds.userEmail) } else { //Basically treat as isBiometricLoginEnabled is false isBiometricLoginEnabled = false } if (allowedLoginMethod == "EMAIL_AND_PHONE" || fb_login_enabled || google_login_enabled || isBiometricLoginEnabled) { continue_text.show() } else { continue_text.hide() } if (allowedLoginMethod == "EMAIL_AND_PHONE" || isBiometricLoginEnabled) { otherLoginMethodsDiv.show() } if (simplifyURLParams.has("checkout_url")) { //there is possibility that input for checkout_url is present , only in cases where we are directly injecting form in liquid, it might not be present const checkoutURLInput = $("input[name=checkout_url]", signInForm) if (checkoutURLInput.length > 0) { //clear relative_route as checkout_url input already present relative_route = "" } else { //set relative_route as checkout_url input relative_route = simplifyURLParams.get("checkout_url") } } if (relative_route && relative_route.length > 0) { //Redirect to a custom endpoint const custom_url = `` signInForm.append(custom_url) } if (SHOPIFY_THEME.indexOf("Lucent PROD") > -1) { $('.account-page-title').hide() getOTPButton.addClass('button-primary') submitOTPButton.addClass('button-primary') submitEmailOTPButton.addClass('button-primary') registerUserButton.addClass('button-primary') } if (SHOP.indexOf("suta") > -1) { getOTPButton.addClass("Form__Submit Button Button--primary Button--full") submitOTPButton.addClass("Form__Submit Button Button--primary Button--full") submitEmailOTPButton.addClass("Form__Submit Button Button--primary Button--full") registerUserButton.addClass("Form__Submit Button Button--primary Button--full") } else { submitOTPButton.addClass("submitOTPButtonClass") submitEmailOTPButton.addClass("submitEmailOTPButtonClass") const submitBtnClassList = signInButton.attr('class') if (submitBtnClassList) { getOTPButton.addClass(submitBtnClassList) submitOTPButton.addClass(submitBtnClassList) submitEmailOTPButton.addClass(submitBtnClassList) registerUserButton.addClass(submitBtnClassList) } } if (SHOP.indexOf("glow-hub-beauty") > -1) { mobileCountryCodeDropdown.css("padding", "16px") $('.selectbox-wrapper').css("margin-top", "40px") getOTPButton.text("Send Code") } if (SHOP.indexOf("sooqaman.myshopify.com") > -1) { submitOTPButton.addClass('black-spinner') submitEmailOTPButton.addClass('black-spinner') continue_text.hide() } if (SHOP.indexOf("therouc") > -1) { $("#resendOTPButton").css("color", "black"); $("#resendEmailOTPButton").css("color", "black"); } if (SHOP.indexOf("chickenwayindia") > -1) { resendOTPButton.css("color", "#D11243") resendEmailOTPButton.css("color", "#D11243") } if (SHOP == "thesovereignsectprebook.myshopify.com") { getOTPButton.text("Get One Time Passcode") resendOTPButton.text("Resend One Time Passcode") submitOTPButton.text("Submit One Time Passcode") const newDiv = `

Trouble Logging In / Enter Phone #

` mobileOTPLoginSection.prepend(newDiv) } if (SHOP == "vannaksemshop.myshopify.com") { getOTPButton.text("Get One Time Code") resendOTPButton.text("Resend One Time Code") submitOTPButton.text("Submit One Time Code") } if (SHOP == "app99.myshopify.com") { continue_text.text("Or") } if (allowedLoginMethod == "ONLY_PHONE") { signInForm.css("padding-bottom", "38px") } if (showTermsAndConditions) { termsAndConditionsCheckbox.click(function() { if (termsAndConditionsCheckbox.is(":checked")) { submitOTPButton.attr("disabled", false); } else { submitOTPButton.attr("disabled", true); } }); } // signInForm.show() signInForm.css('visibility', 'visible') let loginMethodScreen if (allowedLoginMethod == "ONLY_PHONE") { loginMethodScreen = "PHONE_OTP" } if (allowedLoginMethod == "ONLY_EMAIL_PASSWORD") { loginMethodScreen = "EMAIL_PASSWORD" } if (allowedLoginMethod == "EMAIL_AND_PHONE") { loginMethodScreen = localStorage.getItem("SML_LOGIN_METHOD_SCREEN") if (!loginMethodScreen) { //default is login with phone number and otp loginMethodScreen = "PHONE_OTP" } } if (loginMethodScreen == "PHONE_OTP") { loginWithPhoneNumberButton.click() } if (loginMethodScreen == "EMAIL_PASSWORD") { loginWithEmailButton.click() } if (SHOP == "opatra-5041.myshopify.com") { $("#simplify-login-sign-up-text").css("font-size", "14px") } initFirebase() await runOnSMLEventInternal("APP_INIT") } initPage() } const loadSettings = async (data) => { is_disabled = !data.is_enabled allowedLoginMethod = data.allowed_login_method STORE_LANG = data.store_lang LOGIN_EXP = data.login_exp fields_during_signup = data.fields_during_signup fb_login_enabled = data.fb_login_enabled google_login_enabled = data.google_login_enabled selected_country_code = data.selected_country_code relative_route = data.relative_route isBiometricLoginEnabled = data.device_based_login_enabled // check if value exists and is boolean before assigning if (data.is_email_mandatory === true || data.is_email_mandatory === false) { IS_EMAIL_MANDATORY = data.is_email_mandatory } if (SHOP == "inaminute-shop.myshopify.com" || SHOP == "make-it-myn.myshopify.com") { autoFillOTPEnabled = true } if (data.firebase_level) { FIREBASE_LEVEL = data.firebase_level } if (data.show_full_country_name) { SHOW_FULL_COUNTRY_NAME = data.show_full_country_name } if (data.default_country_code) { PHONE_CODE = data.default_country_code } if (data.firebase_config) { FIREBASE_CONFIG = data.firebase_config } if (data.RESEND_OTP_TIMER_ENABLED) { RESEND_OTP_TIMER_ENABLED = data.RESEND_OTP_TIMER_ENABLED } if (data.ASK_PASSWORD_DURING_SIGNUP) { ASK_PASSWORD_DURING_SIGNUP = data.ASK_PASSWORD_DURING_SIGNUP } if (window.location.pathname && window.location.pathname.split('/')[1] == 'en') { STORE_LANG = "ENGLISH" } $(document).ready(async function() { await initExtension() }) } if (window.smlSettings) { loadSettings(smlSettings) } else { $.ajax({ type: 'GET', url: "https://" + SERVER_DOMAIN + "/settings?shop=" + SHOP, success: async function(data) { console.log('settings data: ', data) await loadSettings(data) }, error: function(xhr, status, errorMessage) { console.error("error in settings api ", xhr.responseJSON) }, contentType: "application/json", dataType: 'json' }); }})(simplify_jQuery_3_6_0);

Create Account Forgot Password via Email?

Buy Hair Removal Cream for Women & Men Online at Best Price | O3+ (2024)
Top Articles
Latest Posts
Article information

Author: The Hon. Margery Christiansen

Last Updated:

Views: 6199

Rating: 5 / 5 (70 voted)

Reviews: 85% of readers found this page helpful

Author information

Name: The Hon. Margery Christiansen

Birthday: 2000-07-07

Address: 5050 Breitenberg Knoll, New Robert, MI 45409

Phone: +2556892639372

Job: Investor Mining Engineer

Hobby: Sketching, Cosplaying, Glassblowing, Genealogy, Crocheting, Archery, Skateboarding

Introduction: My name is The Hon. Margery Christiansen, I am a bright, adorable, precious, inexpensive, gorgeous, comfortable, happy person who loves writing and wants to share my knowledge and understanding with you.