diff --git a/Build/Sources/TypeScript/backend/Resources/Public/TypeScript/LoginRefresh.ts b/Build/Sources/TypeScript/backend/Resources/Public/TypeScript/LoginRefresh.ts index 33ba9dad2026..7c13f3b6a5c2 100644 --- a/Build/Sources/TypeScript/backend/Resources/Public/TypeScript/LoginRefresh.ts +++ b/Build/Sources/TypeScript/backend/Resources/Public/TypeScript/LoginRefresh.ts @@ -261,8 +261,12 @@ class LoginRefresh { class: 'btn btn-primary t3js-active', 'data-action': 'refreshSession', }).text(TYPO3.lang['mess.refresh_login_refresh_button']).on('click', () => { - new AjaxRequest(TYPO3.settings.ajaxUrls.login_timedout).get().then((): void => { + new AjaxRequest(TYPO3.settings.ajaxUrls.login_refresh).get().then(async (response: AjaxResponse): Promise => { + const data = await response.resolve(); this.hideTimeoutModal(); + if (!data.refresh.success) { + this.showLoginForm(); + } }); }), ); diff --git a/typo3/sysext/backend/Classes/Controller/AjaxLoginController.php b/typo3/sysext/backend/Classes/Controller/AjaxLoginController.php index 7872ef8e6eac..6b236b75cd05 100644 --- a/typo3/sysext/backend/Classes/Controller/AjaxLoginController.php +++ b/typo3/sysext/backend/Classes/Controller/AjaxLoginController.php @@ -31,7 +31,7 @@ class AjaxLoginController /** * Handles the actual login process, more specifically it defines the response. * The login details were sent in as part of the ajax request and automatically logged in - * the user inside the TYPO3 CMS bootstrap part of the ajax call. If that was successful, we have + * the user inside the BackendUserAuthenticator middleware. If that was successful, we have * a BE user and reset the timer and hide the login window. * If it was unsuccessful, we display that and show the login box again. * @@ -84,18 +84,20 @@ public function preflightAction(ServerRequestInterface $request): ResponseInterf } /** - * Refreshes the login without needing login information. We just refresh the session. + * Handles the actual session refresh, more specifically it defines the response. + * The session refresh has been performed inside the BackendUserAuthenticator middleware. + * If that was successful, we have a BE user and report that information as response. * * @param ServerRequestInterface $request * @return ResponseInterface */ public function refreshAction(ServerRequestInterface $request): ResponseInterface { - $this->getBackendUser()->checkAuthentication(); + $backendUser = $this->getBackendUser(); return new JsonResponse([ 'refresh' => [ - 'success' => true - ] + 'success' => isset($backendUser->user['uid']), + ], ]); } diff --git a/typo3/sysext/backend/Resources/Public/JavaScript/LoginRefresh.js b/typo3/sysext/backend/Resources/Public/JavaScript/LoginRefresh.js index 1009d30af367..554b73ac3b74 100644 --- a/typo3/sysext/backend/Resources/Public/JavaScript/LoginRefresh.js +++ b/typo3/sysext/backend/Resources/Public/JavaScript/LoginRefresh.js @@ -10,4 +10,4 @@ * * The TYPO3 project - inspiring people to share! */ -var __importDefault=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};define(["require","exports","jquery","TYPO3/CMS/Backend/Modal","TYPO3/CMS/Backend/Notification","TYPO3/CMS/Backend/Severity","TYPO3/CMS/Backend/Storage/Client","TYPO3/CMS/Core/Ajax/AjaxRequest"],(function(e,t,o,i,s,n,a,l){"use strict";var d;o=__importDefault(o),function(e){e.loginrefresh="t3js-modal-loginrefresh",e.lockedModal="t3js-modal-backendlocked",e.loginFormModal="t3js-modal-backendloginform"}(d||(d={}));class r{constructor(){this.options={modalConfig:{backdrop:"static"}},this.webNotification=null,this.intervalTime=60,this.intervalId=null,this.backendIsLocked=!1,this.isTimingOut=!1,this.$timeoutModal=null,this.$backendLockedModal=null,this.$loginForm=null,this.loginFramesetUrl="",this.logoutUrl="",this.submitForm=e=>{e.preventDefault();const t=this.$loginForm.find("form"),i=t.find("input[name=p_field]"),n=t.find("input[name=userident]"),a=i.val();if(""===a&&""===n.val())return s.error(TYPO3.lang["mess.refresh_login_failed"],TYPO3.lang["mess.refresh_login_emptyPassword"]),void i.focus();a&&(n.val(a),i.val(""));const d={login_status:"login"};o.default.each(t.serializeArray(),(function(e,t){d[t.name]=t.value})),new l(t.attr("action")).post(d).then(async e=>{(await e.resolve()).login.success?this.hideLoginForm():(s.error(TYPO3.lang["mess.refresh_login_failed"],TYPO3.lang["mess.refresh_login_failed_message"]),i.focus())})},this.checkActiveSession=()=>{new l(TYPO3.settings.ajaxUrls.login_timedout).get().then(async e=>{const t=await e.resolve();t.login.locked?this.backendIsLocked||(this.backendIsLocked=!0,this.showBackendLockedModal()):this.backendIsLocked&&(this.backendIsLocked=!1,this.hideBackendLockedModal()),this.backendIsLocked||(t.login.timed_out||t.login.will_time_out)&&(t.login.timed_out?this.showLoginForm():this.showTimeoutModal())})}}initialize(){this.initializeTimeoutModal(),this.initializeBackendLockedModal(),this.initializeLoginForm(),this.startTask();const e=!(a.isset("notifications.asked")&&"yes"===a.get("notifications.asked")),t="undefined"!=typeof Notification&&"default"===Notification.permission;e&&"https:"===document.location.protocol&&t&&i.confirm(TYPO3.lang["notification.request.title"],TYPO3.lang["notification.request.description"],n.info,[{text:TYPO3.lang["button.yes"]||"Yes",btnClass:"btn-"+n.getCssClass(n.info),name:"ok",active:!0},{text:TYPO3.lang["button.no"]||"No",btnClass:"btn-"+n.getCssClass(n.notice),name:"cancel"}]).on("confirm.button.ok",()=>{Notification.requestPermission(),i.dismiss()}).on("confirm.button.cancel",()=>{i.dismiss()}).on("hide.bs.modal",()=>{a.set("notifications.asked","yes")})}startTask(){if(null!==this.intervalId)return;let e=1e3*this.intervalTime;this.intervalId=setInterval(this.checkActiveSession,e)}stopTask(){clearInterval(this.intervalId),this.intervalId=null}setIntervalTime(e){this.intervalTime=Math.min(e,86400)}setLogoutUrl(e){this.logoutUrl=e}setLoginFramesetUrl(e){this.loginFramesetUrl=e}showTimeoutModal(){this.isTimingOut=!0,this.$timeoutModal.modal(this.options.modalConfig),this.fillProgressbar(this.$timeoutModal),"https:"===document.location.protocol&&"undefined"!=typeof Notification&&"granted"===Notification.permission&&document.hidden&&(this.webNotification=new Notification(TYPO3.lang["mess.login_about_to_expire_title"],{body:TYPO3.lang["mess.login_about_to_expire"],icon:"/typo3/sysext/backend/Resources/Public/Images/Logo.png"}),this.webNotification.onclick=()=>{window.focus()})}hideTimeoutModal(){this.isTimingOut=!1,this.$timeoutModal.modal("hide"),"undefined"!=typeof Notification&&null!==this.webNotification&&this.webNotification.close()}showBackendLockedModal(){this.$backendLockedModal.modal(this.options.modalConfig)}hideBackendLockedModal(){this.$backendLockedModal.modal("hide")}showLoginForm(){new l(TYPO3.settings.ajaxUrls.logout).get().then(()=>{TYPO3.configuration.showRefreshLoginPopup?this.showLoginPopup():this.$loginForm.modal(this.options.modalConfig)})}showLoginPopup(){const e=window.open(this.loginFramesetUrl,"relogin_"+Math.random().toString(16).slice(2),"height=450,width=700,status=0,menubar=0,location=1");e&&e.focus()}hideLoginForm(){this.$loginForm.modal("hide")}initializeBackendLockedModal(){this.$backendLockedModal=this.generateModal(d.lockedModal),this.$backendLockedModal.find(".modal-header h4").text(TYPO3.lang["mess.please_wait"]),this.$backendLockedModal.find(".modal-body").append(o.default("

").text(TYPO3.lang["mess.be_locked"])),this.$backendLockedModal.find(".modal-footer").remove(),o.default("body").append(this.$backendLockedModal)}initializeTimeoutModal(){this.$timeoutModal=this.generateModal(d.loginrefresh),this.$timeoutModal.addClass("modal-severity-notice"),this.$timeoutModal.find(".modal-header h4").text(TYPO3.lang["mess.login_about_to_expire_title"]),this.$timeoutModal.find(".modal-body").append(o.default("

").text(TYPO3.lang["mess.login_about_to_expire"]),o.default("

",{class:"progress"}).append(o.default("
",{class:"progress-bar progress-bar-warning progress-bar-striped active",role:"progressbar","aria-valuemin":"0","aria-valuemax":"100"}).append(o.default("",{class:"sr-only"})))),this.$timeoutModal.find(".modal-footer").append(o.default("