[TASK] Rewrite Backend Login JS to use jQuery 26/31826/6
authorBenjamin Mack <benni@typo3.org>
Wed, 27 Aug 2014 09:31:06 +0000 (11:31 +0200)
committerBenjamin Mack <benni@typo3.org>
Mon, 8 Sep 2014 09:58:20 +0000 (11:58 +0200)
The backend login process uses various
JavaScript parts.

1) Some basic redirects on pure JavaScript
that is inline in the LoginController.

2) A flat and hardcoded JS file in the
login.html template which actually
uses ExtJS and Prototype for various
cookie checks and usability checks.

3) RSA Authentication with Backend Login
for doing an AJAX call. This is done in
ExtJS.

All of the parts above are rewritten
using the proper API calls based on
jQuery.

Resolves: #60576
Releases: 6.3
Change-Id: Ie64c4736c79327b816c39da5bba533bcc65cee45
Reviewed-on: http://review.typo3.org/31826
Reviewed-by: Wouter Wolters <typo3@wouterwolters.nl>
Tested-by: Wouter Wolters <typo3@wouterwolters.nl>
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
Reviewed-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
Tested-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
Reviewed-by: Benjamin Mack <benni@typo3.org>
Tested-by: Benjamin Mack <benni@typo3.org>
typo3/sysext/backend/Classes/Controller/LoginController.php
typo3/sysext/backend/Resources/Private/Templates/login.html
typo3/sysext/backend/Resources/Public/JavaScript/Login.js [new file with mode: 0755]
typo3/sysext/backend/Resources/Public/JavaScript/login.js [deleted file]
typo3/sysext/rsaauth/Classes/Hook/LoginFormHook.php
typo3/sysext/rsaauth/Resources/Public/JavaScript/BackendLoginFormRsaEncryption.js
typo3/sysext/t3skin/Resources/Public/Css/structure/login_screen.css

index 68bae6e..edff1e9 100644 (file)
@@ -191,21 +191,28 @@ class LoginController {
         */
        public function main() {
                // Initialize template object:
-               $GLOBALS['TBE_TEMPLATE']->bodyTagAdditions = ' onload="startUp();"';
                $GLOBALS['TBE_TEMPLATE']->moduleTemplate = $GLOBALS['TBE_TEMPLATE']->getHtmlTemplate('EXT:backend/Resources/Private/Templates/login.html');
                /** @var $pageRenderer \TYPO3\CMS\Core\Page\PageRenderer */
                $pageRenderer = $GLOBALS['TBE_TEMPLATE']->getPageRenderer();
-               $pageRenderer->loadExtJS();
-               $pageRenderer->loadPrototype();
-               $pageRenderer->loadScriptaculous();
                $pageRenderer->loadJquery();
                // support placeholders for IE9 and lower
                $clientInfo = GeneralUtility::clientInfo();
                if ($clientInfo['BROWSER'] == 'msie' && $clientInfo['VERSION'] <= 9) {
                        $pageRenderer->addJsLibrary('placeholders', 'contrib/placeholdersjs/placeholders.jquery.min.js');
                }
-               // Set JavaScript for creating a MD5 hash of the password:
-               $GLOBALS['TBE_TEMPLATE']->JScode .= $this->getJScode();
+
+               $pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/Login');
+               if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/index.php']['loginScriptHook'])) {
+                       foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/index.php']['loginScriptHook'] as $function) {
+                               $params = array();
+                               $JSCode = GeneralUtility::callUserFunction($function, $params, $this);
+                               if ($JSCode) {
+                                       $GLOBALS['TBE_TEMPLATE']->JScode .= $JSCode;
+                                       break;
+                               }
+                       }
+               }
+
                // Checking, if we should make a redirect.
                // Might set JavaScript in the header to close window.
                $this->checkRedirect();
@@ -476,7 +483,7 @@ class LoginController {
         * Returns the login box image, whether the default or an image from the rotation folder.
         *
         * @return string HTML image tag.
-        * @deprecated since 7, see Deprecation-60559-MakeLoginBoxImage.rst
+        * @deprecated since 6.3, see Deprecation-60559-MakeLoginBoxImage.rst
         */
        public function makeLoginBoxImage() {
                GeneralUtility::logDeprecatedFunction();
@@ -560,7 +567,7 @@ class LoginController {
                // The form defaults to 'no login'. This prevents plain
                // text logins to the Backend. The 'sv' extension changes the form to
                // use superchallenged method and rsaauth extension makes rsa authetication.
-               $form = '<form action="index.php" method="post" name="loginform" ' . 'onsubmit="alert(\'No authentication methods available. Please, ' . 'contact your TYPO3 administrator.\');return false">';
+               $form = '<form action="index.php" method="post" name="loginform" ' . 'onsubmit="alert(\'No authentication methods available. Please, contact your TYPO3 administrator.\');return false">';
                // Call hooks. If they do not return anything, we fail to login
                if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/index.php']['loginFormHook'])) {
                        foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/index.php']['loginFormHook'] as $function) {
@@ -572,7 +579,7 @@ class LoginController {
                                }
                        }
                }
-               $output .= $form . '<input type="hidden" name="login_status" value="login" />' . '<input type="hidden" name="userident" value="" />' . '<input type="hidden" name="redirect_url" value="' . htmlspecialchars($this->redirectToURL) . '" />' . '<input type="hidden" name="loginRefresh" value="' . htmlspecialchars($this->loginRefresh) . '" />' . $this->interfaceSelector_hidden . $this->addFields_hidden;
+               $output .= $form . '<input type="hidden" name="login_status" value="login" />' . '<input type="hidden" id="t3-field-userident" name="userident" value="" />' . '<input type="hidden" name="redirect_url" value="' . htmlspecialchars($this->redirectToURL) . '" />' . '<input type="hidden" name="loginRefresh" value="' . htmlspecialchars($this->loginRefresh) . '" />' . $this->interfaceSelector_hidden . $this->addFields_hidden;
                return $output;
        }
 
@@ -581,88 +588,10 @@ class LoginController {
         *
         * @return string JavaScript code
         * @todo Define visibility
+        * @deprecated since TYPO3 6.3, not in use anymore
         */
        public function getJScode() {
-               $JSCode = '';
-               if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/index.php']['loginScriptHook'])) {
-                       foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/index.php']['loginScriptHook'] as $function) {
-                               $params = array();
-                               $JSCode = GeneralUtility::callUserFunction($function, $params, $this);
-                               if ($JSCode) {
-                                       break;
-                               }
-                       }
-               }
-               $JSCode .= $GLOBALS['TBE_TEMPLATE']->wrapScriptTags('
-                       function startUp() {
-                                       // If the login screen is shown in the login_frameset window for re-login, then try to get the username of the current/former login from opening windows main frame:
-                               try {
-                                       if (parent.opener && parent.opener.TS && parent.opener.TS.username && document.loginform && document.loginform.username) {
-                                               document.loginform.username.value = parent.opener.TS.username;
-                                       }
-                               }
-                               catch(error) {
-                                       //continue
-                               }
-
-                                       // Wait a few millisecons before calling checkFocus(). This might be necessary because some browsers need some time to auto-fill in the form fields
-                               window.setTimeout("checkFocus()", 50);
-                       }
-
-                               // This moves focus to the right input field:
-                       function checkFocus() {
-                                       // If for some reason there already is a username in the username form field, move focus to the password field:
-                               if (document.loginform.username && document.loginform.username.value == "") {
-                                       document.loginform.username.focus();
-                               } else if (document.loginform.p_field && document.loginform.p_field.type!="hidden") {
-                                       document.loginform.p_field.focus();
-                               }
-                       }
-
-                               // This function shows a warning, if user has capslock enabled
-                               // parameter showWarning: shows warning if TRUE and capslock active, otherwise only hides warning, if capslock gets inactive
-                       function checkCapslock(e, showWarning) {
-                               if (!isCapslock(e)) {
-                                       document.getElementById(\'t3-capslock\').style.display = \'none\';
-                               } else if (showWarning) {
-                                       document.getElementById(\'t3-capslock\').style.display = \'block\';
-                               }
-                       }
-
-                               // Checks weather capslock is enabled (returns TRUE if enabled, false otherwise)
-                               // thanks to http://24ways.org/2007/capturing-caps-lock
-
-                       function isCapslock(e) {
-                               var ev = e ? e : window.event;
-                               if (!ev) {
-                                       return;
-                               }
-                               var targ = ev.target ? ev.target : ev.srcElement;
-                               // get key pressed
-                               var which = -1;
-                               if (ev.which) {
-                                       which = ev.which;
-                               } else if (ev.keyCode) {
-                                       which = ev.keyCode;
-                               }
-                               // get shift status
-                               var shift_status = false;
-                               if (ev.shiftKey) {
-                                       shift_status = ev.shiftKey;
-                               } else if (ev.modifiers) {
-                                       shift_status = !!(ev.modifiers & 4);
-                               }
-                               return (((which >= 65 && which <= 90) && !shift_status) ||
-                                       ((which >= 97 && which <= 122) && shift_status));
-                       }
-
-                               // prevent opening the login form in the backend frameset
-                       if (top.location.href != self.location.href) {
-                               top.location.href = self.location.href;
-                       }
-
-                       ');
-               return $JSCode;
+               GeneralUtility::logDeprecatedFunction();
        }
 
        /**
index 09f1c4f..b43f456 100644 (file)
@@ -15,7 +15,7 @@
                        </noscript>
                        <div id="t3-nocookies-error" class="t3-login-alert t3-login-alert-warning" style="display:none">
                                <h2>###ERROR_COOKIES###</h2>
-                               <div id="t3-nocookies-ignore"><a href="#"  onclick="TYPO3BackendLogin.hideCookieWarning()">###ERROR_COOKIES_IGNORE###</a></div>
+                               <div id="t3-nocookies-ignore"><a href="#" onclick="TYPO3.BackendLogin.hideCookieWarning()">###ERROR_COOKIES_IGNORE###</a></div>
                        </div>
                        <!--[if lte IE 6]>
                        ###WARNING_BROWSER_INCOMPATIBLE###
@@ -28,7 +28,6 @@
 
                </div>
        </div>
-       <script type="text/javascript" src="sysext/backend/Resources/Public/JavaScript/login.js"></script>
 
        ###NEWS###
 
diff --git a/typo3/sysext/backend/Resources/Public/JavaScript/Login.js b/typo3/sysext/backend/Resources/Public/JavaScript/Login.js
new file mode 100755 (executable)
index 0000000..77281f0
--- /dev/null
@@ -0,0 +1,287 @@
+/**
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+define('TYPO3/CMS/Backend/Login', ['jquery'], function($) {
+
+       var isWebKit = document.childNodes && !document.all && !navigator.taintEnabled;
+       var BackendLogin = {
+               options: {
+                       usernameField: '#t3-username',
+                       passwordField: '#t3-password',
+                       useridentField: '#t3-field-userident',
+                       openIdField: '#openid_url',
+                       submitButton: '#t3-login-submit',
+                       clearIconSelector: '.t3-login-clearInputField',
+                       interfaceSelector: '#t3-interfaceselector'
+               }
+       },
+       options = BackendLogin.options;
+
+       // Checks weather capslock is enabled (returns TRUE if enabled, false otherwise)
+       // thanks to http://24ways.org/2007/capturing-caps-lock
+       BackendLogin.isCapslockEnabled = function(e) {
+               var ev = e ? e : window.event;
+               if (!ev) {
+                       return;
+               }
+               // get key pressed
+               var which = -1;
+               if (ev.which) {
+                       which = ev.which;
+               } else if (ev.keyCode) {
+                       which = ev.keyCode;
+               }
+               // get shift status
+               var shift_status = false;
+               if (ev.shiftKey) {
+                       shift_status = ev.shiftKey;
+               } else if (ev.modifiers) {
+                       shift_status = !!(ev.modifiers & 4);
+               }
+               return (((which >= 65 && which <= 90) && !shift_status) ||
+                       ((which >= 97 && which <= 122) && shift_status));
+       };
+
+       /**
+        * Change to Interface for OpenId login and save the selection to a cookie
+        */
+       BackendLogin.switchToOpenId = function() {
+               $('t3-login-openIdLogo').show();
+
+               $('#t3-login-form-footer-default').hide();
+               $('#t3-login-form-footer-openId').show();
+
+               $('#t3-login-username-section, #t3-login-password-section').hide();
+               $('#t3-login-openid_url-section').show();
+               $('#t3-login-interface-section').hide();
+
+               $(options.openIdField).trigger('focus');
+               if ($(options.usernameField).val() == '') {
+                       $(options.usernameField).val('openid_url');
+               }
+
+               setLogintypeCookie('openid');
+       };
+
+       /**
+        * Change to Interface for default login and save the selection to a cookie
+        */
+       BackendLogin.switchToDefault = function() {
+               $('#t3-login-openIdLogo').hide();
+
+               if ($(options.usernameField).val() == 'openid_url') {
+                       $(options.usernameField).val('');
+               }
+
+               $('#t3-login-form-footer-default').show();
+               $('#t3-login-form-footer-openId').hide();
+               $('#t3-login-username-section, #t3-login-password-section').show();
+               $('#t3-login-openid_url-section').hide();
+               $('#t3-login-interface-section').show();
+
+               $(options.usernameField).trigger('focus');
+
+               setLogintypeCookie('username');
+       };
+
+       /**
+        * Hide all form fields and show a progress message and icon
+        */
+       BackendLogin.showLoginProcess = function() {
+               // setting a fixed height (based on the current, calculated height of the browser) for
+               // the box with the login form, so it doesn't jump around when the spinner is shown
+               var loginBoxHeight = $('#t3-login-form-fields').height();
+               $('#t3-login-process').height(loginBoxHeight).show();
+               $('#t3-login-error').hide();
+               $('#t3-login-form-fields').hide();
+               $('#t3-nocookies-error').hide();
+       };
+
+       /**
+        * Store a login type in a cookie to save it for future visits
+        * Login type means whether you login by username/password or OpenID
+        */
+       BackendLogin.setLogintypeCookie = function(type) {
+               var now = new Date();
+               var expires = new Date(now.getTime() + 1000*60*60*24*365); // cookie expires in one year
+               document.cookie = 'typo3-login-method=' + type + '; expires=' + expires.toGMTString() + ';';
+       };
+
+       /**
+        * Check if a login type was stored in a cookie and change the Interface accordingly
+        */
+       BackendLogin.checkForLogintypeCookie = function() {
+               if (document.cookie.indexOf('typo3-login-method=openid') >- 1) {
+                       BackendLogin.switchToOpenId();
+               }
+       };
+
+       /**
+        * Store the new selected Interface in a cookie to save it for future visits
+        */
+       BackendLogin.interfaceSelectorChanged = function() {
+               var now = new Date();
+               var expires = new Date(now.getTime() + 1000*60*60*24*365); // cookie expires in one year
+               document.cookie = 'typo3-login-interface=' + $(options.interfaceSelector).val() + '; expires=' + expires.toGMTString() + ';';
+       };
+
+       /**
+        * Shows up the clear icon for a field which is not empty, and hides it otherwise
+        */
+       BackendLogin.setVisibilityOfClearIcon = function($formFieldElement) {
+               if ($formFieldElement.val().length > 0) {
+                       $formFieldElement.next(options.clearIconSelector).find('a').show();
+               } else {
+                       $formFieldElement.next(options.clearIconSelector).find('a').hide();
+               }
+       };
+
+       /**
+        * Clears an input field and sets focus to it
+        */
+       BackendLogin.clearInputField = function($formFieldElement) {
+               $formFieldElement.val('').focus();
+       };
+
+       /**
+        * Check if an interface was stored in a cookie and preselect it in the select box
+        */
+       BackendLogin.checkForInterfaceCookie = function() {
+               if ($(options.interfaceSelector).length) {
+                       var posStart = document.cookie.indexOf('typo3-login-interface=');
+                       if (posStart != -1) {
+                               var selectedInterface = document.cookie.substr(posStart + 22);
+                               selectedInterface = selectedInterface.substr(0, selectedInterface.indexOf(';'));
+                       }
+                       $(options.interfaceSelector).val(selectedInterface);
+               }
+       };
+
+       /**
+        * To prevent its unintented use when typing the password, the user is warned when Capslock is on
+        */
+       BackendLogin.showCapsLockWarning = function($alertIconElement, event) {
+               if (BackendLogin.isCapslockEnabled(event) === true) {
+                       $alertIconElement.show();
+               } else {
+                       $alertIconElement.hide();
+               }
+       };
+
+       /**
+        * Hides input fields and shows cookie warning
+        */
+       BackendLogin.showCookieWarning = function() {
+               $('#t3-login-form-fields').hide();
+               $('#t3-nocookies-error').show();
+       };
+
+       /**
+        * Hides cookie warning and shows input fields
+        */
+       BackendLogin.hideCookieWarning = function() {
+               $('#t3-nocookies-error').hide();
+               $('#t3-login-form-fields').show();
+       };
+
+       /**
+        * Checks browser's cookie support
+        * see http://stackoverflow.com/questions/8112634/jquery-detecting-cookies-enabled
+        */
+       BackendLogin.checkCookieSupport = function() {
+               var cookieEnabled = navigator.cookieEnabled;
+
+               // when cookieEnabled flag is present and false then cookies are disabled.
+               if (cookieEnabled === false) {
+                       BackendLogin.showCookieWarning();
+               } else {
+                       // try to set a test cookie if we can't see any cookies and we're using
+                       // either a browser that doesn't support navigator.cookieEnabled
+                       // or IE (which always returns true for navigator.cookieEnabled)
+                       if (!document.cookie && (cookieEnabled === null || /*@cc_on!@*/false)) {
+                               document.cookie = 'typo3-login-cookiecheck=1';
+
+                               if (!document.cookie) {
+                                       BackendLogin.showCookieWarning();
+                               } else {
+                                       // unset the cookie again
+                                       document.cookie = 'typo3-login-cookiecheck=; expires=' + new Date(0).toUTCString();
+                               }
+                       }
+               }
+       };
+
+       /**
+        * Registers listeners for the Login Interface (e.g. to toggle OpenID and Default login)
+        */
+       BackendLogin.initializeEvents = function() {
+               $(document).on('click', '#t3-login-switchToOpenId', BackendLogin.switchToOpenId);
+               $(document).on('click', '#t3-login-switchToDefault', BackendLogin.switchToDefault);
+               $(document).on('click', options.submitButton, BackendLogin.showLoginProcess);
+
+                       // The Interface selector is not always present, so this check is needed
+               if ($(options.interfaceSelector).length > 0) {
+                       $(document).on('change blur', options.interfaceSelector, BackendLogin.interfaceSelectorChanged);
+               }
+
+               $(document).on('click', options.clearIconSelector, function() {
+                       BackendLogin.clearInputField($(this).prev());
+               });
+               $(document).on('focus blur keypress', options.usernameField + ', ' + options.passwordField + ', ' + options.openIdField, function() {
+                       BackendLogin.setVisibilityOfClearIcon($(this));
+               });
+               if (!isWebKit) {
+                       $(document).on('keypress', options.usernameField + ', ' + options.passwordField + ', ' + options.openIdField, function(evt) {
+                               BackendLogin.showCapsLockWarning($(this).siblings('.t3-login-alert-capslock'), evt);
+                       });
+               }
+       };
+       // intialize and return the BackendLogin object
+       return function() {
+
+               $(document).ready(function() {
+                       BackendLogin.checkForInterfaceCookie();
+                       BackendLogin.checkForLogintypeCookie();
+                       BackendLogin.checkCookieSupport();
+                       BackendLogin.initializeEvents();
+
+                       // previously named "startUp"
+
+                       // If the login screen is shown in the login_frameset window for re-login,
+                       // then try to get the username of the current/former login from opening windows main frame:
+                       try {
+                               if (parent.opener && parent.opener.TS && parent.opener.TS.username) {
+                                       $(options.usernameField).val(parent.opener.TS.username);
+                               }
+                       } catch(error) {} // continue
+
+                       BackendLogin.setVisibilityOfClearIcon($(options.usernameField));
+                       BackendLogin.setVisibilityOfClearIcon($(options.passwordField));
+
+                       // previously named "check focus"
+                       if ($(options.usernameField).val() == '') {
+                               $(options.usernameField).focus();
+                       } else if ($(options.passwordField).attr('type') !== 'hidden') {
+                               $(options.passwordField).focus();
+                       }
+
+               });
+
+               // prevent opening the login form in the backend frameset
+               if (top.location.href != self.location.href) {
+                       top.location.href = self.location.href;
+               }
+
+               TYPO3.BackendLogin = BackendLogin;
+               return BackendLogin;
+       }();
+});
\ No newline at end of file
diff --git a/typo3/sysext/backend/Resources/Public/JavaScript/login.js b/typo3/sysext/backend/Resources/Public/JavaScript/login.js
deleted file mode 100644 (file)
index 4091e9e..0000000
+++ /dev/null
@@ -1,259 +0,0 @@
-var isWebKit = document.childNodes && !document.all && !navigator.taintEnabled;
-
-TYPO3BackendLogin = {
-
-       /**
-        *  Initializing the Login Interface
-        */
-       start: function() {
-               TYPO3BackendLogin.preloadImages();
-               TYPO3BackendLogin.registerEventListeners();
-               TYPO3BackendLogin.setVisibilityOfClearIcon($('t3-username'), $('t3-username-clearIcon'));
-               TYPO3BackendLogin.setVisibilityOfClearIcon($('t3-password'), $('t3-password-clearIcon'));
-               TYPO3BackendLogin.checkCookieSupport();
-               TYPO3BackendLogin.checkForLogintypeCookie();
-               TYPO3BackendLogin.checkForInterfaceCookie();
-               $('t3-username').activate();
-       },
-
-       /**
-        * Preload the login process image, so it can show up immediatelly after submitting
-        */
-       preloadImages: function() {
-               var image = new Image();
-               image.src = 'sysext/t3skin/icons/login-submit-progress.gif';
-       },
-
-       /**
-        * Registers listeners for the Login Interface (e.g. to toggle OpenID and Default login)
-        */
-       registerEventListeners: function() {
-               Event.observe(
-                               $('t3-login-switchToOpenId'),
-                               'click',
-                               TYPO3BackendLogin.switchToOpenId
-                       );
-               Event.observe(
-                       $('t3-login-switchToDefault'),
-                       'click',
-                       TYPO3BackendLogin.switchToDefault
-               );
-               Event.observe(
-                       $('t3-login-submit'),
-                       'click',
-                       TYPO3BackendLogin.showLoginProcess
-               );
-
-                       // The Interface selector is not always present, so this check is needed
-               if (Object.isElement($('t3-interfaceselector'))) {
-                       TYPO3BackendLogin.observeEvents(
-                               $('t3-interfaceselector'),
-                               ['change', 'blur'],
-                               TYPO3BackendLogin.interfaceSelectorChanged
-                       );
-               }
-
-               $A(['t3-username', 't3-password', 'openid_url']).each(function(value) {
-                       Event.observe(
-                                       $(value + '-clearIcon'),
-                                       'click',
-                                       function() { TYPO3BackendLogin.clearInputField($(value)); }
-                       );
-                       TYPO3BackendLogin.observeEvents(
-                                       $(value),
-                                       ['focus', 'blur', 'keypress'],
-                                       function() { TYPO3BackendLogin.setVisibilityOfClearIcon($(value), $(value + '-clearIcon')); }
-                       );
-                       if (!isWebKit) {
-                               Event.observe(
-                                       $(value),
-                                       'keypress',
-                                       function(event) { TYPO3BackendLogin.showCapsLockWarning($(value + '-alert-capslock'), event); }
-                               );
-                       }
-               })
-       },
-
-       /**
-        * Wrapper for Event.observe that takes an array with events, instead of only one event
-        */
-       observeEvents: function(element, events, handler) {
-               events.each(function(event) {
-                       Event.observe(
-                               element,
-                               event,
-                               handler
-                       );
-               });
-       },
-
-       /**
-        * Shows up the clear icon for a field which is not empty, and hides it otherwise
-        */
-       setVisibilityOfClearIcon: function(formField, clearIcon) {
-               if (formField.value) {
-                       clearIcon.show();
-               } else {
-                       clearIcon.hide();
-               }
-       },
-
-       /**
-        * To prevent its unintented use when typing the password, the user is warned when Capslock is on
-        */
-       showCapsLockWarning: function(alertIcon, event) {
-               if (isCapslock(event)) {
-                       alertIcon.show();
-               } else {
-                       alertIcon.hide();
-               }
-       },
-
-       /**
-        * Clears an input field and sets focus to it
-        */
-       clearInputField: function(formField) {
-               formField.value = '';
-               formField.focus();
-       },
-
-       /**
-        * Change to Interface for OpenId login and save the selection to a cookie
-        */
-       switchToOpenId: function() {
-               $('t3-login-openIdLogo').show();
-
-               $('t3-login-form-footer-default').hide();
-               $('t3-login-form-footer-openId').show();
-               $('t3-login-username-section').hide();
-               $('t3-login-password-section').hide();
-               $('t3-login-openid_url-section').show();
-
-               if ($('t3-login-interface-section')) {
-                       $('t3-login-interface-section').hide();
-               }
-
-               $('openid_url').activate();
-               if ($('t3-username').getValue() == '') {
-                       $('t3-username').setValue('openid_url');
-               }
-
-               TYPO3BackendLogin.setLogintypeCookie('openid');
-       },
-
-       /**
-        * Change to Interface for default login and save the selection to a cookie
-        */
-       switchToDefault: function() {
-               $('t3-login-openIdLogo').hide();
-
-               if ($('t3-username').getValue() == 'openid_url') {
-                       $('t3-username').setValue('');
-               }
-
-               $('t3-login-form-footer-default').show();
-               $('t3-login-form-footer-openId').hide();
-               $('t3-login-username-section').show();
-               $('t3-login-password-section').show();
-               $('t3-login-openid_url-section').hide();
-
-               if ($('t3-login-interface-section')) {
-                       $('t3-login-interface-section').show();
-               }
-
-               $('t3-username').activate();
-
-               TYPO3BackendLogin.setLogintypeCookie('username');
-       },
-
-       /**
-        * Checks browser's cookie support
-        */
-       checkCookieSupport: function() {
-               Ext.util.Cookies.set('typo3-login-cookiecheck', true);
-               cookieEnabled = Ext.util.Cookies.get('typo3-login-cookiecheck');
-
-               if (!cookieEnabled) {
-                       TYPO3BackendLogin.showCookieWarning()
-               }
-
-               Ext.util.Cookies.set('typo3-login-cookiecheck', '', new Date(0));
-       },
-
-       /**
-        * Hides input fields and shows cookie warning
-        */
-       showCookieWarning: function() {
-               Ext.get('t3-login-form-fields').setVisibilityMode(Ext.Element.DISPLAY).hide();
-               Ext.get('t3-nocookies-error').show();
-       },
-
-       /**
-        * Hides cookie warning and shows input fields
-        */
-       hideCookieWarning: function() {
-               Ext.get('t3-nocookies-error').setVisibilityMode(Ext.Element.DISPLAY).hide();
-               Ext.get('t3-login-form-fields').show();
-       },
-
-       /**
-        * Store a login type in a cookie to save it for future visits
-        * Login type means whether you login by username/password or OpenID
-        */
-       setLogintypeCookie: function(type) {
-               var now = new Date();
-               var expires = new Date(now.getTime() + 1000*60*60*24*365); // cookie expires in one year
-               document.cookie = 'typo3-login-method=' + type + '; expires=' + expires.toGMTString() + ';';
-       },
-
-       /**
-        * Check if a login type was stored in a cookie and change the Interface accordingly
-        */
-       checkForLogintypeCookie: function() {
-               if(document.cookie.indexOf('typo3-login-method=openid') >- 1) {
-                       TYPO3BackendLogin.switchToOpenId();
-               }
-       },
-
-       /**
-        * Store the new selected Interface in a cookie to save it for future visits
-        */
-       interfaceSelectorChanged: function(event) {
-               var now = new Date();
-               var expires = new Date(now.getTime() + 1000*60*60*24*365); // cookie expires in one year
-               document.cookie = 'typo3-login-interface=' + $('t3-interfaceselector').getValue() + '; expires=' + expires.toGMTString() + ';';
-       },
-
-       /**
-        * Check if an interface was stored in a cookie and preselect it in the select box
-        */
-       checkForInterfaceCookie: function() {
-               if (Object.isElement($('t3-interfaceselector'))) {
-                       var posStart = document.cookie.indexOf('typo3-login-interface=');
-                       if (posStart != -1) {
-                               var selectedInterface = document.cookie.substr(posStart + 22);
-                               selectedInterface = selectedInterface.substr(0, selectedInterface.indexOf(';'));
-                       }
-                       $('t3-interfaceselector').setValue(selectedInterface);
-               }
-       },
-
-       /**
-        * Hide all form fields and show a progress message and icon
-        */
-       showLoginProcess: function() {
-               if ($('t3-login-error')) {
-                       $('t3-login-error').hide();
-               }
-
-               $('t3-login-form-fields').hide();
-               $('t3-nocookies-error').hide();
-
-               // setting a fixed height (based on the current, calculated height of the browser) for
-               // the box with the login form, so it doesn't jump around when the spinner is shown
-               var loginBoxHeight = $('t3-login-form-fields').getHeight();
-               $('t3-login-process').setStyle({height: loginBoxHeight + 'px'}).show();
-       }
-};
-
-Ext.onReady(TYPO3BackendLogin.start, TYPO3BackendLogin);
index 4028b0b..3e7f577 100644 (file)
@@ -41,13 +41,14 @@ class LoginFormHook {
                                'jsbn/prng4.js',
                                'jsbn/rng.js',
                                'jsbn/rsa.js',
-                               'jsbn/base64.js',
-                               'BackendLoginFormRsaEncryption.js'
+                               'jsbn/base64.js'
                        );
                        foreach ($files as $file) {
                                $pageRenderer->addJsFile($javascriptPath . $file);
                        }
 
+                       $pageRenderer->loadRequireJsModule('TYPO3/CMS/Rsaauth/BackendLoginFormRsaEncryption');
+
                        return '<form action="index.php" id="typo3-login-form" method="post" name="loginform">';
                }
                return $form;
index 53b9670..c1da8bf 100644 (file)
 /**
  * Object that handles RSA encryption and submission of the form
  */
-TYPO3RsaBackendLogin = {
+define('TYPO3/CMS/Rsaauth/BackendLoginFormRsaEncryption', ['jquery', 'TYPO3/CMS/Backend/Login'], function($, BackendLogin) {
 
-       /**
-        * Field in which users enter their password
-        */
-       userPasswordField: '',
+       var RsaBackendLogin = {
 
-       /**
-        * Field that is used by TYPO3 to evaluate the password during login process
-        */
-       typo3PasswordField: '',
+               /**
+                * Field in which users enter their password
+                */
+               userPasswordField: false,
 
-       /**
-        * Replace event handler of submit button
-        */
-       initialize: function() {
-               this.userPasswordField = document.loginform.p_field;
-               this.typo3PasswordField = document.loginform.userident;
-               var submitButton = $('t3-login-submit');
-               Event.stopObserving(
-                       submitButton,
-                       'click',
-                       TYPO3BackendLogin.showLoginProcess
-               );
-               Event.observe(
-                       submitButton,
-                       'click',
-                       TYPO3RsaBackendLogin.handleFormSubmitRequest
-               );
-       },
+               /**
+                * Field that is used by TYPO3 to evaluate the password during login process
+                */
+               typo3PasswordField: false,
 
-       /**
-        * Fetches a new public key by Ajax and encrypts the password for transmission
-        *
-        * @param event
-        */
-       handleFormSubmitRequest: function(event) {
-               event.preventDefault();
-               // Call the original event handler
-               TYPO3BackendLogin.showLoginProcess();
+               /**
+                * Replace event handler of submit button
+                */
+               initialize: function() {
+                       this.userPasswordField = BackendLogin.options.passwordField;
+                       this.typo3PasswordField = BackendLogin.options.useridentField;
 
-               Ext.Ajax.request({
-                       url: TYPO3.settings.ajaxUrls['BackendLogin::getRsaPublicKey'],
-                       params: {
-                               'skipSessionUpdate': 1
-                       },
-                       method: 'GET',
-                       success: TYPO3RsaBackendLogin.handlePublicKeyResponse
-               });
-       },
+                       $(document).off('click', BackendLogin.options.submitButton, BackendLogin.showLoginProcess);
+                       $(document).on('click', BackendLogin.options.submitButton, this.handleFormSubmitRequest);
+                       return this;
+               },
 
-       /**
-        * Parses the Json response and triggers submission of the form
-        *
-        * @param response Ajax response object
-        */
-       handlePublicKeyResponse: function(response) {
-               var publicKey = Ext.util.JSON.decode(response.responseText);
-               if (publicKey.publicKeyModulus && publicKey.exponent) {
-                       TYPO3RsaBackendLogin.encryptPasswordAndSubmitForm(publicKey);
-               } else {
-                       alert('No public key could be generated. Please inform your TYPO3 administrator to check the OpenSSL settings.');
-               }
-       },
+               /**
+                * Fetches a new public key by Ajax and encrypts the password for transmission
+                *
+                * @param event
+                */
+               handleFormSubmitRequest: function(event) {
+                       event.preventDefault();
+
+                       BackendLogin.showLoginProcess();
 
-       /**
-        * Uses the public key with the RSA library to encrypt the password.
-        *
-        * @param publicKey
-        */
-       encryptPasswordAndSubmitForm: function(publicKey) {
-               var form, rsa, inputField;
+                       $.ajax({
+                               url: TYPO3.settings.ajaxUrls['BackendLogin::getRsaPublicKey'],
+                               data: {'skipSessionUpdate': 1},
+                               success: RsaBackendLogin.handlePublicKeyResponse,
+                               dataType: 'json'
+                       });
+               },
 
-               rsa = new RSAKey();
-               rsa.setPublic(publicKey.publicKeyModulus, publicKey.exponent);
-               var encryptedPassword = rsa.encrypt(TYPO3RsaBackendLogin.userPasswordField.value);
+               /**
+                * Parses the Json response and triggers submission of the form
+                *
+                * @param publicKey Ajax response object
+                */
+               handlePublicKeyResponse: function(publicKey) {
+                       if (publicKey.publicKeyModulus && publicKey.exponent) {
+                               RsaBackendLogin.encryptPasswordAndSubmitForm(publicKey);
+                       } else {
+                               alert('No public key could be generated. Please inform your TYPO3 administrator to check the OpenSSL settings.');
+                       }
+               },
 
-               // Reset user password field to prevent it from being submitted
-               TYPO3RsaBackendLogin.userPasswordField.value = '';
-               TYPO3RsaBackendLogin.typo3PasswordField.value = 'rsa:' + hex2b64(encryptedPassword);
+               /**
+                * Uses the public key with the RSA library to encrypt the password.
+                *
+                * @param publicKey
+                */
+               encryptPasswordAndSubmitForm: function(publicKey) {
+                       var rsa = new RSAKey();
+                       rsa.setPublic(publicKey.publicKeyModulus, publicKey.exponent);
+                       var encryptedPassword = rsa.encrypt($(RsaBackendLogin.userPasswordField).val());
 
-               // Create a hidden input field to fake pressing the submit button
-               inputField = TYPO3RsaBackendLogin.getHiddenField('commandLI', 'Submit');
-               form = $('typo3-login-form');
-               form.appendChild(inputField);
+                       // Reset user password field to prevent it from being submitted
+                       $(RsaBackendLogin.userPasswordField).val('');
+                       $(RsaBackendLogin.typo3PasswordField).val('rsa:' + hex2b64(encryptedPassword));
 
-               // Submit the form
-               form.submit();
-       },
+                       var $formElement = $('form:first');
 
-       /**
-        * Creates a new hidden field DOM element
-        *
-        * @param name Name attribute of the field
-        * @param value Value attribute of the field
-        * @returns {HTMLElement}
-        */
-       getHiddenField: function(name, value) {
-               var input = document.createElement("input");
-               input.setAttribute("type", "hidden");
-               input.setAttribute("name", name);
-               input.setAttribute("value", value);
-               return input;
-       }
-};
+                       // Create a hidden input field to fake pressing the submit button
+                       $formElement.append('<input type="hidden" name="commandLI" value="Submit">');
 
-Ext.onReady(TYPO3RsaBackendLogin.initialize, TYPO3RsaBackendLogin);
+                       // Submit the form
+                       $formElement.trigger('submit');
+               }
+       };
+       RsaBackendLogin.initialize();
+});
index ce116b7..936ad85 100644 (file)
@@ -58,9 +58,9 @@
 }
 
 #typo3-index-php .t3-login-field .t3-login-alert-capslock {
-       left: 307px;
+       left: 300px;
        position: absolute;
-       top: 2px;
+       top: 5px;
 }
 
 #typo3-index-php .t3-login-field input {