CINXE.COM
WSO2 Identity Server
<!doctype html> <html lang="en-US"> <head> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="icon" href="libs/themes/default/assets/images/branding/favicon.ico" type="image/x-icon"/> <link href="libs/themes/default/theme.70534561.min.css" rel="stylesheet"> <title>WSO2 Identity Server</title> <script src="libs/jquery_3.6.0/jquery-3.6.0.min.js"></script> <style> .login-portal.layout { background-image: url('./images/apollo-e-dafne.png'); background-size: cover; background-color: #0073e660; } .ui.primary.button, .ui.primary.button:hover { background-color: #0d6efd; color: #fff; text-shadow: none; } .login-portal.layout .center-segment > .ui.container > .ui.segment { margin: 0; border-radius: 0; border: 0; box-shadow: 0; padding-top: 1em; } a { color: #0a58ca !important; } .ui.header { color: #57617F !important; } </style> <!-- CINECA CUSTOM SPID btn to external idp--> <!--link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous"> <link href='https://fonts.googleapis.com/css?family=Titillium Web' rel='stylesheet'> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-C6RzsynM9kWDrMNeT87bh95OGNyZPhcTNXj1NW7RuBCsyN/o0jlpcV8Qyq46cDfL" crossorigin="anonymous"></script> <script type="text/javascript"src="js/jquery.min.js"></script--> <link rel="stylesheet" href="css/spid-sp-access-button.min.css" /> <script type="text/javascript"src="js/spid-sp-access-button.min.js"></script> <!-- Add only if you want load remotally the idps list --> <script src="js/spid-idps.js"></script> <!-- CINECA CUSTOM SPID btn to external idp--> </head> <body class="login-portal layout authentication-portal-layout" onload="checkSessionKey()"> <script> const ZERO = 0; const THOUSAND_MILLISECONDS = 1000; const ONE_MINUTE = 60; // 1 * 60 Seconds const ONE_HOUR = 60; // 1 * 60 minutes const ONE_DAY = 24; // Hours /** * This function will give you a new instance of a Countdown object. * You can create the instance like for example:- * * const countdown1 = new Countdown(Countdown.seconds(5), function () { * // On done * }, function (time) { * // On tick * }, "MY_TIMER").start(); * * const countdown2 = new Countdown(Countdown.seconds(5), function () { * // On done * }, null, "MY_TIMER").start(); * * const countdown3 = new Countdown(Countdown.seconds(5), function () { * // On done * }).start(); * * * How can you utilize the onTick callback to do stuff? * * If you want to trigger some action on a specific time, what you can do is * check each time component state or in relative time. For example:- * * #1 Time state condition check * ----------------------------- * Now say for example you set a countdown of 5 minutes * and want to run some code after 2 minute and 15 seconds * of the countdown. You can have a condition like:- * * if (time.minutes === 2 && time.seconds === 45) * # will execute once. * if (time.minutes <= 2 && time.seconds <= 45) * # will execute until finished. * * #2 Total time state relative check * ---------------------------------- * Following the same example you can place a condition like below:- * * const checkpoint = Countdown.minutes(2) + Countdown.seconds(15); * * if (time.total === checkpoint) * # will execute once * if (time.total < checkpoint) * # will execute until finished * * @param time {number} as minutes/seconds/hours. * @param onDone {function} called when countdown ends. * @param onTick {function({total: number, hours: number, seconds: number, minutes: number, days: number})} * @param name {String} a descriptive name for the timer. */ function Countdown( time = ZERO, onDone = Countdown.noop, onTick = Countdown.noop, name = "COUNTDOWN" ) { this.until = new Date(Date.now() + time); this.onTick = onTick; this.onDone = onDone; this.name = name; this._enableLogs = false; this._timerInterval = null; this._running = false; } /** * Starts the countdown. If it's running calling this * multiple times won't reset the countdown. */ Countdown.prototype.start = function () { if (!this._running) { // Since we have to use setInterval here we need to make // sure the scope of 'this' is bind to callee. this._timerInterval = setInterval(function () { this.tick(); }.bind(this), THOUSAND_MILLISECONDS); this._running = true; this.log("Countdown: " + this.name + " started."); } return this; }; /** * Stops the countdown. When not running calling this * will have no affect to the countdown instance. */ Countdown.prototype.stop = function () { if (this._running) { clearInterval(this._timerInterval); this._running = false; if (this.onDone) { this.onDone(); } this.log("Countdown " + this.name + " stopped."); } }; Countdown.prototype.log = function (message) { if (this._enableLogs && console && console.debug && message) { console.debug(message); } }; /** * Returns the remaining time as days, hours, minutes, and * seconds. It also include a total sum of epoch seconds * left (multiplied by 1000). */ Countdown.prototype.getRemainingTime = function () { const total = Date.parse(this.until.toString()) - Date.parse(new Date().toString()); const seconds = Math.floor((total / THOUSAND_MILLISECONDS) % ONE_MINUTE); const minutes = Math.floor((total / THOUSAND_MILLISECONDS / ONE_MINUTE) % ONE_MINUTE); const hours = Math.floor((total / (THOUSAND_MILLISECONDS * ONE_MINUTE * ONE_MINUTE)) % ONE_DAY); const days = Math.floor(total / (THOUSAND_MILLISECONDS * ONE_MINUTE * ONE_MINUTE * ONE_DAY)); return { total, days, hours, minutes, seconds }; }; /** * Calls every second when the timer is started. */ Countdown.prototype.tick = function () { const time = this.getRemainingTime(); if (this.onTick) { this.onTick(time); } if (time.total <= ZERO) { this.stop(); } }; Countdown.seconds = function (input) { return (input * ONE_MINUTE * THOUSAND_MILLISECONDS) / ONE_MINUTE; }; Countdown.minutes = function (input) { return input * ONE_MINUTE * THOUSAND_MILLISECONDS; }; Countdown.hours = function (input) { return input * ONE_MINUTE * THOUSAND_MILLISECONDS * ONE_HOUR; }; Countdown.days = function (input) { return (input * ONE_MINUTE * THOUSAND_MILLISECONDS) * ONE_HOUR * ONE_DAY; }; /** * @param time {{ * total: number, * hours: number, * seconds: number, * minutes: number, * days: number * }} */ Countdown.timeToReadable = function (time) { let str = ""; // 1 days(s), 1 hour(s), 1 minute(s) and 30 second(s) let hasPrevious = false; if (time.days > 0) { if (time.days === 1) { str += "1 day"; } else { str += String(time.days) + " days"; } hasPrevious = true; } if (time.hours > 0) { if (hasPrevious) str += ", "; if (time.hours === 1) { str += "1 hour"; } else { str += String(time.hours) + " hours"; } hasPrevious = true; } if (time.minutes > 0) { if (hasPrevious) str += ", "; if (time.minutes === 1) { str += "1 minute"; } else { str += String(time.minutes) + " minutes"; } hasPrevious = true; } if (time.seconds > 0) { if (hasPrevious) str += ", and "; if (time.seconds === 1) { str += "1 second"; } else { str += String(time.seconds) + " seconds"; } } if (!str) return "now"; return "in " + str; }; Countdown.noop = function () { // No operations }; </script> <div class="ui modal tiny notify" id="asg-modal-0"> <div class="animated-icon text-center"> <div class="svg-box" data-testid="session-timeout-modal-warning-animated-icon"> <svg class="circular warning-stroke"> <circle class="path" cx="75" cy="75" r="50" fill="none" stroke-width="2" stroke-miterlimit="10"> </circle> </svg> <svg class="warning-icon warning-stroke"> <g transform="matrix(1,0,0,1,-615.516,-257.346)"> <g transform="matrix(0.56541,-0.56541,0.56541,0.56541,93.7153,495.69)"> <path class="line" d="M634.087,300.805L673.361,261.53" fill="none"></path> </g> <g transform="matrix(2.27612,-2.46519e-32,0,2.27612,-792.339,-404.147)"> <circle class="dot" cx="621.52" cy="316.126" r="1.318"></circle> </g> </g> </svg> </div> </div> <div class="content text-center"> <div class="description"> <div class="ui header" id="asg-modal-0-title"> <b>This sign-in instance is about to timeout!</b> </div> <p id="asg-modal-0-description"> You have been idle in this page for too long. For security reasons,you need to start over or you will be redirected to the sign-in page </p> </div> </div> <div class="actions"> <div class="ui deny button" id="asg-modal-0-dismiss-button"> Dismiss </div> <div class="ui primary button" id="asg-modal-0-action-button"> Start over </div> </div> </div> <script> function ModalRef(onAction = ModalRef.noop, onCancel = ModalRef.noop) { try { this.onAction = onAction; this.onCancel = onCancel; this.modal = $("#asg-modal-0"); this.desc = $("#asg-modal-0-description"); this.cancelBtn = $("#asg-modal-0-dismiss-button"); this.actionBtn = $("#asg-modal-0-action-button"); this.init(); } catch (e) { // Ignore any exceptions. } } ModalRef.prototype.init = function () { if (this.cancelBtn) { this.cancelBtn.click(this.onCancel); } if (this.actionBtn) { this.actionBtn.click(this.onAction); } }; ModalRef.prototype.isActive = function () { return this.modal.hasClass("active"); }; ModalRef.prototype.show = function () { if (this.isActive()) return; this.modal.modal({ detachable: false, closable: false }).modal("show"); }; ModalRef.prototype.hide = function () { this.modal.modal("hide"); }; ModalRef.prototype.changeDescription = function (desc) { this.desc.text(desc); }; ModalRef.prototype.changeDescriptionAsHTML = function (html) { this.desc.html(html); }; ModalRef.prototype.hideDismissButton = function () { this.cancelBtn.hide(); }; ModalRef.prototype.showDismissButton = function () { this.cancelBtn.show(); }; ModalRef.prototype.dispose = function () { this.hide(); this.actionBtn.unbind("click"); this.cancelBtn.unbind("click"); this.onAction = null; this.onCancel = null; this.modal = null; this.desc = null; this.cancelBtn = null; this.actionBtn = null; }; ModalRef.noop = function () { // No operations }; </script> <script> /** * This the props object that holds dynamic server side variables. * This will allow the script functions to access the variable * simply via a object. */ const PROPS = { totalTimeoutMinutes: 35, notifyOnMinute: 2, appAccessUrlEncoded: "", pageName: "sign-in", showModal: false }; if(PROPS.showModal) { $(document).ready(function () { const SPACE_CHAR = " "; const timeout = Countdown.minutes(PROPS.totalTimeoutMinutes); const countdown = new Countdown(timeout, onDone, onTick); const modal = new ModalRef(function (/*Modal onAction*/) { // Once the modal action button clicked, the user will be redirected // to the specified URL immediately. If the url is not available then // it will not redirect or do anything. if (PROPS.appAccessUrlEncoded) { window.location = PROPS.appAccessUrlEncoded; } }); /** * This function will be called everytime when time ticks. * * @param time {{total: number, hours: number, seconds: number, minutes: number, days: number}} */ function onTick(time) { if (time.total < Countdown.minutes(PROPS.notifyOnMinute)) { modal.changeDescriptionAsHTML( "You have been idle in" + SPACE_CHAR + PROPS.pageName + SPACE_CHAR + "page for too long. For security reasons, you need to start over or you will be redirected " + "to the sign-in page" + SPACE_CHAR + "<b>" + Countdown.timeToReadable(time) + "</b>." ); } if (time.total === Countdown.minutes(PROPS.notifyOnMinute)) { modal.show(); } } /** * Once the timer is finished, this method will be * invoked to execute the target action. */ function onDone() { // Once the countdown is over, the user will be redirected // to the access URL immediately. window.location = PROPS.appAccessUrlEncoded; } countdown.start(); }); } </script> <main class="center-segment"> <div class="ui container medium center aligned middle aligned"> <div class="product-title" data-testid="product-title" style="background-color: white;"> <div class="theme-icon inline auto transparent product-logo portal-logo"> <img src="./images/logo_2.png" style="height: 100%;" alt="Cineca" /> </div> </div> <div class="ui segment"> <!-- <h3 class="ui header ellipsis"> Sign In </h3> --> <div class="segment-form"> <script> function onCompleted() { $('#identifierForm').submit(); } $(document).ready(function(){ $.fn.preventDoubleSubmission = function() { $(this).on('submit',function(e){ var $form = $(this); e.preventDefault(); var userName = document.getElementById("username"); userName.value = userName.value.trim(); var genericReCaptchaEnabled = "false"; if (genericReCaptchaEnabled === "true") { if (!grecaptcha.getResponse()) { grecaptcha.execute(); return; } } if (username.value) { $.ajax({ type: "GET", url: "../logincontext?sessionDataKey=9d8040cb-8d32-47e0-b859-147c04a04277&application=PORTALI-SRI&authenticators=SAMLSSOAuthenticator%3ASPID%3BIdentifierExecutor%3ALOCAL&tenantDomain=iccu.it", xhrFields: { withCredentials: true }, success: function (data) { if (data && data.status === "redirect" && data.redirectUrl && data.redirectUrl.length > 0) { window.location.href = data.redirectUrl; } else { document.getElementById("identifierForm").submit(); } }, cache: false }); } }); return this; }; $('#identifierForm').preventDoubleSubmission(); }); </script> <form class="ui large form" action="../commonauth" method="post" id="identifierForm" onsubmit="event.preventDefault()"> <div class="ui visible negative message" style="display: none;" id="error-msg"></div> <div class="field"> <div class="ui fluid left icon input"> <input type="text" id="username" value="" name="username" maxlength="50" tabindex="0" placeholder="User Identifier" required /> <i aria-hidden="true" class="user icon"></i> </div> <input id="authType" name="authType" type="hidden" value="idf"> </div> <input type="hidden" name="sessionDataKey" value='9d8040cb-8d32-47e0-b859-147c04a04277'/> <div class="ui two column stackable grid"> <div class="column align-left buttons"> </div> <div class="column align-right buttons"> <button type="submit" class="ui primary fluid large button" role="button" data-testid="identifier-auth-continue-button" > Continue </button> </div> </div> </form> <!--div class="ui divider hidden"></div> <div class="ui horizontal divider"> Or </div--> <div class="field"> <div class="ui vertical ui center aligned segment form"> <!-- CINECA CUSTOM SPID BTN--> <a href="#" class="italia-it-button italia-it-button-size-m button-spid" style="width:100%" spid-idp-button="#spid-idp-button-medium-get" aria-haspopup="true" aria-expanded="false" onclick="handleNoDomain(this, 'SPID', 'SAMLSSOAuthenticator')" id="icon-2"> <span class="italia-it-button-icon"><img src="images/spid-ico-circle-bb.svg" onerror="this.src='images/spid-ico-circle-bb.png'; this.onerror=null;" alt="" /></span> <span class="italia-it-button-text" style="color: white;">Entra con Identit脿 Digitale</span> </a> <div id="spid-idp-button-medium-get" class="spid-idp-button spid-idp-button-tip spid-idp-button-relative"> </div> </div> </div> </div> </div> </div> </main> <!--footer class="footer" style="text-align: center"> <div class="container-fluid"> <p>WSO2 Identity Server © <script>document.write(new Date().getFullYear());</script> </p> </div> </footer--> <script src="libs/themes/default/semantic.min.js"></script> <script> function onMoment(notification) { displayGoogleSignIn(notification.isNotDisplayed() || notification.isSkippedMoment()); } function displayGoogleSignIn(display) { var element = document.getElementById("googleSignIn"); if (element != null) { if (display) { element.style.display = "block"; } else { element.style.display = "none"; } } } function handleCredentialResponse(response) { $('#credential').val(response.credential); $('#googleOneTapForm').submit(); } function checkSessionKey() { var proxyPath = "" $.ajax({ type: "GET", url: proxyPath + "../logincontext?sessionDataKey=9d8040cb-8d32-47e0-b859-147c04a04277&application=PORTALI-SRI&authenticators=SAMLSSOAuthenticator%3ASPID%3BIdentifierExecutor%3ALOCAL&tenantDomain=iccu.it", xhrFields: { withCredentials: true }, success: function (data) { if (data && data.status == 'redirect' && data.redirectUrl && data.redirectUrl.length > 0) { window.location.href = data.redirectUrl; } }, cache: false }); } function getParameterByName(name, url) { if (!url) { url = window.location.href; } name = name.replace(/[\[\]]/g, '\$&'); var regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)'), results = regex.exec(url); if (!results) return null; if (!results[2]) return ""; return decodeURIComponent(results[2].replace(/\+/g, ' ')); } $(document).ready(function () { $('#user-name-label').popup({ lastResort: 'top left' }); $('.main-link').click(function () { $('.main-link').next().hide(); $(this).next().toggle('fast'); var w = $(document).width(); var h = $(document).height(); $('.overlay').css("width", w + "px").css("height", h + "px").show(); }); $('.overlay').click(function () { $(this).hide(); $('.main-link').next().hide(); }); }); function myFunction(key, value, name) { var object = document.getElementById(name); var domain = object.value; if (domain != "") { document.location = "../commonauth?idp=" + key + "&authenticator=" + value + "&sessionDataKey=9d8040cb-8d32-47e0-b859-147c04a04277&domain=" + domain; } else { document.location = "../commonauth?idp=" + key + "&authenticator=" + value + "&sessionDataKey=9d8040cb-8d32-47e0-b859-147c04a04277"; } } function handleNoDomain(elem, key, value) { var linkClicked = "link-clicked"; if ($(elem).hasClass(linkClicked)) { console.warn("Preventing multi click.") } else { $(elem).addClass(linkClicked); document.location = "../commonauth?idp=" + key + "&authenticator=" + value + "&sessionDataKey=9d8040cb-8d32-47e0-b859-147c04a04277" + "&multiOptionURI=%2Fauthenticationendpoint%2Fdefault_login.jsp%3Fauthenticators%3DSAMLSSOAuthenticator%253ASPID%253BIdentifierExecutor%253ALOCAL%26response_type%3Dcode%26type%3Doidc%26nonce%3DXroqYJCazW6kD7bBuOzTda_Mc8V-DZ2KI9bfYJwRLjY%26tenantDomain%3Diccu.it%26client_id%3DVn7JRfIcJcDbRsaIYvw1XB17_DAa%26relyingParty%3DVn7JRfIcJcDbRsaIYvw1XB17_DAa%26passiveAuth%3Dfalse%26isSaaSApp%3Dfalse%26commonAuthCallerPath%3D%252Foauth2%252Fauthorize%26scope%3Dopenid%2Bemail%2Bprofile%26forceAuth%3Dfalse%26sessionDataKey%3D9d8040cb-8d32-47e0-b859-147c04a04277%26redirect_uri%3Dhttps%253A%252F%252Fopac.sbn.it%252Fc%252Fportal%252Flogin%252Fopenidconnect%26state%3Dj1icqYwl0bpjzu8Pk1mVgjo9g5_81f-o7tt61MLMRbE%26sp%3DPORTALI-SRI"; } } window.onunload = function(){}; function changeUsername (e) { document.getElementById("changeUserForm").submit(); } $('.isHubIdpPopupButton').popup({ popup: '.isHubIdpPopup', on: 'click', position: 'top left', delay: { show: 300, hide: 800 } }); </script> </body> </html>