Advertisement
xosski

XSS sanitation

Feb 10th, 2025
15
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 24.92 KB | None | 0 0
  1. function LoginApp() {
  2.  
  3. /* ----------------------------------------------------------------------------------------------------------------
  4. -------------------------------------------- OBJECT PROPERTIES -------------------------------------------------
  5. ---------------------------------------------------------------------------------------------------------------- */
  6.  
  7. this.baseUri = sessionStorage.getItem("baseUri");
  8. this.debugEnabled = sessionStorage.getItem("debugEnabled") && (sessionStorage.getItem("debugEnabled").toLowerCase() == "true");
  9. this.pushPollInterval;
  10. this.serverSideBaseUri = sessionStorage.getItem("serverSideBaseUri");
  11.  
  12. this.requestState = document.getElementById("requestState").value;
  13. //console.log('loginApp] requestState...: '+ requestState);
  14.  
  15.  
  16. /* ----------------------------------------------------------------------------------------------------------------
  17. -------------------------------------------- HELPER METHODS ----------------------------------------------------
  18. ---------------------------------------------------------------------------------------------------------------- */
  19.  
  20. // Removes the spinner from DOM tree.
  21. // Used, for instance, when an error comes and we have to stop spinning.
  22. this.removeSpinner = function () {
  23. let spinner = document.querySelector("div.loader");
  24. if (spinner != null) {
  25. spinner.parentNode.removeChild(spinner);
  26. }
  27. }
  28.  
  29. // Removes button and show spinner.
  30. // Mainly used on form submission, where submit button is swapped by spinner.
  31. this.removeBtnAndShowSpinner = function (btn) {
  32. btn.style.display = 'none';
  33. var spinnerDiv = document.createElement('div');
  34. spinnerDiv.classList.add('loader');
  35. spinnerDiv.data_res = 'loading-msg';
  36. spinnerDiv.innerHTML = 'Loading...';
  37. // Showing the spinner after btn
  38. btn.parentNode.insertBefore(spinnerDiv, btn.nextSibling);
  39. }
  40.  
  41. // Keeps polling for push notifications at the specified interval.
  42. this.submitPushPoll = function (timeInMillis) {
  43. const self = this;
  44. this.logMsg('submitPushPoll');
  45. this.pushPollInterval = setInterval(function () {
  46. self.logMsg('timer');
  47. let signinTr = document.getElementById("signin-tr");
  48. if ((signinTr) &&
  49. (signinTr.whichFactorForm === "PUSH")) {
  50. self.logMsg(signinTr.whichFactorForm + " is active");
  51.  
  52. // Issue #1 fix. Change introduced to channel the call to submitPushPoll through buildPayload for adding credentials
  53. const payload = self.buildPayload("submitPushPoll", signinTr);
  54. self.logMsg("Invoking submitPushPoll with payload " + self.mask(payload));
  55. self.sdk.submitPushPoll(payload);
  56. // End of fix.
  57. }
  58. }, timeInMillis);
  59. }
  60.  
  61. // Stops polling for push notifications
  62. this.stopPushPoll = function () {
  63. if (this.pushPollInterval != null) {
  64. this.removeSpinner();
  65. this.logMsg('Stopping push poll...');
  66. clearInterval(this.pushPollInterval);
  67. }
  68. }
  69.  
  70. this.showReinputUserName = function (formDiv, obj, timeInMilis) {
  71. if (formDiv && formDiv.whichForm != null && formDiv.whichForm === "FORGOT_PASSWORD_FORM") {
  72. var usernameLocal = formDiv.querySelector("#forgotUserName").value;
  73.  
  74. let didNotGetMsg = this.localizeMsg('forgot-pw-incorrect-username-msg', 'Incorrect UserName?');
  75. let resendMsg = this.localizeMsg('forgot-pw-incorrect-username-btn', 'Fix UserName');
  76.  
  77. setTimeout(function () {
  78. formDiv.appendChild(document.createElement('hr'));
  79.  
  80. var resendDivElem = document.createElement('div');
  81. resendDivElem.classList.add('sameline');
  82. resendDivElem.innerHTML = '<span class="info">' + didNotGetMsg + '</span>&nbsp;' +
  83. '<a href="#" id="resend-username-btn">' + resendMsg + '</a>';
  84.  
  85. // Adding the Resend Option preferably right after the submit button.
  86. let submitBtnElem = formDiv.querySelector("#submit-btn");
  87. if (submitBtnElem) {
  88. submitBtnElem.parentNode.insertBefore(resendDivElem, submitBtnElem.nextSibling);
  89. }
  90. else {
  91. formDiv.appendChild(resendDivElem);
  92. }
  93.  
  94. formDiv.querySelector("#resend-username-btn").onclick = function () {
  95. obj.displayForgotPassWordForm();
  96.  
  97. };
  98. }, timeInMilis);
  99. }
  100. }
  101.  
  102. // Localizes all labels inside formDiv
  103. this.localize = function (formDiv) {
  104. if (resources) {
  105. var resElms = formDiv.querySelectorAll('[data-res]');
  106. for (var n = 0; n < resElms.length; n++) {
  107. var elem = resElms[n];
  108. var resKey = elem.getAttribute('data-res');
  109. if (resKey) {
  110. if (resources[resKey]) {
  111. elem.innerHTML = resources[resKey];
  112. }
  113. else {
  114. this.logWarning("Translation missing for resource key '" + resKey + "'");
  115. }
  116. }
  117. }
  118. }
  119. } // this.localize
  120.  
  121. // Returns the message associated with a given key. If the key isn't found, the message (msg) as passed is returned.
  122. this.localizeMsg = function (resKey, msg) {
  123. if (resources && resources[resKey]) {
  124. return resources[resKey];
  125. }
  126. else {
  127. this.logWarning("Translation missing for resource key '" + resKey + "'");
  128. return msg;
  129. }
  130. }
  131.  
  132. this.mask = function (msg) {
  133. let propsToMask = ['username', 'password', 'bypasscode', 'otpcode', 'questions', 'deviceid', 'requeststate', 'phonenumber', 'token', 'authntoken', 'trusttoken', 'userid'];
  134.  
  135. var stars = '***';
  136. var temp;
  137. try {
  138. if (msg !== Object(msg)) {
  139. temp = JSON.parse(msg); // Object deep copy, except methods, that we don't need here.
  140. }
  141. else {
  142. temp = JSON.parse(JSON.stringify(msg)); // Object deep copy, except methods, that we don't need here.
  143. }
  144. for (key in temp) {
  145. if (temp.hasOwnProperty(key)) {
  146. if (temp[key] !== Object(temp[key]) && propsToMask.indexOf(key.toLowerCase()) != -1) { // key is not a object
  147. temp[key] = stars;
  148. }
  149.  
  150. else if (Array.isArray(temp[key]) && propsToMask.indexOf(key.toLowerCase()) != -1) { // key is an object array
  151. temp[key] = stars; // we're simply masking the whole array, don't care about the contents.
  152. }
  153.  
  154. else { // key is simple object
  155. for (subkey in temp[key]) {
  156. if (temp[key].hasOwnProperty(subkey) && propsToMask.indexOf(subkey.toLowerCase()) != -1) {
  157. temp[key][subkey] = stars;
  158. }
  159. }
  160. }
  161. }
  162. }
  163. return JSON.stringify(temp);
  164. }
  165. catch (e) {
  166. return stars;
  167. }
  168. } //this.mask
  169.  
  170. this.logMsg = function (msg) {
  171. if (window.console && this.debugEnabled) {
  172. console.log('LoginApp: ' + msg);
  173. }
  174. } // this.logMsg
  175.  
  176. this.logWarning = function (msg) {
  177. console.log('LoginApp (WARNING): ' + msg);
  178. }
  179.  
  180. this.replaceDiv = function (divid, replacement, dofocus) {
  181. // divname is the ID of the div to replace
  182. // replacement is the Element to replace it with
  183. // dofocus says "set the focus to the first text input"
  184.  
  185. // Note: for the signin-Tr the replacement div SHOULD havr a .id prop
  186. // matching the one that's being replacing
  187. if (replacement.id != divid) {
  188. this.logMsg("WARNING: replacement div id=" + replacement.id + " does not match expected value of " + divid);
  189. }
  190.  
  191. // Localizing while replacement div still not visible.
  192. this.localize(replacement);
  193.  
  194. var oldForm = document.getElementById(divid);
  195. if (oldForm) {
  196. oldForm.parentNode.replaceChild(replacement, oldForm);
  197. }
  198.  
  199. this.showReinputUserName(replacement, this, 2000);
  200.  
  201. // find the first text input field and put the focus there
  202. if (dofocus) {
  203. div = document.getElementById(divid);
  204. if (div) {
  205. let firstInput = div.querySelector('input[type="text"]');
  206. if (firstInput) firstInput.focus();
  207. }
  208. }
  209. }
  210.  
  211. // Performs form data validation and style form elements accordingly
  212. this.validateForm = function (formDiv) {
  213. formDiv.querySelector("#submit-btn").disabled = true;
  214. // Looking for input fields marked as required and empty.
  215. const inputFields = formDiv.getElementsByTagName("INPUT");
  216. var isError = false;
  217. for (i = 0; i < inputFields.length; i++) {
  218. this.logMsg('Validating field ' + inputFields[i].id);
  219. if (inputFields[i].required && inputFields[i].value.trim() === '') {
  220. isError = true;
  221. // Toggling the element class for styling on error.
  222. inputFields[i].classList.add('on__error');
  223. }
  224. }
  225. if (isError) {
  226. let errorMessage = this.localizeMsg('error-required-fld', 'Required field empty');
  227. this.setLoginErrorMessage({ code: '', msg: errorMessage });
  228. formDiv.querySelector("#submit-btn").disabled = false;
  229. return false;
  230. }
  231. this.logMsg('Validation OK.');
  232. this.removeBtnAndShowSpinner(formDiv.querySelector("#submit-btn"));
  233. return true;
  234. }
  235.  
  236. // Handles focusout event on input fields for styling the field
  237. this.handleFocusOutEvent = function (elem) {
  238. elem.addEventListener('focusout', function () {
  239. if (elem.value.trim().length == 0) {
  240. elem.classList.add('on__error');
  241. }
  242. else {
  243. elem.classList.remove('on__error');
  244. }
  245. });
  246. }
  247.  
  248. // Handles onClick event for submiting form data.
  249. this.handleClickToSubmitEvent = function (formDiv, obj, methodName, includeAuthnFactor) {
  250. const self = this;
  251. formDiv.querySelector("#submit-btn").onclick = function () {
  252. if (obj.validateForm(formDiv)) {
  253. const payload = obj.buildPayload(methodName, formDiv);
  254. if (payload) { // Giving a chance for buildPayload to fail.
  255. self.logMsg("Invoking " + methodName + " with credentials " + self.mask(payload));
  256. obj.sdk[methodName](payload, includeAuthnFactor);
  257. }
  258. else {
  259. this.log("handleClickToSubmitEvent: [BUG] payload must not be null");
  260. }
  261. }
  262. }
  263. }
  264.  
  265. // Handles onKeyPress event for submiting form data.
  266. this.handleKeyPressToSubmitEvent = function (formDiv, elem, obj, methodName, includeAuthnFactor) {
  267. const self = this;
  268. elem.onkeypress = function (event) {
  269. if (event.keyCode == 13) {
  270. if (obj.validateForm(formDiv)) {
  271. const payload = obj.buildPayload(methodName, formDiv);
  272. if (payload) { // Giving a chance for buildPayload to fail.
  273. self.logMsg("Invoking " + methodName + " with credentials " + self.mask(payload));
  274. obj.sdk[methodName](payload, includeAuthnFactor);
  275. }
  276. else {
  277. this.log("handleKeyPressToSubmitEvent: [BUG] payload must not be null");
  278. }
  279. }
  280. }
  281. }
  282. }
  283.  
  284. // Handles onClick event for handling forgotPassword.
  285. this.handleClickEvent = function (formDiv, obj) {
  286.  
  287. }
  288.  
  289. // Builds the expected credentials payload to the respective API in the SDK, here identified by methodName.
  290. this.buildPayload = function (methodName, formDiv) {
  291. console.log('*** LoginApp buildPayload');
  292.  
  293. // ER #1. Saving the request origin. This is read later for determining the user preferred factor.
  294. this.setUnPwOrigin("true");
  295. var data = {
  296. "username": document.getElementById("userid").value,
  297. "password": document.getElementById("password").value,
  298. "origin": window.location.origin
  299. }
  300. if (document.getElementById("kmsi") != null) {
  301. data["keepMeSignedIn"] = document.getElementById("kmsi").checked;
  302. return data;
  303. }
  304. return data;
  305. }
  306.  
  307. /* ----------------------------------------------------------------------------------------------------------------
  308. -------------------------------------------- MAIN METHODS ------------------------------------------------------
  309. ---------------------------------------------------------------------------------------------------------------- */
  310.  
  311. // Generic method for displaying a form, identified by which (the factor) and step (which build method to call)
  312. this.displayForm = function (which, step, payload, username) {
  313. const self = this;
  314.  
  315. this.logMsg("Which: " + which);
  316. this.logMsg("Step: " + step);
  317. this.logMsg("Payload: " + this.mask(payload));
  318.  
  319. // "which" will be the key to this.AuthenticationFactorInfo
  320. var formDiv = document.createElement('tr');
  321. formDiv.classList.add("form");
  322. formDiv.classList.add("sign-in");
  323. formDiv.id = 'signin-tr';
  324. // our own tag so we can suppress this option if the user clicks alternative
  325. formDiv.whichFactorForm = which;
  326. formDiv.step = step;
  327.  
  328. if (which === "spinner") {
  329. formDiv.innerHTML = '<tr class="loader" data-res="loading-msg">Loading...</tr>';
  330. this.replaceDiv("signin-tr", formDiv, true);
  331. }
  332. else
  333. if (this.AuthenticationFactorInfo[which]) {
  334. if (step === "submitCreds") {
  335. (this.AuthenticationFactorInfo[which]["loginFormFunction"])(formDiv, payload);
  336.  
  337. // hide stuff that is not needed except on the initial screen
  338. if ((which !== "USERNAME_PASSWORD") && (which !== "USERNAME") && (which !== "PASSWORD")) {
  339. Array.prototype.slice.call(document.querySelectorAll('.hidelater')).forEach(function (e) { // Making MS (IE and Edge) family happy
  340. e.style.visibility = "hidden";
  341. });
  342.  
  343.  
  344. }
  345.  
  346. this.replaceDiv("signin-tr", formDiv, true);
  347. }
  348. }
  349.  
  350. }
  351.  
  352. // Builds the main form, allowing username/password posting + IDP selection
  353. // Logic has been moved into buildForm
  354. this.buildUidPwForm = function (formDiv, IDPdata) {
  355. this.buildForm(formDiv, "showUidPw", IDPdata, true);
  356. }
  357.  
  358. // this function builds both the UID + PW and/or the IDP chooser form
  359. // this is all in one function to avoid duplicating code or comments
  360. // the boolean showUidPw determines whether to show the uid+pw portion
  361. this.buildForm = function (formDiv, showField, IDPdata, isFirstForm) {
  362. const self = this;
  363. var showUidOrUidPwFields = true;
  364.  
  365. let keepMeSignedIn = JSON.parse(this.getLoginCtx())["keepMeSignedInEnabled"];
  366. let checkbox = "";
  367. formDiv.innerHTML +=
  368. '<label><span style="font-weight: bold;font-size:12px;padding-left:5px;margin-left:5px" data-res="signin-username-fld">Username</span><span class="mandatory_field">*</span><input style="margin-left:3px" type="text" id="userid" value="" required></label>' +
  369. '<label><span style="font-weight: bold;font-size:12px;padding-left:5px;margin-left:5px" data-res="signin-password-fld">Password</span><span class="mandatory_field">*</span><input style="margin-left:8px" type="password" id="password" value="" required></label>';
  370.  
  371. if (showUidOrUidPwFields) {
  372. formDiv.innerHTML +=
  373. '<label class="error-msg" id="login-error-msg"></label>' + checkbox +
  374. '<br/><button type="button" style="width: 80px;margin-left:75px" class="btn btn-primary btn-sm btn-color shadow rounded"" id="submit-btn" data-res="signin-submit-btn">Sign In</button>'
  375. }
  376.  
  377. // and now that we're done updating the HTML of that div we can
  378. // attach the event handlers for clicking or hitting enter
  379. if (showUidOrUidPwFields) {
  380. if (showField == "showUid") {
  381. this.handleClickToSubmitEvent(formDiv, this, 'postUserName');
  382. this.handleKeyPressToSubmitEvent(formDiv, formDiv.querySelector("#userid"), this, 'postUserName');
  383. }
  384. else {
  385. this.handleClickToSubmitEvent(formDiv, this, 'postCreds');
  386. this.handleKeyPressToSubmitEvent(formDiv, formDiv.querySelector("#password"), this, 'postCreds');
  387. }
  388. this.handleClickEvent(formDiv, this);
  389. }
  390.  
  391. return formDiv;
  392. }; // this.buildForm
  393.  
  394.  
  395. // This method works as the app main controller, directing requests to the appropriate methods based on the received payload from IDCS.
  396. this.nextOperation = function (payload, username) {
  397.  
  398. this.logMsg("nextOperation: " + this.mask(payload));
  399.  
  400. if (payload.requestState && payload.nextOp) {
  401.  
  402. this.setRequestState(payload.requestState);
  403.  
  404. if (payload.nextOp[0] === 'credSubmit') {
  405. if (payload.nextAuthFactors) {
  406.  
  407. if (payload.nextAuthFactors.includes('USERNAME_PASSWORD')) {
  408. this.displayPasswordForm(payload);
  409. }
  410. if (payload.nextAuthFactors.includes('IDP')) {
  411. this.displayIDPChooserForm(payload);
  412. }
  413.  
  414. // else {
  415. var sameFactorMultipleDevices = false;
  416. payload.nextAuthFactors.forEach(function (factor) {
  417. if (payload[factor] && payload[factor].enrolledDevices && payload[factor].enrolledDevices.length > 0) {
  418. sameFactorMultipleDevices = true;
  419. }
  420. });
  421. // Fix on bug reported by Pulkit Agarwal on 12/04/18. Used to happen when MFA is active for a Social User that isn't registered in IDCS.
  422. // We must send the user to enrollment where enrollment is also in nextOp array.
  423. if (payload.nextOp[1] === "enrollment") {
  424. this.displayEnrollmentOptionsForm(payload);
  425. }
  426. // End of fix.
  427. // If there's more than one nextAuthFactor or multiple devices for the same factor, we go to alternative factors flow.
  428. else if (payload.nextAuthFactors.length > 1 && payload.nextAuthFactors.includes("USERNAME") && payload.nextOp.includes("credSubmit")) {
  429. if (!this.getUnPwOrigin() || this.getUnPwOrigin() === "true") {
  430. this.setPreferredFactor({ factor: payload.nextAuthFactors[0], displayName: payload.displayName });
  431. this.setUnPwOrigin("false");
  432. }
  433. this.displayForm(payload.nextAuthFactors[0], "submitCreds", payload);
  434. }
  435.  
  436. else {
  437. // ER #1
  438. // Doing this because the API response not always tell whether the factor is the preferred one.
  439. // Setting the user preferred factor. It's the one returned from username/password submit.
  440. // We may also come here via Social Login, in which case the origin is undefined.
  441. if (!this.getUnPwOrigin() || this.getUnPwOrigin() === "true") {
  442. this.setPreferredFactor({ factor: payload.nextAuthFactors[0], displayName: payload.displayName });
  443. this.setUnPwOrigin("false");
  444. }
  445. // End of ER #1.
  446. this.displayForm(payload.nextAuthFactors[0], "submitCreds", payload);
  447. // }
  448. }
  449. }
  450. }
  451. else {
  452. this.logMsg('Do not know what to do with given payload.');
  453. }
  454. }
  455. }; // this.nextOperation
  456.  
  457. /* ----------------------------------------------------------------------------------------------------------------
  458. -------------------------------------------- HELPER METHODS ----------------------------------------------------
  459. ---------------------------------------------------------------------------------------------------------------- */
  460.  
  461. this.addErrorDetailsIfAny = function (errorElem, details) {
  462. if (details != null) {
  463. var detailsDiv = document.createElement('div');
  464. detailsDiv.classList.add('newline');
  465. for (i = 0; i < details.length; i++) {
  466. detailsDiv.innerHTML += '<span class="error-msg-detail">' + details[i] + '</span>';
  467. }
  468. errorElem.appendChild(detailsDiv);
  469. }
  470. }
  471.  
  472. this.handleBackendError = function (error) {
  473. var errorMsg = '';
  474. if (error) {
  475. errorMsg = error.msg;
  476. if (error.code.indexOf('AUTH-1120') != -1) {
  477. errorMsg = this.localizeMsg('error-AUTH-1120', 'Invalid state. Please, reinitiate login');
  478. }
  479. else if (error.code.indexOf('AUTH-1112') != -1) {
  480. errorMsg = this.localizeMsg('error-AUTH-1112', 'Access denied');
  481. }
  482. else if (error.code.indexOf('SDK-AUTH') != -1) {
  483. errorMsg = this.localizeMsg('error-' + error.code, error.msg);
  484. }
  485. else if (error.code.indexOf('SSO-') != -1 && error.msg === 'undefined') {
  486. errorMsg = this.localizeMsg('error-' + error.code, '<Undefined error message>');
  487. }
  488. else {
  489. this.logMsg('Passing backend error message as is: ' + errorMsg);
  490. }
  491. }
  492. return errorMsg;
  493. }
  494.  
  495. this.changeButtonOnError = function (button) {
  496. if (button) {
  497. button.style.display = 'block';
  498. button.disabled = false;
  499. }
  500. }
  501.  
  502. this.clearErrorsOnScreenIfAny = function () {
  503. var socialErrorElem = document.getElementById("social-login-error-msg");
  504. if (socialErrorElem) {
  505. socialErrorElem.innerHTML = '';
  506. }
  507. var loginErrorElem = document.getElementById("login-error-msg");
  508. if (loginErrorElem) {
  509. loginErrorElem.innerHTML = '';
  510. }
  511. }
  512.  
  513. this.setLoginErrorMessage = function (error) {
  514. this.clearErrorsOnScreenIfAny();
  515. var errorElemId = "login-error-msg";
  516. if (error.type === 'social') {
  517. errorElemId = "social-login-error-msg";
  518. }
  519.  
  520. this.stopPushPoll();
  521. this.removeSpinner();
  522. var errorMsg = this.handleBackendError(error);
  523.  
  524. var errorElem = document.getElementById(errorElemId);
  525. if (errorElem) {
  526.  
  527. this.changeButtonOnError(document.querySelector("#submit-btn"));
  528. errorElem.innerHTML = errorMsg;
  529. this.addErrorDetailsIfAny(errorElem, error.details);
  530. }
  531. else {
  532. var formDiv = document.createElement('div');
  533. formDiv.id = 'signin-tr';
  534. formDiv.classList.add('form');
  535.  
  536. var errorLabel = document.createElement('label');
  537. errorLabel.id = errorElemId;
  538. errorLabel.classList.add('error-msg');
  539. errorLabel.innerHTML = errorMsg;
  540.  
  541. formDiv.appendChild(errorLabel);
  542. this.replaceDiv("signin-tr", formDiv, true)
  543. }
  544. }
  545.  
  546. this.getBackendErrorMsg = function () {
  547. var error = sessionStorage.getItem('backendError'); // This is set by the server-side backend
  548. if (error) {
  549. sessionStorage.removeItem('backendError');
  550. return error;
  551. }
  552. return;
  553. }
  554.  
  555. this.encodeValueChars = function (str) {
  556. return (
  557. encodeURIComponent(str)
  558. // Note that although RFC3986 reserves "!", RFC5987 does not,
  559. // so we do not need to escape it
  560. .replace(/['()]/g, escape) // i.e., %27 %28 %29
  561. .replace(/\*/g, "%2A")
  562. // The following are not required for percent-encoding per RFC5987,
  563. // so we can allow for a little better readability over the wire: |`^
  564. .replace(/%(?:7C|60|5E)/g, unescape)
  565. );
  566. }
  567.  
  568. this.htmlEscape = function (string) {
  569. return String(string)
  570. .replace(/&/g, '&amp;')
  571. .replace(/"/g, '&quot;')
  572. .replace(/'/g, '&#39;')
  573. .replace(/</g, '&lt;')
  574. .replace(/>/g, '&gt;');
  575. }
  576.  
  577. this.setAccessToken = function (at) {
  578. return sessionStorage.setItem("signinAT", at);
  579. }
  580.  
  581. this.getAccessToken = function () {
  582. return sessionStorage.getItem("signinAT");
  583. }
  584.  
  585. this.isIDPUserInIDCS = function () {
  586. return sessionStorage.getItem("isIDPUserInIDCS");
  587. }
  588.  
  589. this.getIDPAuthnToken = function () {
  590. return sessionStorage.getItem("IDPAuthnToken");
  591. }
  592.  
  593. this.getLoginCtx = function () {
  594. return sessionStorage.getItem("initialState");
  595. }
  596.  
  597. this.setRequestState = function (rs) {
  598. sessionStorage.setItem("requestState", rs);
  599. }
  600.  
  601. this.getRequestState = function () {
  602. return sessionStorage.getItem("requestState");
  603. }
  604.  
  605. this.getClientId = function () {
  606. return sessionStorage.getItem("clientId");
  607. }
  608.  
  609. this.getInitialState = function () {
  610. return sessionStorage.getItem("initialState");
  611. }
  612.  
  613. // This object is used mostly by method displayForm, telling it which form to build.
  614. const self = this;
  615. this.AuthenticationFactorInfo = {
  616. USERNAME_PASSWORD: {
  617. // this one is only used for the initial login screen
  618. label: "Username and password",
  619. loginFormFunction: function (formdiv, payload) { self.buildUidPwForm(formdiv, payload); },
  620. },
  621. USERNAME: {
  622. // this one is only used for the initial login screen
  623. label: "Username",
  624. loginFormFunction: function (formdiv, payload) { self.buildUidForm(formdiv, payload); },
  625. },
  626. IDP: {
  627. // If the admin removes "local IDP" in the IDP Policies then IDCS asks custom login app
  628. // to display only the IDP chooser on the intiial form
  629. label: "Select an IDP",
  630. loginFormFunction: function (formdiv, payload) { self.buildIdpChooserForm(formdiv, payload.IDP, true); },
  631. }
  632. }
  633. this.setUnPwOrigin = function (flag) {
  634. sessionStorage.setItem("unPwOrigin", flag)
  635. }
  636.  
  637. this.getOperation = function () {
  638. return sessionStorage.getItem("operation");
  639. }
  640.  
  641. this.getToken = function () {
  642. return decodeURIComponent(sessionStorage.getItem("token"));
  643. }
  644.  
  645. this.ToBeImplemented = function (which) {
  646. alert("Case " + which + " needs to be implemented!");
  647. }
  648.  
  649. this.sdk = new IdcsAuthnSDK(this);
  650. this.sdk.initAuthentication();
  651. }; // function loginApp
  652.  
  653. const loginApp = new LoginApp();
  654. loginApp.localize(document);
  655.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement