1/** 2 * @file 3 * Integrates the My Citizen Profile global header with the ACM session. 4 */ 5 6(function (Drupal, once, drupalSettings) { 7 Drupal.behaviors.myCitizenProfileBehavior = { 8 attach: function (context, settings) { 9 // The widget client stores every captured callback and replays it for 10 // each widget instance, and session.configure() may only be performed 11 // once per page load. Register a single time so that re-attaching on 12 // AJAX or BigPipe does not duplicate the capture, the activity event 13 // listeners or the session configuration. 14 if (!once('my-citizen-profile', 'html').length) { 15 return; 16 } 17 18 // Capture any widget that is present or will be present on the webpage. 19 vl.widget.client.capture(function (widget) { 20 // Only process the widget if widget is a global header. 21 if (widget.getPluginTypeId() === 'global_header') { 22 // Get the Citizen Profile Session extension from the global header widget. 23 widget.getExtension('citizen_profile.session').then(function (session) { 24 /** 25 * Event handler which extends a Citizen Profile session. 26 */ 27 function activityEventHandler() { 28 // Inform the Citizen Profile Session extension about activity. 29 session.extend(); 30 } 31 32 // Build a list of event names which should be used for activity tracking. 33 var eventNames = [ 34 'mousedown', 35 'mousemove', 36 'mousewheel', 37 'DOMMouseScroll', 38 'scroll', 39 'wheel', 40 'keydown', 41 'keypress', 42 'touchmove', 43 'touchstart' 44 ]; 45 // Iterate through the events names to enable activity tracking. 46 for (var i = 0; i < eventNames.length; i++) { 47 // Register our event handler given event name. 48 window.addEventListener(eventNames[i], activityEventHandler); 49 } 50 51 if (drupalSettings.acm.enabled) { 52 // Ensure the fallback login button uses the session instead of redirect to login page. 53 var loginButtonList = document.getElementsByClassName('acm-login-button'); 54 for (var loginButton of loginButtonList) { 55 loginButton.addEventListener('click', function (event) { 56 // Start the login flow using the Citizen Profile Session extension. 57 session.login(); 58 59 // Prevent default behavior as the redirect is no longer required. 60 event.preventDefault(); 61 }); 62 } 63 64 // Ensure the fallback logout button uses the session instead of redirect to logout page. 65 var logoutButtonList = document.getElementsByClassName('acm-logout-button'); 66 for (var logoutButton of logoutButtonList) { 67 logoutButton.addEventListener('click', function (event) { 68 // Start the logout flow using the Citizen Profile Session extension. 69 session.logout(); 70 71 // Prevent default behavior as the redirect is no longer required. 72 event.preventDefault(); 73 }); 74 } 75 76 // This variable is purely to indicate which values are allowed (true / false). 77 var websiteHasAuthenticatedSession = drupalSettings.acm.has_session; 78 79 // Inform the session extension about the current session state of the website. Keep in mind 80 // this operation can only be performed once on every page load. 81 session.configure({ 82 active: websiteHasAuthenticatedSession, 83 endpoints: { 84 loginUrl: '/openid/login', 85 loginRedirectUrl: window.location.href, 86 logoutUrl: '/openid/logout' 87 } 88 }); 89 90 // Also add the current URL to local storage in case we use the fallback scenario without modal. 91 try { 92 window.localStorage.setItem('mcp.redirect', window.location.href); 93 } 94 catch (e) { 95 // No localStorage available. 96 } 97 } 98 }); 99 100 if (drupalSettings.acm.enabled) { 101 // Register for session extend event. 102 widget.on('citizen_profile.session.extend', function (event) { 103 // Perform custom website specific session extend logic. 104 fetch('/openid/validate'); 105 }); 106 107 // Get the Citizen Profile Session extension from the global header widget. 108 widget.on('citizen_profile.session.logout.request', function (logoutRequest) { 109 // Acknowledge the logout request to prevent the session extension from performing default 110 // action due to response timeout (5 seconds). 111 logoutRequest.acknowledge(); 112 113 // Evaluate the type of logout request.
114 switch (logoutRequest.getRequest().getReason()) { 115 // Logout was requested because the citizen profile extension has detected an expired 116 // session which prevents the user from accessing citizen profile without a step-up. 117 // This could be the result of an application logout or external logout. 118 case 'expired': 119 // Validate whether our application still has a valid session. Keep in mind that this 120 // implementation is purely as an example and does not enforce any rules on how a session 121 // state is detected. In our example the API call will return 204 if session is present, 122 // otherwise 401. 123 fetch('/openid/validate') 124 .then(function (response) { 125 // Check whether the application backend reported an active session. 126 if (response.status === 204) { 127 // Reject the logout request as our application still has an active session. 128 logoutRequest.reject(); 129 } 130 else { 131 // Accept the logout request as our application has no active session or failed to 132 // generate a valid response. 133 logoutRequest.accept(); 134 } 135 }) 136 .catch(function () { 137 // Failed to determine the session state accept the request to ensure no session 138 // inconsistency. 139 logoutRequest.accept(); 140 }); 141 break; 142 143 // Logout was requested by the user. This request should never be rejected in normal 144 // circumstances. 145 case 'user': 146 // Logout was requested as the citizen profile extension has detected inactivity from 147 // the user. 148 case 'inactivity': 149 // Accept the request for website logout. 150 logoutRequest.accept(); 151 break; 152 153 default: 154 // Reject the request for website logout. 155 logoutRequest.reject(); 156 break; 157 } 158 }); 159 } 160 } 161 }); 162 } 163 }; 164})(Drupal, once, drupalSettings);
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.