1// const LOGIN_URL = '/aaa/v3/consumer/authenticate'; // old 2const LOGIN_URL = '/api/v1/aaa/consumer/authenticate'; //digital-portal api 3 4const USER_ID_KEY = 'user_id'; 5const ERROR_MESSAGE_KEY = 'error_message'; 6const CHALLENGE_NAME_KEY = 'challenge_name'; 7const CHALLENGE_PARAMETERS_KEY = 'challenge_parameters'; 8const STEP_KEY = 'step'; 9 10function handleExistingCookies() { 11 let message = getCookie('ath_c_reg'); 12 if (message) { 13 let errorMsg = ` 14 <div class='row genericErrDiv'> 15 <div class='col-12 col-lg-9 offset-lg-1'> 16 <div class="alert alert-success d-flex align-items-center" role="alert"> 17 <i class="text-success fas fa-check-circle align-self-start me-3 fs-3 mt-n1" aria-hidden="true"></i> 18 <strong class="logic-alert-content">${message}</strong> 19 </div> 20 </div> 21 </div>`; 22 $("#divLoginMessage").prepend(errorMsg); 23 setCookie('ath_c_reg', "", 0, ''); 24 } 25 26 message = getCookie('ath_p_msg'); 27 if (message) { 28 let displaymsg = ` 29 <div class='row genericErrDiv'> 30 <div class='col-12 col-lg-9 offset-lg-1'> 31 <div class="alert alert-danger d-flex align-items-center" role="alert"> 32 <i class="text-danger fas fa-exclamation-triangle align-self-start me-3 fs-3 mt-n1" aria-hidden="true"></i> 33 <strong class="logic-alert-content">${message}</strong> 34 </div> 35 </div> 36 </div>`; 37 $("#divLoginMessage").prepend(displaymsg); 38 setCookie('ath_p_msg', '', 0, ''); 39 } 40 41 message = getCookie('ath_t_v'); 42 if (message) { 43 let errorMsg = ''; 44 if (message == 'false') { 45 errorMsg = ` 46 <div class='row genericErrDiv'> 47 <div class='col-12 col-lg-9 offset-lg-1'> 48 <div class="alert alert-danger d-flex align-items-center" role="alert"> 49 <i class="text-danger fas fa-exclamation-triangle align-self-start me-3 fs-3 mt-n1" aria-hidden="true"></i> 50 <strong class="logic-alert-content">Email verification link expired. Please log in to submit a new request.</strong> 51 </div> 52 </div> 53 </div>`; 54 } 55 else { 56 errorMsg = ` 57 <div class='row genericErrDiv'> 58 <div class='col-12 col-lg-9 offset-lg-1'> 59 <div class="alert alert-success d-flex align-items-center" role="alert"> 60 <i class="text-success fas fa-check-circle align-self-start me-3 fs-3 mt-n1" aria-hidden="true"></i> 61 <strong class="logic-alert-content">Registration complete. Log in to view your account.</strong> 62 </div> 63 </div> 64 </div>`; 65 } 66 $("#divLoginMessage").prepend(errorMsg); 67 setCookie('ath_t_v', "", 0, ''); 68 } 69 70} 71 72function _showLoginSkeleton() { 73 $('#loginFormSkeleton').show(); 74 $('#loginFormMyAthene').hide(); 75} 76 77function _hideLoginSkeleton() { 78 $('#loginFormSkeleton').hide(); 79 $('#loginFormMyAthene').fadeIn(200); 80} 81 82$(document).ready(function () { 83 handleExistingCookies(); 84 85 var errorMessage = localStorage.getItem(ERROR_MESSAGE_KEY); 86 if(errorMessage){ 87 showUserErrorDiv("#divLoginMessage", errorMessage); 88 localStorage.removeItem(ERROR_MESSAGE_KEY); 89 } 90 91 _showLoginSkeleton(); 92 _runRecaptchaV3Preflight(); 93 94 $('#atheneLoginBtn').click(function (e) { 95 e.preventDefault(); 96 if (!$('#loginFormMyAthene').valid()) return false; 97 98 $("#divLoginMessage").find('.genericErrDiv').remove(); 99 let userPoolId = Portal.Configs[window.location.hostname]['PP_USER_POOL_ID']; 100 let clientId = Portal.Configs[window.location.hostname]['PP_CLIENT_ID']; 101 let deviceToken = AmazonCognitoAdvancedSecurityData.getData('consumer', userPoolId, clientId); 102 let sanitizedUserId = $("#userId").val(); 103 104 var credentials = { 105 username: sanitizedUserId, 106 password: $('#loginPassword').val(), 107 device_token: deviceToken, 108 }; 109 110 if (_wafSuspicious) { 111 // WAF flagged on page load â use pre-solved token or wait for checkbox solve 112 showRecaptchaV2Checkbox(credentials) 113 .then(function (v2Token) { 114 return submitLogin(credentials, v2Token, 'v2'); 115 }) 116 .then(function (data) { 117 localStorage.setItem(USER_ID_KEY, sanitizedUserId); 118 localStorage.setItem(CHALLENGE_NAME_KEY, data.challenge_name); 119 localStorage.setItem(CHALLENGE_PARAMETERS_KEY, JSON.stringify(data.challenge_parameters)); 120 localStorage.setItem(STEP_KEY, data.step); 121 callbackAuthenticateSuccess(data); 122 }) 123 .catch(function (errorMsg) { 124 showUserErrorDiv("#divLoginMessage", errorMsg); 125 }); 126 return false;
127 } 128 129 getRecaptchaV3Token() 130 .then(function (v3Token) { 131 return submitLogin(credentials, v3Token, 'v3'); 132 }) 133 .then(function (data) { 134 localStorage.setItem(USER_ID_KEY, sanitizedUserId); 135 localStorage.setItem(CHALLENGE_NAME_KEY, data.challenge_name); 136 localStorage.setItem(CHALLENGE_PARAMETERS_KEY, JSON.stringify(data.challenge_parameters)); 137 localStorage.setItem(STEP_KEY, data.step); 138 callbackAuthenticateSuccess(data); 139 }) 140 .catch(function (errorMsg) { 141 showUserErrorDiv("#divLoginMessage", errorMsg); 142 }); 143 144 return false; 145 }); 146 147 jQuery.extend(jQuery.validator.messages, { 148 required: 'Required.', 149 }); 150 $('#loginFormMyAthene').validate({ 151 errorClass: 'invalid-tooltip', 152 rules: { 153 userId: { 154 required: true 155 }, 156 loginPassword: { 157 required: true 158 }, 159 }, 160 }); 161 $("#athene-eye").on("click keydown", function (event) { 162 if ((event.type == 'click') || (event.type == 'keydown' && event.which == 13)) { 163 $(this).toggleClass("fa-eye-slash fa-eye"); 164 var newConfirmPassword = $(this).siblings('input.logic-athene-hide-show'); 165 if (newConfirmPassword.attr("type") == "password") { 166 newConfirmPassword.attr("type", "text"); 167 } else { 168 newConfirmPassword.attr("type", "password"); 169 } 170 } 171 }); 172 173}); 174 175////////////////////////////////////////////////////////////////////// 176// reCAPTCHA v3 (invisible score) + v2 (checkbox fallback) 177////////////////////////////////////////////////////////////////////// 178var _recaptchaV3Loaded = false; 179var _recaptchaV2WidgetId = null; 180var _v2ResolveCallback = null; 181var _v2RejectCallback = null; 182var _wafSuspicious = false; 183var _v2Token = null; 184 185function loadRecaptchaV3() { 186 return new Promise(function (resolve, reject) { 187 if (_recaptchaV3Loaded && window.grecaptcha && window.grecaptcha.enterprise) { 188 resolve(); 189 return; 190 } 191 var siteKey = Portal.Configs[window.location.hostname]['G_RECAPTCHA_V3_SITE_KEY']; 192 var script = document.createElement('script'); 193 script.src = 'https://www.google.com/recaptcha/enterprise.js?render=' + siteKey; 194 script.async = true; 195 script.onload = function () { 196 grecaptcha.enterprise.ready(function () { 197 _recaptchaV3Loaded = true; 198 resolve(); 199 }); 200 }; 201 script.onerror = function () { reject(new Error('reCAPTCHA v3 script failed to load')); }; 202 document.head.appendChild(script); 203 }); 204} 205 206function getRecaptchaV3Token() { 207 var siteKey = Portal.Configs[window.location.hostname]['G_RECAPTCHA_V3_SITE_KEY']; 208 return loadRecaptchaV3().then(function () { 209 return grecaptcha.enterprise.execute(siteKey, { action: 'login' }); 210 }); 211} 212 213function _setRecaptchaLabelError(hasError) { 214 var wrapper = document.getElementById('recaptcha-v2-wrapper'); 215 if (!wrapper) return; 216 var label = wrapper.querySelector('p strong'); 217 if (!label) return; 218 label.style.color = hasError ? '#c62828' : ''; 219} 220 221function _renderV2Widget() { 222 return loadRecaptchaV3().then(function () { 223 var wrapper = document.getElementById('recaptcha-v2-wrapper'); 224 if (!wrapper) { 225 wrapper = document.createElement('div'); 226 wrapper.id = 'recaptcha-v2-wrapper'; 227 wrapper.className = 'border border-warning p-3 mb-3'; 228 var label = document.createElement('p'); 229 label.className = 'mb-2'; 230 label.innerHTML = '<strong>Check "I\'m not a robot" to continue *</strong>'; 231 wrapper.appendChild(label); 232 var container = document.createElement('div'); 233 container.id = 'recaptcha-v2-container'; 234 wrapper.appendChild(container); 235 var loginBtn = document.getElementById('atheneLoginBtn'); 236 loginBtn.parentNode.insertBefore(wrapper, loginBtn); 237 } 238 wrapper.style.display = ''; 239 var container = document.getElementById('recaptcha-v2-container'); 240 if (_recaptchaV2WidgetId === null) { 241 var v2SiteKey = Portal.Configs[window.location.hostname]['G_RECAPTCHA_V2_SITE_KEY']; 242 _recaptchaV2WidgetId = grecaptcha.enterprise.render(container, { 243 sitekey: v2SiteKey, 244 callback: function (token) { 245 _v2Token = token; 246 _setRecaptchaLabelError(false); 247 if (_v2ResolveCallback) { _v2ResolveCallback(token); } 248 }, 249 'expired-callback': function () { 250 _v2Token = null; 251 if (_v2RejectCallback) { _v2RejectCallback('reCAPTCHA expired. Please try again.'); } 252 }, 253 'error-callback': function () { 254 _v2Token = null; 255 if (_v2RejectCallback) { _v2RejectCallback('reCAPTCHA error. Please try again.'); } 256 }, 257 }); 258 } else { 259 _v2Token = null; 260 grecaptcha.enterprise.reset(_recaptchaV2WidgetId); 261 } 262 }); 263} 264 265function _runRecaptchaV3Preflight() { 266 getRecaptchaV3Token().then(function (v3Token) { 267 return fetch('/api/v1/aaa/consumer/authenticate/recaptcha/preflight', { 268 method: 'POST', 269 headers: { 'Content-Type': 'application/json' }, 270 body: JSON.stringify({ recaptchaToken: v3Token }), 271 }); 272 }).then(function (res) { 273 return res.json(); 274 }).then(function (data) { 275 if (data.stepup === true) { 276 _wafSuspicious = true; 277 _renderV2Widget(); 278 } 279 _hideLoginSkeleton(); 280 }).catch(function () { 281 _hideLoginSkeleton(); 282 }); 283} 284 285function showRecaptchaV2Checkbox(credentials) { 286 // If user already solved the pre-rendered widget, use the stored token immediately 287 if (_v2Token) { 288 var token = _v2Token; 289 _v2Token = null; 290 return Promise.resolve(token); 291 } 292 return new Promise(function (resolve, reject) { 293 _v2ResolveCallback = resolve; 294 _v2RejectCallback = reject; 295 _renderV2Widget(); 296 }); 297} 298 299function submitLogin(credentials, recaptchaToken, recaptchaType) { 300 var payload = Object.assign({}, credentials, { 301 recaptchaToken: recaptchaToken || null, 302 recaptchaType: recaptchaType || 'v3', 303 }); 304 305 if (typeof ath_show_loader === 'function') ath_show_loader(); 306 return fetch(LOGIN_URL, { 307 method: 'POST', 308 headers: { 'Content-Type': 'application/json' }, 309 body: JSON.stringify(payload), 310 }).then(function (response) { 311 if (response.status === 202) { 312 if (typeof ath_hide_loader === 'function') ath_hide_loader(); 313 return response.json().then(function (data) { 314 if (data.challenge === 'recaptcha_v2_required') { 315 return showRecaptchaV2Checkbox(credentials).then(function (v2Token) { 316 return submitLogin(credentials, v2Token, 'v2'); 317 }); 318 } 319 return Promise.reject('Something went wrong. Please try again.'); 320 }); 321 } 322 if (!response.ok) { 323 return response.json().then(function (data) { 324 if (_recaptchaV2WidgetId !== null) { 325 _v2Token = null; 326 grecaptcha.enterprise.reset(_recaptchaV2WidgetId); 327 if (!_wafSuspicious && recaptchaType !== 'v2') { 328 var wrapper = document.getElementById('recaptcha-v2-wrapper'); 329 if (wrapper) { wrapper.style.display = 'none'; } 330 } 331 } 332 return Promise.reject(data.msg || 'Something went wrong. Please try again.'); 333 }); 334 } 335 return response.json(); 336 }).then(function (result) { 337 if (typeof ath_hide_loader === 'function') ath_hide_loader(); 338 return result; 339 }).catch(function (err) { 340 if (typeof ath_hide_loader === 'function') ath_hide_loader(); 341 if (_recaptchaV2WidgetId !== null) { 342 _v2Token = null; 343 grecaptcha.enterprise.reset(_recaptchaV2WidgetId); 344 } 345 if (typeof err === 'string') return Promise.reject(err); 346 console.error('Login error:', err); 347 return Promise.reject('Something went wrong. Please try again.'); 348 }); 349} 350 351function callbackAuthenticateSuccess(response) { 352 if (response.id_token) { 353 sessionStorage.setItem('salte.auth.id-token', response.id_token); 354 } 355 if (response.state) { 356 sessionStorage.setItem('salte.auth.$local-state', response.state); 357 sessionStorage.setItem('salte.auth.$state', response.state); 358 sessionStorage.setItem('salte.auth.action.' + response.state
358+ '', 'login'); 359 sessionStorage.setItem('salte.auth.$nonce', response.state); 360 } 361 if (response.expires_in) { 362 sessionStorage.setItem('salte.auth.expiration', response.expires_in); 363 } 364 if (response.token_type) { 365 sessionStorage.setItem('salte.auth.$token-type', response.token_type); 366 } 367 if (response.landing_page) { 368 sessionStorage.setItem('salte.auth.$redirect-url', response.landing_page); 369 } 370 window.location.href = response.redirect_url; 371} 372function showUserErrorDiv(targetDiv, msgId) { 373 $(targetDiv).find('.genericErrDiv').remove(); 374 let errDivHtml = ` 375 <div class="row"> 376 <div class="col-12 col-lg-9 offset-lg-1"> 377 <div class="alert alert-danger d-flex align-items-center genericErrDiv" id="divGenericErrAlert" role="alert"> 378 <i class="text-danger fas fa-exclamation-triangle align-self-start me-3 fs-3 mt-n1" aria-hidden="true"></i> 379 <strong class="logic-alert-content">${msgId}</strong> 380 </div> 381 </div> 382 </div>`; 383 384 if ($(targetDiv).siblings('.genericErrDiv').length == 0) { 385 $(targetDiv).append(errDivHtml); 386 } 387 $('html, body').animate({ 388 scrollTop: 0 389 }, 0); 390}
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.