PageSourceSearch

https://www.americaneagle.ae/scripts/customer/otp.js

js americaneagle.ae collected 2026-10-02 13:25:59 UTC 11,038 bytes, 267 lines download raw bytes

1/* eslint-disable import/no-cycle */
2import { getConfigValue } from '../configs.js';
3import { openModal, closeModal, createModalFromContent } from '../utils.js';
4import {
5  setupOtpValidation,
6  sendOtp,
7  verifyOtp,
8  sendEmailOtp,
9  showErrorMessage,
10} from '../forms.js';
11import { verifyOtpLinkAura } from '../aura/api.js';
12import { welcomeModal } from '../login/login-utils.js';
13import { getCustomer } from './api.js';
14import { dataLayerAuraAutoEnrollmentOtpResend, dataLayerOpenPopup } from '../analytics/google-data-layer.js';
15
16export default async function openOtpVerificationModal(
17  inputElement,
18  countryIso,
19  resendCounter,
20  placeholders,
21) {
22  const customerExistsData = JSON.parse(sessionStorage.getItem('customerExistsData') || '{}');
23  const auraAutoEnrollment = (await getConfigValue('aura-autoenrollment') === 'true');
24  const OTP_VERIFICATION = 'otp-verification-dialog';
25  const modalOtp = document.createElement('div');
26  modalOtp.classList.add('otp-verification-container');
27
28  const otpContainerTitle = placeholders.sentOtpModalTitle || 'Verify';
29  const otpContainerInnerTitleText = document.createElement('p');
30  otpContainerInnerTitleText.textContent = placeholders.sentOtpModalText || 'Please enter the OTP sent to';
31
32  let timerInterval;
33  function startResendOtpTimer() {
34    const timerElement = document.querySelector('.resend-code-text');
35    let timeRemaining = 59; // Start at 59 seconds
36    // Clear any existing interval to avoid multiple timers
37    if (timerInterval) {
38      clearInterval(timerInterval);
39    }
40    timerInterval = setInterval(() => {
41      if (timeRemaining > 0) {
42        timeRemaining -= 1;
43        const seconds = timeRemaining < 10 ? `0${timeRemaining}` : timeRemaining;
44        timerElement.textContent = `${placeholders.resendInText || 'Resend in'} 00:${seconds}s`;
45      } else {
46        clearInterval(timerInterval);
47        timerElement.textContent = `${placeholders.resendotp || 'Resend OTP'}`;
48        timerElement.classList.add('resend-code');
49      }
50    }, 1000); // Update every 1 second
51    document.querySelector('.resend-code-text')?.addEventListener('click', async (event) => {
52      event.preventDefault();
53      if (event.target.classList.contains('resend-code')) {
54        dataLayerAuraAutoEnrollmentOtpResend();
55      }
56      if (countryIso) {
57        sendOtp(inputElement, countryIso, resendCounter, placeholders);
58      } else {
59        sendEmailOtp(inputElement, resendCounter, placeholders);
60      }
61    });
62  }
63
64  if (countryIso) {
65    const otpContainerInnercountryIso = document.createElement('span');
66    otpContainerInnercountryIso.textContent = `+${countryIso}${inputElement.value}`;
67    otpContainerInnerTitleText.append(otpContainerInnercountryIso);
68  } else {
69    otpContainerInnerTitleText.textContent = placeholders.accountFoundSendotpText
70      || 'Aura account found! Please verify the OTP sent to your mobile number to link.';
71  }
72
73  modalOtp.appendChild(otpContainerInnerTitleText);
74
75  const otpFieldsContainer = document.createElement('div');
76  otpFieldsContainer.classList.add('otp-fields-container');
77
78  for (let i = 0; i < 6; i += 1) {
79    const otpInputContainer = document.createElement('div');
80    otpInputContainer.classList.add('otp-input-container');
81    const otpInput = document.createElement('input');
82    otpInput.type = 'text';
83    otpInput.classList.add('otp-input');
84    otpInput.autocomplete = 'off';
85    otpInput.inputMode = 'numeric';
86    otpInput.maxLength = 1;
87    otpInput.pattern = '\\d{1}';
88
89    const line = document.createElement('div');
90    line.classList.add('line');
91
92    otpInputContainer.appendChild(otpInput);
93    otpInputContainer.appendChild(line);
94    otpFieldsContainer.appendChild(otpInputContainer);
95
96    otpInput.addEventListener('input', () => {
97      if (this.value.trim() !== '') {
98        this.nextElementSibling.style.display = 'none';
99      } else {
100        this.nextElementSibling.style.display = 'block';
101      }
102    });
103  }
104  modalOtp.appendChild(otpFieldsContainer);
105
106  const otpMessageContainer = document.createElement('p');
107  otpMessageContainer.textContent = placeholders.invalidOtpMessage || 'Please enter a valid OTP';
108  otpMessageContainer.classList.add('otp-message-container');
109  modalOtp.appendChild(otpMessageContainer);
110
111  const otpVerifyButton = document.createElement('button');
112  otpVerifyButton.textContent = placeholders.otpVerifyButtonText || 'Verify';
113  otpVerifyButton.classList.add('otp-verify-button');
114  otpVerifyButton.disabled = true;
115  modalOtp.appendChild(otpVerifyButton);
116
117  const resendCodeText = document.createElement('p');
118  resendCodeText.classList.add('resend-code-text');
119  resendCodeText.textContent = placeholders.resendCodeText || 'Not received the code?';
120  const resendCode = document.createElement('a');
121  resendCode.href = '';
122  resendCode.textContent = placeholders.resendCode || 'Resend Code';
123  resendCode.classList.add('resend-code');
124  resendCodeText.appendChild(resendCode);
125  modalOtp.appendChild(resendCodeText);
126
127  await createModalFromContent(
128    OTP_VERIFICATION,
129    otpContainerTitle,
130    modalOtp.outerHTML,
131    [OTP_VERIFICATION],
132  );
133  openModal(OTP_VERIFICATION);
134  if (auraAutoEnrollment) {
135    if (resendCounter === 1) {
136      dataLayerOpenPopup('verify otp');
137    }
138    startResendOtpTimer();
139  }
140
141  const otpInputs = document.querySelectorAll('.otp-input');
142  otpInputs.forEach((input) => {
143    input.addEventListener('input', (event) => {
144      event.target.value = event.target.value.replace(/\D/g, '');
145    });
146  });
147
148  const otpLine = document.querySelectorAll('.line');
149  const otpVerifyButtonField = document.querySelector('.otp-verify-button');
150
151  setupOtpValidation(otpInputs, otpVerifyButtonField, otpLine);
152
153  otpVerifyButtonField.addEventListener('click', async (event) => {
154    event.preventDefault();
155    const otp = Array.from(otpInputs).map((i) => i.value).join('');
156    const apcID = customerExistsData?.apcIDNumber || '';
157    if (!!(customerExistsData?.token) || !!(localStorage.getItem('loginType'))) {
158      let auraLinkingStatus;
159      const auraLinkingDetails = JSON.parse(sessionStorage.getItem('_aura_linking_details_social_signin') || '{}');
160      if (auraLinkingDetails) {
161        const { type, value } = auraLinkingDetails;
162        auraLinkingStatus = await verifyOtpLinkAura(otp, '', type, value, true);
163      } else {
164        auraLinkingStatus = await verifyOtpLinkAura(otp, apcID);
165      }
166      if (auraLinkingStatus) {
167        closeModal('otp-verification-dialog');
168        welcomeModal(placeholders);
169      } else {
170        document.querySelector('.otp-verification-container')?.classList.add('otp-error');
171      }
172    } else {
173      const verifyOtpResponse = await verifyOtp(countryIso, inputElement, otp, placeholders);
174      // v1 on success returns true, in v2 on success returns information.
175      const verifyOtpStatus = verifyOtpResponse === true
176        || (verifyOtpResponse?.error === null && verifyOtpResponse?.message === null);
177      if (verifyOtpStatus && auraAutoEnrollment) {
178        const phoneNumber = document.querySelector('.mobile-number-field input');
179        const countryDropdown = document.querySelector('#country-dropdown');
180        const fullNameInput = document.querySelector('#fullname');
181        const changeNumberBtn = document.querySelector('.change-number-element');
182        changeNumberBtn?.classList.add('hidden');
183        countryDropdown.disabled = true;
184        phoneNumber.readOnly = true;
185        document.querySelector('.verifyMobileNumber')?.classList.add('hide');
186        let searchUser = customerExistsData;
187        let loginType = 'Email';
188        const setLoginType = (searchUserFlag) => {
189          if (!customerExistsData?.auraLinked) {
190            loginType = searchUserFlag ? 'Email-Aura_signin' : 'Email-Aura_create';
191          }
192          sessionStorage.setItem('loginType', loginType);
193        };
194
195        if (!(searchUser?.apc_identifier_number) || window.location.href.includes('/register')) {
196          searchUser = verifyOtpResponse;
197          if (searchUser.apc_identifier_number) {
198            sessionStorage.setItem('apcIdentifierNumber', searchUser.apc_identifier_number);
199          }
200          if (!!(fullNameInput) && !!(searchUser?.first_name)) {
201            fullNameInput.value = `${searchUser?.first_name} ${searchUser?.last_name}`;
202          }
203        } else {
204          sessionStorage.setItem('apcIdentifierNumber', searchUser);
205        }
206        const verifiedText = document.createElement('div');
207        verifiedText.innerHTML = ` <p class='verified-text'>
208            <img src="/icons/aura-logo-color.svg">
209            <span>${((!!searchUser?.apc_identifier_number) || (!!customerExistsData?.apcIDNumber)) ? (placeholders?.auraAccountVerifiedText || 'An Aura account was found and verified') : (placeholders?.numberVerifiedAccountCreated || 'Aura account has been created and linked to your account.')}</span>
210          </p>`;
211        document.querySelector('.mobile-number-field')?.insertAdjacentElement('afterend', verifiedText);
212        sessionStorage.removeItem('customerExistsData');
213        setLoginType(!searchUser?.message);
214      }
215    }
216  });
217
218  document.querySelector('.resend-code').addEventListener('click', async (event) => {
219    event.preventDefault();
220    await sendOtp(inputElement, countryIso, resendCounter, placeholders);
221  });
222}
223
224// handle user phone number verification.
225export async function phoneNumberVerification(placeholders) {
226  const cntryCode = document.querySelector('#country-dropdown')?.value;
227  const countryCode = cntryCode.replace('+', '');
228  const mobileNo = document.querySelector('#mobile');
229  const inputFieldWrapper = document.querySelector(
230    '.input-field-wrapper:has(.input-wrapper.mobile-number-field)',
231  );
232  const customerExistsData = JSON.parse(sessionStorage.getItem('customerExistsData'));
233  const mobile = mobileNo.value;
234  if (mobile === '') {
235    const errorMessage = placeholders.noMobileMessage || 'Please enter Mobile Number';
236    showErrorMessage(inputFieldWrapper, errorMessage);
237    return;
238  }
239
240  if (mobile.length !== mobileNo.minLength) {
241    const errorMessage = placeholders.validMobileMessage || 'Please enter Valid Mobile Number';
242    showErrorMessage(inputFieldWrapper, errorMessage);
243    return;
244  }
245
246  if (!(customerExistsData?.maskedMobileNo)) {
247    try {
248      const resendCounter = 0;
249      await sendOtp(mobileNo, countryCode, resendCounter, placeholders);
250    } catch (error) {
251      console.error('Error in handleOtpRequest:', error);
252    }
253  } else if (customerExistsData?.token) {
254    const resendCounter = 0;
255    const customer = await getCustomer();
256    if (customer?.email) {
257      await sendEmailOtp(customer.email, resendCounter, placeholders);
258    }
259  } else {
260    const userEmail = document.querySelector('.email-add')
261      || document.querySelector('.email-info-container p');
262    if (userEmail.textContent) {
263      const resendCounter = 0;
264      await sendEmailOtp(userEmail.textContent, resendCounter, placeholders);
265    }
266  }
267}

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.