Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/matomo-org/matomo.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbenakamoorthi <benaka.moorthi@gmail.com>2012-09-02 15:14:40 +0400
committerbenakamoorthi <benaka.moorthi@gmail.com>2012-09-02 15:14:40 +0400
commit8e7cc3c95530187f39dc9edbe45cf2a26aa435e8 (patch)
tree1874dd52df5c7974b36e64fd6a7a22b875f09692 /plugins/Login
parentaeaf2ab3471d24a5a074dd523ab30a12060991e8 (diff)
Fixes #3334, redesigned the reset password functionality.
Notes: * Resetting password is done through AJAX and the reset token does not need to be entered in a form. * Moved password related utility functions in UsersManager_API to UsersManager as static functions. * Added hidden _isPasswordHashed parameter to UsersManager::updateUser. * Make sure superuser login is set in Access instance when setSuperUser(true) is used. * Add ability to get rendered form data as array in QuickForm2 (moved existing logic in Piwik_View into new function). git-svn-id: http://dev.piwik.org/svn/trunk@6900 59fd770c-687e-43c8-a1e3-f5a4ff64c105
Diffstat (limited to 'plugins/Login')
-rw-r--r--plugins/Login/Controller.php292
-rw-r--r--plugins/Login/FormPassword.php33
-rw-r--r--plugins/Login/FormResetPassword.php13
-rw-r--r--plugins/Login/Login.php52
-rw-r--r--plugins/Login/templates/header.tpl1
-rw-r--r--plugins/Login/templates/login.css19
-rwxr-xr-xplugins/Login/templates/login.js107
-rw-r--r--plugins/Login/templates/login.tpl78
-rw-r--r--plugins/Login/templates/lostPassword.tpl39
-rwxr-xr-xplugins/Login/templates/message.tpl11
-rw-r--r--plugins/Login/templates/passwordchanged.tpl21
-rw-r--r--plugins/Login/templates/passwordsent.tpl22
-rw-r--r--plugins/Login/templates/resetPassword.tpl51
13 files changed, 406 insertions, 333 deletions
diff --git a/plugins/Login/Controller.php b/plugins/Login/Controller.php
index d33bc4e451..d706538d74 100644
--- a/plugins/Login/Controller.php
+++ b/plugins/Login/Controller.php
@@ -53,7 +53,7 @@ class Piwik_Login_Controller extends Piwik_Controller
* @param string $currentUrl Current URL
* @return void
*/
- function login($messageNoAccess = null)
+ function login($messageNoAccess = null, $infoMessage = false)
{
self::checkForceSslLogin();
@@ -81,6 +81,7 @@ class Piwik_Login_Controller extends Piwik_Controller
$view = Piwik_View::factory('login');
$view->AccessErrorString = $messageNoAccess;
+ $view->infoMessage = $infoMessage;
$view->addForm( $form );
$this->configureView($view);
echo $view->render();
@@ -158,68 +159,118 @@ class Piwik_Login_Controller extends Piwik_Controller
Piwik_Url::redirectToUrl($urlToRedirect);
}
+ protected function getMessageExceptionNoAccess()
+ {
+ $message = Piwik_Translate('Login_InvalidNonceOrHeadersOrReferer', array('<a href="?module=Proxy&action=redirect&url='.urlencode('http://piwik.org/faq/how-to-install/#faq_98').'" target="_blank">', '</a>'));
+ // Should mention trusted_hosts or link to FAQ
+ return $message;
+ }
+
/**
- * Lost password form. Email password reset information.
+ * Reset password action. Stores new password as hash and sends email
+ * to confirm use.
*
* @param none
* @return void
*/
- function lostPassword()
+ function resetPassword()
{
self::checkForceSslLogin();
- $messageNoAccess = null;
+ $infoMessage = null;
+ $formErrors = null;
- $form = new Piwik_Login_FormPassword();
+ $form = new Piwik_Login_FormResetPassword();
if($form->validate())
{
$nonce = $form->getSubmitValue('form_nonce');
if(Piwik_Nonce::verifyNonce('Piwik_Login.login', $nonce))
{
- $loginMail = $form->getSubmitValue('form_login');
- $messageNoAccess = $this->lostPasswordFormValidated($loginMail);
+ $formErrors = $this->resetPasswordFirstStep($form);
+ if (empty($formErrors))
+ {
+ $infoMessage = Piwik_Translate('Login_ConfirmationLinkSent');
+ }
}
else
{
- $messageNoAccess = $this->getMessageExceptionNoAccess();
+ $formErrors = array($this->getMessageExceptionNoAccess());
}
}
-
- $view = Piwik_View::factory('lostPassword');
- $view->AccessErrorString = $messageNoAccess;
- $view->addForm( $form );
- $this->configureView($view);
+ else
+ {
+ // if invalid, display error
+ $formData = $form->getFormData();
+ $formErrors = $formData['errors'];
+ }
+
+ $view = Piwik_View::factory('message');
+ $view->infoMessage = $infoMessage;
+ $view->formErrors = $formErrors;
echo $view->render();
}
-
- protected function getMessageExceptionNoAccess()
- {
- $message = Piwik_Translate('Login_InvalidNonceOrHeadersOrReferer', array('<a href="?module=Proxy&action=redirect&url='.urlencode('http://piwik.org/faq/how-to-install/#faq_98').'" target="_blank">', '</a>'));
- // Should mention trusted_hosts or link to FAQ
- return $message;
- }
-
+
/**
- * Validate user (by username or email address).
- *
- * @param string $loginMail user name or email address
- * @return string failure message if unable to validate
+ * Saves password reset info and sends confirmation email.
+ *
+ * @return array Error message(s) if an error occurs.
*/
- protected function lostPasswordFormValidated($loginMail)
+ private function resetPasswordFirstStep( $form )
{
- if( $loginMail === 'anonymous' )
+ $loginMail = $form->getSubmitValue('form_login');
+ $token = $form->getSubmitValue('form_token');
+ $password = $form->getSubmitValue('form_password');
+
+ // check the password
+ try
+ {
+ Piwik_UsersManager::checkPassword($password);
+ }
+ catch (Exception $ex)
{
- return Piwik_Translate('Login_InvalidUsernameEmail');
+ return array($ex->getMessage());
+ }
+
+ // get the user's login
+ if ($loginMail === 'anonymous')
+ {
+ return array(Piwik_Translate('Login_InvalidUsernameEmail'));
}
$user = self::getUserInformation($loginMail);
- if( $user === null )
+ if ($user === null)
{
- return Piwik_Translate('Login_InvalidUsernameEmail');
+ return array(Piwik_Translate('Login_InvalidUsernameEmail'));
}
-
- $view = Piwik_View::factory('passwordsent');
-
+
+ $login = $user['login'];
+
+ // if valid, store password information in options table, then...
+ Piwik_Login::savePasswordResetInfo($login, $password);
+
+ // ... send email with confirmation link
+ try
+ {
+ $this->sendEmailConfirmationLink($user);
+ }
+ catch (Exception $ex)
+ {
+ // remove password reset info
+ Piwik_Login::removePasswordResetInfo($login);
+
+ return array($ex->getMessage().'<br/>'.Piwik_Translate('Login_ContactAdmin'));
+ }
+
+ return null;
+ }
+
+ /**
+ * Sends email confirmation link for a password reset request.
+ *
+ * @param array $user User info for the requested password reset.
+ */
+ private function sendEmailConfirmationLink( $user )
+ {
$login = $user['login'];
$email = $user['email'];
@@ -227,122 +278,113 @@ class Piwik_Login_Controller extends Piwik_Controller
$resetToken = self::generatePasswordResetToken($user);
$ip = Piwik_IP::getIpFromHeader();
- $url = Piwik_Url::getCurrentUrlWithoutQueryString() . "?module=Login&action=resetPassword";
+ $url = Piwik_Url::getCurrentUrlWithoutQueryString()
+ . "?module=Login&action=confirmResetPassword&login=".urlencode($login)
+ . "&resetToken=".urlencode($resetToken);
// send email with new password
- try
- {
- $mail = new Piwik_Mail();
- $mail->addTo($email, $login);
- $mail->setSubject(Piwik_Translate('Login_MailTopicPasswordRecovery'));
- $bodyText = str_replace(
- '\n',
- "\n",
- sprintf(Piwik_Translate('Login_MailPasswordRecoveryBody'), $login, $ip, $url, $resetToken)
- ) . "\n";
- $mail->setBodyText($bodyText);
-
-
- $fromEmailName = Piwik_Config::getInstance()->General['login_password_recovery_email_name'];
- $fromEmailAddress = Piwik_Config::getInstance()->General['login_password_recovery_email_address'];
- $mail->setFrom($fromEmailAddress, $fromEmailName);
- @$mail->send();
- }
- catch(Exception $e)
- {
- $view->ErrorString = $e->getMessage();
- }
- $this->configureView($view);
- echo $view->render();
- exit;
+ $mail = new Piwik_Mail();
+ $mail->addTo($email, $login);
+ $mail->setSubject(Piwik_Translate('Login_MailTopicPasswordChange'));
+ $bodyText = str_replace(
+ '\n',
+ "\n",
+ sprintf(Piwik_Translate('Login_MailPasswordChangeBody'), $login, $ip, $url)
+ ) . "\n";
+ $mail->setBodyText($bodyText);
+
+ $fromEmailName = Piwik_Config::getInstance()->General['login_password_recovery_email_name'];
+ $fromEmailAddress = Piwik_Config::getInstance()->General['login_password_recovery_email_address'];
+ $mail->setFrom($fromEmailAddress, $fromEmailName);
+ @$mail->send();
}
-
+
/**
- * Reset password form. Enter new password here.
- *
- * @param none
- * @return void
+ * Password reset confirmation action. Finishes the password reset process.
+ * Users visit this action from a link supplied in an email.
*/
- function resetPassword()
+ public function confirmResetPassword()
{
- self::checkForceSslLogin();
-
- $messageNoAccess = null;
-
- $form = new Piwik_Login_FormResetPassword();
- if($form->validate())
+ $errorMessage = null;
+
+ $login = Piwik_Common::getRequestVar('login', '');
+ $resetToken = Piwik_Common::getRequestVar('resetToken', '');
+
+ try
{
- $nonce = $form->getSubmitValue('form_nonce');
- if(Piwik_Nonce::verifyNonce('Piwik_Login.login', $nonce))
+ // get password reset info & user info
+ $user = self::getUserInformation($login);
+ if ($user === null)
{
- $loginMail = $form->getSubmitValue('form_login');
- $token = $form->getSubmitValue('form_token');
- $password = $form->getSubmitValue('form_password');
- $messageNoAccess = $this->resetPasswordFormValidated($loginMail, $token, $password);
+ throw new Exception(Piwik_Translate('Login_InvalidUsernameEmail'));
}
- else
+
+ // check that the reset token is valid
+ $resetPassword = Piwik_Login::getPasswordToResetTo($login);
+ if ($resetPassword === false || !self::isValidToken($resetToken, $user))
{
- $messageNoAccess = $this->getMessageExceptionNoAccess();
+ throw new Exception(Piwik_Translate('Login_InvalidOrExpiredToken'));
}
+
+ // reset password of user
+ $this->setNewUserPassword($user, $resetPassword);
+ }
+ catch (Exception $ex)
+ {
+ $errorMessage = $ex->getMessage();
+ }
+
+ if (is_null($errorMessage)) // if success, show login w/ success message
+ {
+ $this->redirectToIndex('Login', 'resetPasswordSuccess');
+ }
+ else
+ {
+ // show login page w/ error. this will keep the token in the URL
+ return $this->login($errorMessage);
}
-
- $view = Piwik_View::factory('resetPassword');
- $view->AccessErrorString = $messageNoAccess;
- $view->forceSslLogin = Piwik_Config::getInstance()->General['force_ssl_login'];
- $view->addForm( $form );
- $this->configureView($view);
- echo $view->render();
}
-
+
/**
- * Validate password reset request. If successful, set new password and redirect.
- *
- * @param string $loginMail user name or email address
- * @param string $token password reset token
- * @param string $password new password
- * @throws Exception
- * @return string failure message
+ * Sets the password for a user.
+ *
+ * @param array $user User info.
+ * @param string $passwordHash The hashed password to use.
*/
- protected function resetPasswordFormValidated($loginMail, $token, $password)
+ private function setNewUserPassword( $user, $passwordHash )
{
- $user = self::getUserInformation($loginMail);
- if( $user === null )
+ if (strlen($passwordHash) !== 32) // sanity check
{
- return Piwik_Translate('Login_InvalidUsernameEmail');
+ throw new Exception(
+ "setNewUserPassword called w/ incorrect password hash. Something has gone terribly wrong.");
}
-
- if(!self::isValidToken($token, $user))
+
+ if( $user['email'] == Piwik::getSuperUserEmail() )
{
- return Piwik_Translate('Login_InvalidOrExpiredToken');
- }
-
- $view = Piwik_View::factory('passwordchanged');
- try
- {
- if( $user['email'] == Piwik::getSuperUserEmail() )
+ if(!Piwik_Config::getInstance()->isFileWritable())
{
- if(!Piwik_Config::getInstance()->isFileWritable())
- {
- throw new Exception(Piwik_Translate('General_ConfigFileIsNotWritable', array("(config/config.ini.php)","<br/>")));
- }
-
- $user['password'] = md5($password);
- Piwik_Config::getInstance()->superuser = $user;
- Piwik_Config::getInstance()->forceSave();
- }
- else
- {
- Piwik_UsersManager_API::getInstance()->updateUser($user['login'], $password);
+ throw new Exception(Piwik_Translate('General_ConfigFileIsNotWritable', array("(config/config.ini.php)","<br/>")));
}
+
+ $user['password'] = $passwordHash;
+ Piwik_Config::getInstance()->superuser = $user;
+ Piwik_Config::getInstance()->forceSave();
}
- catch(Exception $e)
+ else
{
- $view->ErrorString = $e->getMessage();
+ Piwik_UsersManager_API::getInstance()->updateUser(
+ $user['login'], $passwordHash, $email = false, $alias = false, $isPasswordHashed = true);
}
-
- $this->configureView($view);
- echo $view->render();
- exit;
+ }
+
+ /**
+ * The action used after a password is successfully reset. Displays the login
+ * screen with an extra message. A separate action is used instead of returning
+ * the HTML in confirmResetPassword so the resetToken won't be in the URL.
+ */
+ public function resetPasswordSuccess()
+ {
+ return $this->login($errorMessage = null, $infoMessage = Piwik_Translate('Login_PasswordChanged'));
}
/**
diff --git a/plugins/Login/FormPassword.php b/plugins/Login/FormPassword.php
deleted file mode 100644
index 095b0c8d4b..0000000000
--- a/plugins/Login/FormPassword.php
+++ /dev/null
@@ -1,33 +0,0 @@
-<?php
-/**
- * Piwik - Open source web analytics
- *
- * @link http://piwik.org
- * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
- * @version $Id$
- *
- * @category Piwik_Plugins
- * @package Piwik_Login
- */
-
-/**
- *
- * @package Piwik_Login
- */
-class Piwik_Login_FormPassword extends Piwik_QuickForm2
-{
- function __construct( $id = 'lostpasswordform', $method = 'post', $attributes = null, $trackSubmit = false)
- {
- parent::__construct($id, $method, $attributes, $trackSubmit);
- }
-
- function init()
- {
- $this->addElement('text', 'form_login')
- ->addRule('required', Piwik_Translate('General_Required', Piwik_Translate('Login_LoginOrEmail')));
-
- $this->addElement('hidden', 'form_nonce');
-
- $this->addElement('submit', 'submit');
- }
-}
diff --git a/plugins/Login/FormResetPassword.php b/plugins/Login/FormResetPassword.php
index 49d63cf7a4..fb050ba274 100644
--- a/plugins/Login/FormResetPassword.php
+++ b/plugins/Login/FormResetPassword.php
@@ -33,21 +33,8 @@ class Piwik_Login_FormResetPassword extends Piwik_QuickForm2
$passwordBis->addRule('required', Piwik_Translate('General_Required', Piwik_Translate('Login_PasswordRepeat')));
$passwordBis->addRule('eq', Piwik_Translate( 'Login_PasswordsDoNotMatch'), $password);
- $this->addElement('text', 'form_token')
- ->addRule('required', Piwik_Translate('General_Required', Piwik_Translate('Login_PasswordResetToken')));
-
$this->addElement('hidden', 'form_nonce');
$this->addElement('submit', 'submit');
-
- $resetToken = Piwik_Common::getRequestVar('token', '', 'string');
- if(!empty($resetToken)) {
- // default values
- $this->addDataSource(new HTML_QuickForm2_DataSource_Array(array(
- 'form_token' => $resetToken,
- )));
-
- $this->attributes['action'] = 'index.php' . Piwik_Url::getCurrentQueryStringWithParametersModified( array('token' => null) );
- }
}
}
diff --git a/plugins/Login/Login.php b/plugins/Login/Login.php
index 7c8bcbe994..0925045fda 100644
--- a/plugins/Login/Login.php
+++ b/plugins/Login/Login.php
@@ -138,5 +138,57 @@ class Piwik_Login extends Piwik_Plugin
$cookie->save();
@Piwik_Session::regenerateId();
+
+ // remove password reset entry if it exists
+ self::removePasswordResetInfo($login);
+ }
+
+ /**
+ * Stores password reset info for a specific login.
+ *
+ * @param string $login The user login for whom a password change was requested.
+ * @param string $password The new password to set.
+ */
+ public static function savePasswordResetInfo( $login, $password )
+ {
+ $optionName = self::getPasswordResetInfoOptionName($login);
+ $optionData = Piwik_UsersManager::getPasswordHash($password);
+
+ Piwik_SetOption($optionName, $optionData);
+ }
+
+ /**
+ * Removes stored password reset info if it exists.
+ *
+ * @param string $login The user login to check for.
+ */
+ public static function removePasswordResetInfo( $login )
+ {
+ $optionName = self::getPasswordResetInfoOptionName($login);
+ Piwik_Option::getInstance()->delete($optionName);
+ }
+
+ /**
+ * Gets password hash stored in password reset info.
+ *
+ * @param string $login The user login to check for.
+ * @return string|false The hashed password or false if no reset info exists.
+ */
+ public static function getPasswordToResetTo( $login )
+ {
+ $optionName = self::getPasswordResetInfoOptionName($login);
+ return Piwik_GetOption($optionName);
+ }
+
+ /**
+ * Gets the option name for the option that will store a user's password change
+ * request.
+ *
+ * @param string $login The user login for whom a password change was requested.
+ * @return string
+ */
+ public static function getPasswordResetInfoOptionName( $login )
+ {
+ return $login.'_reset_password_info';
}
}
diff --git a/plugins/Login/templates/header.tpl b/plugins/Login/templates/header.tpl
index 3cd9011b46..1fbb563c67 100644
--- a/plugins/Login/templates/header.tpl
+++ b/plugins/Login/templates/header.tpl
@@ -34,6 +34,7 @@
</script>
{/literal}
<script type="text/javascript" src="libs/jquery/jquery.js"></script>
+ <script type="text/javascript" src="plugins/Login/templates/login.js"></script>
{if 'General_LayoutDirection'|translate =='rtl'}
<link rel="stylesheet" type="text/css" href="themes/default/rtl.css" />
{/if}
diff --git a/plugins/Login/templates/login.css b/plugins/Login/templates/login.css
index 7a80a3733c..6f7454812e 100644
--- a/plugins/Login/templates/login.css
+++ b/plugins/Login/templates/login.css
@@ -24,7 +24,7 @@ form .forgetmenot {
margin-bottom: 0;
}
-#login form .submit input {
+#login form input.submit {
font-family: "Lucida Grande", "Lucida Sans Unicode", Tahoma, Verdana,
sans-serif;
padding: 3px 5px;
@@ -67,7 +67,8 @@ form p {
padding: 16px;
}
-#form_password,#form_password_bis,#form_login,#user_email,#form_token {
+#login_form_password,#reset_form_password,#reset_form_password_bis,
+#login_form_login,#reset_form_login {
font-size: 20px;
width: 97%;
padding: 3px;
@@ -82,7 +83,7 @@ form p {
background-color: #eaf3fa;
}
-#login form .submit input {
+#login form input.submit {
background-color: #cee1ef !important;
}
@@ -91,17 +92,14 @@ form p {
border-color: #c00;
}
-#login form .submit input {
+#login form input.submit {
background-color: #e5e5e5;
color: #246;
border-color: #80b5d0;
}
-#login form .submit input:hover {
+#login form input.submit:hover {
color: #d54e21;
-}
-
-#login form .submit input:hover {
border-color: #328ab2;
}
@@ -156,3 +154,8 @@ a {
margin-left:50px;
margin-bottom:30px;
}
+
+.loadingPiwik {
+ float: left;
+ margin-left: 16px;
+}
diff --git a/plugins/Login/templates/login.js b/plugins/Login/templates/login.js
new file mode 100755
index 0000000000..28171b47ab
--- /dev/null
+++ b/plugins/Login/templates/login.js
@@ -0,0 +1,107 @@
+/*!
+ * Piwik - Web Analytics
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ */
+(function($) {
+
+$(document).ready(function() {
+ var switchForm = function(fromFormId, toFormId, message, callback) {
+ var fromLoginInputId = '#'+fromFormId+'_login',
+ toLoginInputId = '#'+toFormId+'_login',
+ toPasswordInputId = '#'+toFormId+'_password',
+ fromLoginNavId = '#'+fromFormId+'_nav',
+ toLoginNavId = '#'+toFormId+'_nav';
+
+ if ($(toLoginInputId).val() === '')
+ {
+ $(toLoginInputId).val($(fromLoginInputId).val());
+ }
+
+ // hide the bottom portion of the login screen & show the password reset bits
+ $('#'+fromFormId+',#message_container').fadeOut(500, function() {
+ // show lost password instructions
+ $('#message_container').html(message);
+
+ $(fromLoginNavId).hide();
+ $(toLoginNavId).show();
+ $('#'+toFormId+',#message_container').fadeIn(500, function() {
+ // focus on login or password control based on whether a login exists
+ if ($(toLoginInputId).val() === '')
+ {
+ $(toLoginInputId).focus();
+ }
+ else
+ {
+ $(toPasswordInputId).focus();
+ }
+
+ if (callback)
+ {
+ callback();
+ }
+ });
+ });
+ };
+
+ // 'lost your password?' on click
+ $('#login_form_nav').click(function(e) {
+ e.preventDefault();
+ switchForm('login_form', 'reset_form', $('#lost_password_instructions').html());
+ return false;
+ });
+
+ // 'cancel' on click
+ $('#reset_form_nav,#alternate_reset_nav').click(function(e) {
+ e.preventDefault();
+ $('#alternate_reset_nav').hide();
+ switchForm('reset_form', 'login_form', '');
+ return false;
+ });
+
+ // password reset on submit
+ $('#reset_form_submit').click(function(e) {
+ e.preventDefault();
+
+ var ajaxDone = function(response)
+ {
+ $('.loadingPiwik').hide();
+
+ var isSuccess = response.indexOf('id="login_error"') === -1,
+ fadeOutIds = '#message_container';
+ if (isSuccess)
+ {
+ fadeOutIds += ',#reset_form,#reset_form_nav';
+ }
+
+ $(fadeOutIds).fadeOut(300, function() {
+ if (isSuccess)
+ {
+ $('#alternate_reset_nav').show();
+ }
+
+ $('#message_container').html(response).fadeIn(300);
+ });
+ };
+
+ $('.loadingPiwik').show();
+
+ // perform reset password request
+ $.ajax({
+ type: 'POST',
+ url: 'index.php',
+ dataType: 'html',
+ async: true,
+ error: function() { ajaxDone('<div id="login_error"><strong>HTTP Error</strong></div>'); },
+ success: ajaxDone, // Callback when the request succeeds
+ data: $('#reset_form').serialize()
+ });
+
+ return false;
+ });
+
+ $('#login_form_login').focus();
+});
+
+}(jQuery));
diff --git a/plugins/Login/templates/login.tpl b/plugins/Login/templates/login.tpl
index fb0b93e58b..cdcef19db3 100644
--- a/plugins/Login/templates/login.tpl
+++ b/plugins/Login/templates/login.tpl
@@ -2,39 +2,74 @@
<div id="login">
-{if $form_data.errors}
-<div id="login_error">
- {foreach from=$form_data.errors item=data}
- <strong>{'General_Error'|translate}</strong>: {$data}<br />
- {/foreach}
-</div>
-{/if}
+<div id="message_container">
+ {if $form_data.errors}
+ <div id="login_error">
+ {foreach from=$form_data.errors item=data}
+ <strong>{'General_Error'|translate}</strong>: {$data}<br />
+ {/foreach}
+ </div>
+ {/if}
-{if $AccessErrorString}
-<div id="login_error"><strong>{'General_Error'|translate}</strong>: {$AccessErrorString}<br /></div>
-{/if}
+ {if $AccessErrorString}
+ <div id="login_error"><strong>{'General_Error'|translate}</strong>: {$AccessErrorString}<br /></div>
+ {/if}
-<form {$form_data.attributes}>
+ {if $infoMessage}
+ <p class="message">{$infoMessage}</p>
+ {/if}
+</div>
+
+<form id="login_form" {$form_data.attributes}>
<p>
- <label>{'General_Username'|translate}:<br />
- <input type="text" name="form_login" id="form_login" class="input" value="" size="20" tabindex="10" />
- <input type="hidden" name="form_nonce" id="form_nonce" value="{$nonce}" /></label>
+ <label>{'General_Username'|translate}:<br/>
+ <input type="text" name="form_login" id="login_form_login" class="input" value="" size="20" tabindex="10" />
+ <input type="hidden" name="form_nonce" id="login_form_nonce" value="{$nonce}" /></label>
</p>
<p>
<label>{'Login_Password'|translate}:<br />
- <input type="password" name="form_password" id="form_password" class="input" value="" size="20" tabindex="20" /></label>
+ <input type="password" name="form_password" id="login_form_password" class="input" value="" size="20" tabindex="20" /></label>
</p>
+
<p class="forgetmenot">
- <label><input name="form_rememberme" type="checkbox" id="form_rememberme" value="1" tabindex="90" {if $form_data.form_rememberme.value}checked="checked" {/if}/> {'Login_RememberMe'|translate} </label>
+ <label><input name="form_rememberme" type="checkbox" id="login_form_rememberme" value="1" tabindex="90" {if $form_data.form_rememberme.value}checked="checked" {/if}/> {'Login_RememberMe'|translate} </label>
</p>
- <p class="submit">
- <input type="submit" value="{'Login_LogIn'|translate}" tabindex="100" />
+ <p>
+ <input class="submit" id='login_form_submit' type="submit" value="{'Login_LogIn'|translate}" tabindex="100" />
</p>
</form>
+<form id="reset_form" style="display:none;">
+ <p>
+ <label>{'Login_LoginOrEmail'|translate}:<br />
+ <input type="text" name="form_login" id="reset_form_login" class="input" value="" size="20" tabindex="10" />
+ <input type="hidden" name="form_nonce" id="reset_form_nonce" value="{$nonce}" /></label>
+ </p>
+
+ <p>
+ <label>{'Login_Password'|translate}:<br />
+ <input type="password" name="form_password" id="reset_form_password" class="input" value="" size="20" tabindex="20" /></label>
+ </p>
+
+ <p>
+ <label>{'Login_PasswordRepeat'|translate}:<br />
+ <input type="password" name="form_password_bis" id="reset_form_password_bis" class="input" value="" size="20" tabindex="30" /></label>
+ </p>
+
+ <p>
+ <span class="loadingPiwik" style="display:none;"><img src="themes/default/images/loading-blue.gif" /></span>
+ <input class="submit" id='reset_form_submit' type="submit" value="{'Login_ChangePassword'|translate}" tabindex="100"/>
+ </p>
+
+ <input type="hidden" name="module" value="Login"/>
+ <input type="hidden" name="action" value="resetPassword"/>
+</form>
+
<p id="nav">
-<a href="index.php?module=Login&amp;action=lostPassword" title="{'Login_LostYourPassword'|translate}">{'Login_LostYourPassword'|translate}</a>
+<a id="login_form_nav" href="#" title="{'Login_LostYourPassword'|translate}">{'Login_LostYourPassword'|translate}</a>
+<a id="reset_form_nav" href="#" style="display:none;" title="{'Mobile_NavigationBack'|translate}">{'General_Cancel'|translate}</a>
+<a id="alternate_reset_nav" href="#" style="display:none;" title="{'Login_LogIn'|translate}">{'Login_LogIn'|translate}</a>
</p>
{if isset($smarty.capture.poweredByPiwik)}
<p id="piwik">
@@ -42,9 +77,10 @@
</p>
{/if}
-
+<div id="lost_password_instructions" style="display:none;">
+ <p class="message">{'Login_ResetPasswordInstructions'|translate}</p>
</div>
-
+</div>
</body>
</html>
diff --git a/plugins/Login/templates/lostPassword.tpl b/plugins/Login/templates/lostPassword.tpl
deleted file mode 100644
index 3898e5034a..0000000000
--- a/plugins/Login/templates/lostPassword.tpl
+++ /dev/null
@@ -1,39 +0,0 @@
-{include file="Login/templates/header.tpl"}
-
-<div id="login">
-
-{if $form_data.errors}
-<div id="login_error">
- {foreach from=$form_data.errors item=data}
- <strong>{'General_Error'|translate}</strong>: {$data}<br />
- {/foreach}
-</div>
-{/if}
-
-{if $AccessErrorString}
-<div id="login_error"><strong>{'General_Error'|translate}</strong>: {$AccessErrorString}<br /></div>
-{/if}
-
-<p class="message">
-{'Login_PasswordReminder'|translate}
-</p>
-
-<form {$form_data.attributes}>
- <p>
- <label>{'Login_LoginOrEmail'|translate}:<br />
- <input type="text" name="form_login" id="form_login" class="input" value="" size="20" tabindex="10" /></label>
- <input type="hidden" name="form_nonce" id="form_nonce" value="{$nonce}" /></label>
- </p>
- <p class="submit">
- <input type="submit" value="{'Login_RemindPassword'|translate}" tabindex="100" />
- </p>
-</form>
-
-<p id="nav">
-<a href="index.php?module=Login" title="{'Login_LogIn'|translate}">{'Login_LogIn'|translate}</a>
-</p>
-
-</div>
-
-</body>
-</html>
diff --git a/plugins/Login/templates/message.tpl b/plugins/Login/templates/message.tpl
new file mode 100755
index 0000000000..7b85147d8f
--- /dev/null
+++ b/plugins/Login/templates/message.tpl
@@ -0,0 +1,11 @@
+{if isset($infoMessage)}
+<p class="message">{$infoMessage}</p>
+{/if}
+{if isset($formErrors)}
+<p id="login_error">
+ {foreach from=$formErrors item=data}
+ <strong>{'General_Error'|translate}</strong>: {$data}<br />
+ {/foreach}
+</p>
+{/if}
+
diff --git a/plugins/Login/templates/passwordchanged.tpl b/plugins/Login/templates/passwordchanged.tpl
deleted file mode 100644
index bc55d94f15..0000000000
--- a/plugins/Login/templates/passwordchanged.tpl
+++ /dev/null
@@ -1,21 +0,0 @@
-{include file="Login/templates/header.tpl"}
-
-<div id="login">
-
-{if isset($ErrorString)}
- <div id="login_error"><strong>{'General_Error'|translate}</strong>: {$ErrorString}<br />
- </div>
-{else}
- <p class="message">
- {'Login_PasswordSuccessfullyChanged'|translate}
- </p>
-{/if}
-
-<p id="nav">
-<a href="index.php?module=Login" title="{'Login_LogIn'|translate}">{'Login_LogIn'|translate}</a>
-</p>
-
-</div>
-
-</body>
-</html>
diff --git a/plugins/Login/templates/passwordsent.tpl b/plugins/Login/templates/passwordsent.tpl
deleted file mode 100644
index 7529c57f24..0000000000
--- a/plugins/Login/templates/passwordsent.tpl
+++ /dev/null
@@ -1,22 +0,0 @@
-{include file="Login/templates/header.tpl"}
-
-<div id="login">
-
-{if isset($ErrorString)}
- <div id="login_error"><strong>{'General_Error'|translate}</strong>: {$ErrorString}<br />
- {'Login_ContactAdmin'|translate}
- </div>
-{else}
- <p class="message">
- {'Login_PasswordSent'|translate}
- </p>
-{/if}
-
-<p id="nav">
-<a href="index.php?module=Login" title="{'Login_LogIn'|translate}">{'Login_LogIn'|translate}</a>
-</p>
-
-</div>
-
-</body>
-</html>
diff --git a/plugins/Login/templates/resetPassword.tpl b/plugins/Login/templates/resetPassword.tpl
deleted file mode 100644
index 36a3ff8aa5..0000000000
--- a/plugins/Login/templates/resetPassword.tpl
+++ /dev/null
@@ -1,51 +0,0 @@
-{include file="Login/templates/header.tpl"}
-
-<div id="login">
-
-{if $form_data.errors}
-<div id="login_error">
- {foreach from=$form_data.errors item=data}
- <strong>{'General_Error'|translate}</strong>: {$data}<br />
- {/foreach}
-</div>
-{/if}
-
-{if $AccessErrorString}
-<div id="login_error"><strong>{'General_Error'|translate}</strong>: {$AccessErrorString}<br /></div>
-{/if}
-
-<form {$form_data.attributes}>
- <p>
- <label>{'Login_LoginOrEmail'|translate}:<br />
- <input type="text" name="form_login" id="form_login" class="input" value="" size="20" tabindex="10" /></label>
- <input type="hidden" name="form_nonce" id="form_nonce" value="{$nonce}" /></label>
- </p>
-
- <p>
- <label>{'Login_Password'|translate}:<br />
- <input type="password" name="form_password" id="form_password" class="input" value="" size="20" tabindex="20" /></label>
- </p>
-
- <p>
- <label>{'Login_PasswordRepeat'|translate}:<br />
- <input type="password" name="form_password_bis" id="form_password_bis" class="input" value="" size="20" tabindex="30" /></label>
- </p>
-
- <p>
- <label>{'Login_PasswordResetToken'|translate}:<br />
- <input type="text" name="form_token" id="form_token" class="input" value="{$form_data.form_token.value}" size="20" tabindex="40" /></label>
- </p>
-
- <p class="submit">
- <input type="submit" value="{'Login_ChangePassword'|translate}" tabindex="100" />
- </p>
-</form>
-
-<p id="nav">
-<a href="index.php?module=Login&amp;action=lostPassword" title="{'Login_LostYourPassword'|translate}">{'Login_LostYourPassword'|translate}</a>
-</p>
-
-</div>
-
-</body>
-</html>