Login access code via email
This commit is contained in:
parent
fca3ff9ab0
commit
c4d8825151
|
@ -17,14 +17,14 @@ function editUser($args)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function setPassword($new, $confirm)
|
function setPassword($username, $new_password, $confirm_password)
|
||||||
{
|
{
|
||||||
global $dbUsers;
|
global $dbUsers;
|
||||||
global $Language;
|
global $Language;
|
||||||
|
|
||||||
if( ($new===$confirm) && !Text::isEmpty($new) )
|
if( ($new_password===$confirm_password) && !Text::isEmpty($new_password) )
|
||||||
{
|
{
|
||||||
if( $dbUsers->setPassword($new) ) {
|
if( $dbUsers->setPassword($username, $new_password) ) {
|
||||||
Alert::set($Language->g('The changes have been saved'));
|
Alert::set($Language->g('The changes have been saved'));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -93,7 +93,7 @@ if( $_SERVER['REQUEST_METHOD'] == 'POST' )
|
||||||
deleteUser($_POST, false);
|
deleteUser($_POST, false);
|
||||||
}
|
}
|
||||||
elseif( !empty($_POST['new-password']) && !empty($_POST['confirm-password']) ) {
|
elseif( !empty($_POST['new-password']) && !empty($_POST['confirm-password']) ) {
|
||||||
setPassword($_POST['new-password'], $_POST['confirm-password']);
|
setPassword($_POST['username'], $_POST['new-password'], $_POST['confirm-password']);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
editUser($_POST);
|
editUser($_POST);
|
||||||
|
|
|
@ -11,8 +11,67 @@
|
||||||
function checkPost($args)
|
function checkPost($args)
|
||||||
{
|
{
|
||||||
global $Security;
|
global $Security;
|
||||||
global $Login;
|
|
||||||
global $Language;
|
global $Language;
|
||||||
|
global $dbUsers;
|
||||||
|
global $Site;
|
||||||
|
|
||||||
|
if($Security->isBlocked()) {
|
||||||
|
Alert::set($Language->g('IP address has been blocked').'<br>'.$Language->g('Try again in a few minutes'));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove illegal characters from email
|
||||||
|
$email = Sanitize::email($args['email']);
|
||||||
|
|
||||||
|
if(Valid::email($email))
|
||||||
|
{
|
||||||
|
$user = $dbUsers->getByEmail($email);
|
||||||
|
if($user!=false)
|
||||||
|
{
|
||||||
|
// Generate the token and the token expiration date.
|
||||||
|
$token = $dbUsers->generateTokenEmail($user['username']);
|
||||||
|
|
||||||
|
// ---- EMAIL ----
|
||||||
|
$link = $Site->url().'admin/login-email?tokenEmail='.$token.'&username='.$user['username'];
|
||||||
|
$subject = $Language->g('BLUDIT Login access code');
|
||||||
|
$message = Text::replaceAssoc(
|
||||||
|
array(
|
||||||
|
'{{WEBSITE_NAME}}'=>$Site->title(),
|
||||||
|
'{{LINK}}'=>'<a href="'.$link.'">'.$link.'</a>'
|
||||||
|
),
|
||||||
|
$Language->g('email-notification-login-access-code')
|
||||||
|
);
|
||||||
|
|
||||||
|
$sent = Email::send(array(
|
||||||
|
'from'=>$Site->emailFrom(),
|
||||||
|
'to'=>$email,
|
||||||
|
'subject'=>$subject,
|
||||||
|
'message'=>$message
|
||||||
|
));
|
||||||
|
|
||||||
|
if($sent) {
|
||||||
|
Alert::set($Language->g('check-your-inbox-for-your-login-access-code'));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Alert::set($Language->g('There was a problem sending the email'));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bruteforce protection, add IP to blacklist.
|
||||||
|
$Security->addLoginFail();
|
||||||
|
Alert::set($Language->g('check-your-inbox-for-your-login-access-code'));
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkGet($args)
|
||||||
|
{
|
||||||
|
global $Security;
|
||||||
|
global $Language;
|
||||||
|
global $Login;
|
||||||
|
|
||||||
if($Security->isBlocked()) {
|
if($Security->isBlocked()) {
|
||||||
Alert::set($Language->g('IP address has been blocked').'<br>'.$Language->g('Try again in a few minutes'));
|
Alert::set($Language->g('IP address has been blocked').'<br>'.$Language->g('Try again in a few minutes'));
|
||||||
|
@ -20,9 +79,9 @@ function checkPost($args)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify User sanitize the input
|
// Verify User sanitize the input
|
||||||
if( $Login->verifyUser($_POST['username'], $_POST['password']) )
|
if( $Login->verifyUserByToken($args['username'], $args['tokenEmail']) )
|
||||||
{
|
{
|
||||||
// Renew the token. This token will be the same inside the session for multiple forms.
|
// Renew the tokenCRFS. This token will be the same inside the session for multiple forms.
|
||||||
$Security->generateToken();
|
$Security->generateToken();
|
||||||
|
|
||||||
Redirect::page('admin', 'dashboard');
|
Redirect::page('admin', 'dashboard');
|
||||||
|
@ -31,8 +90,6 @@ function checkPost($args)
|
||||||
|
|
||||||
// Bruteforce protection, add IP to blacklist.
|
// Bruteforce protection, add IP to blacklist.
|
||||||
$Security->addLoginFail();
|
$Security->addLoginFail();
|
||||||
Alert::set($Language->g('Username or password incorrect'));
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,6 +97,16 @@ function checkPost($args)
|
||||||
// Main before POST
|
// Main before POST
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// GET Method
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
if( !empty($_GET['tokenEmail']) && !empty($_GET['username']) )
|
||||||
|
{
|
||||||
|
checkGet($_GET);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// POST Method
|
// POST Method
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
|
@ -6,7 +6,7 @@ HTML::formOpen(array('class'=>'uk-form-horizontal'));
|
||||||
|
|
||||||
// Security token
|
// Security token
|
||||||
HTML::formInputHidden(array(
|
HTML::formInputHidden(array(
|
||||||
'name'=>'token',
|
'name'=>'tokenCSRF',
|
||||||
'value'=>$Security->getToken()
|
'value'=>$Security->getToken()
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ HTML::formOpen(array('id'=>'jsformplugin'));
|
||||||
|
|
||||||
// Security token
|
// Security token
|
||||||
HTML::formInputHidden(array(
|
HTML::formInputHidden(array(
|
||||||
'name'=>'token',
|
'name'=>'tokenCSRF',
|
||||||
'value'=>$Security->getToken()
|
'value'=>$Security->getToken()
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ HTML::formOpen(array('class'=>'uk-form-stacked'));
|
||||||
|
|
||||||
// Security token
|
// Security token
|
||||||
HTML::formInputHidden(array(
|
HTML::formInputHidden(array(
|
||||||
'name'=>'token',
|
'name'=>'tokenCSRF',
|
||||||
'value'=>$Security->getToken()
|
'value'=>$Security->getToken()
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ HTML::formOpen(array('class'=>'uk-form-stacked'));
|
||||||
|
|
||||||
// Security token
|
// Security token
|
||||||
HTML::formInputHidden(array(
|
HTML::formInputHidden(array(
|
||||||
'name'=>'token',
|
'name'=>'tokenCSRF',
|
||||||
'value'=>$Security->getToken()
|
'value'=>$Security->getToken()
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ HTML::formOpen(array('class'=>'uk-form-horizontal'));
|
||||||
|
|
||||||
// Security token
|
// Security token
|
||||||
HTML::formInputHidden(array(
|
HTML::formInputHidden(array(
|
||||||
'name'=>'token',
|
'name'=>'tokenCSRF',
|
||||||
'value'=>$Security->getToken()
|
'value'=>$Security->getToken()
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
<div class="login-form">
|
<div class="login-form">
|
||||||
|
|
||||||
<form method="post" action="<?php echo HTML_PATH_ADMIN_ROOT.'login' ?>" class="uk-form" autocomplete="off">
|
<form method="post" action="<?php echo HTML_PATH_ADMIN_ROOT.'login-email' ?>" class="uk-form" autocomplete="off">
|
||||||
|
|
||||||
<input type="hidden" id="jstoken" name="token" value="<?php $Security->printToken() ?>">
|
<input type="hidden" id="jstoken" name="tokenCSRF" value="<?php $Security->printToken() ?>">
|
||||||
|
|
||||||
<div class="uk-form-row">
|
<div class="uk-form-row">
|
||||||
<input name="email" class="uk-width-1-1 uk-form-large" placeholder="<?php $L->p('Email') ?>" type="text">
|
<input name="email" class="uk-width-1-1 uk-form-large" placeholder="<?php $L->p('Email') ?>" type="text">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="uk-form-row">
|
<div class="uk-form-row">
|
||||||
<button type="submit" class="uk-width-1-1 uk-button uk-button-primary uk-button-large">Send me the email</button>
|
<button type="submit" class="uk-width-1-1 uk-button uk-button-primary uk-button-large"><?php $L->p('Get login access code') ?></button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<a class="login-email" href="<?php echo HTML_PATH_ADMIN_ROOT.'login' ?>"> Back to login form</a>
|
<a class="login-email" href="<?php echo HTML_PATH_ADMIN_ROOT.'login' ?>"><i class="uk-icon-chevron-left"></i> <?php $L->p('Back to login form') ?></a>
|
|
@ -2,14 +2,14 @@
|
||||||
|
|
||||||
<form method="post" action="<?php echo HTML_PATH_ADMIN_ROOT.'login' ?>" class="uk-form" autocomplete="off">
|
<form method="post" action="<?php echo HTML_PATH_ADMIN_ROOT.'login' ?>" class="uk-form" autocomplete="off">
|
||||||
|
|
||||||
<input type="hidden" id="jstoken" name="token" value="<?php $Security->printToken() ?>">
|
<input type="hidden" id="jstoken" name="tokenCSRF" value="<?php $Security->printToken() ?>">
|
||||||
|
|
||||||
<div class="uk-form-row">
|
<div class="uk-form-row">
|
||||||
<input name="username" class="uk-width-1-1 uk-form-large" placeholder="<?php $L->p('Username') ?>" type="text">
|
<input name="username" class="uk-width-1-1 uk-form-large" placeholder="<?php $L->p('Username') ?>" type="text">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="uk-form-row">
|
<div class="uk-form-row">
|
||||||
<input name="password" class="uk-width-1-1 uk-form-large" placeholder="<?php $L->p('Password') ?>" type="text">
|
<input name="password" class="uk-width-1-1 uk-form-large" placeholder="<?php $L->p('Password') ?>" type="password">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="uk-form-row">
|
<div class="uk-form-row">
|
||||||
|
@ -20,4 +20,4 @@
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<a class="login-email" href="<?php echo HTML_PATH_ADMIN_ROOT.'login-email' ?>"><i class="uk-icon-envelope-o"></i> Log in with email</a>
|
<a class="login-email" href="<?php echo HTML_PATH_ADMIN_ROOT.'login-email' ?>"><i class="uk-icon-envelope-o"></i> <?php $L->p('Send me a login access code') ?></a>
|
|
@ -6,7 +6,7 @@ HTML::formOpen(array('class'=>'uk-form-stacked'));
|
||||||
|
|
||||||
// Security token
|
// Security token
|
||||||
HTML::formInputHidden(array(
|
HTML::formInputHidden(array(
|
||||||
'name'=>'token',
|
'name'=>'tokenCSRF',
|
||||||
'value'=>$Security->getToken()
|
'value'=>$Security->getToken()
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ HTML::formOpen(array('class'=>'uk-form-stacked'));
|
||||||
|
|
||||||
// Security token
|
// Security token
|
||||||
HTML::formInputHidden(array(
|
HTML::formInputHidden(array(
|
||||||
'name'=>'token',
|
'name'=>'tokenCSRF',
|
||||||
'value'=>$Security->getToken()
|
'value'=>$Security->getToken()
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ HTML::title(array('title'=>$L->g('Settings'), 'icon'=>'cogs'));
|
||||||
HTML::formOpen(array('class'=>'uk-form-horizontal'));
|
HTML::formOpen(array('class'=>'uk-form-horizontal'));
|
||||||
|
|
||||||
HTML::formInputHidden(array(
|
HTML::formInputHidden(array(
|
||||||
'name'=>'token',
|
'name'=>'tokenCSRF',
|
||||||
'value'=>$Security->getToken()
|
'value'=>$Security->getToken()
|
||||||
));
|
));
|
||||||
|
|
||||||
|
@ -46,11 +46,21 @@ HTML::formOpen(array('class'=>'uk-form-horizontal'));
|
||||||
'tip'=>$L->g('enable-the-command-line-mode-if-you-add-edit')
|
'tip'=>$L->g('enable-the-command-line-mode-if-you-add-edit')
|
||||||
));
|
));
|
||||||
|
|
||||||
|
HTML::legend(array('value'=>$L->g('Email account settings')));
|
||||||
|
|
||||||
|
HTML::formInputText(array(
|
||||||
|
'name'=>'emailFrom',
|
||||||
|
'label'=>$L->g('Sender email'),
|
||||||
|
'value'=>$Site->emailFrom(),
|
||||||
|
'class'=>'uk-width-1-2 uk-form-medium',
|
||||||
|
'tip'=>$L->g('Emails will be sent from this address')
|
||||||
|
));
|
||||||
|
|
||||||
HTML::legend(array('value'=>$L->g('URL Filters')));
|
HTML::legend(array('value'=>$L->g('URL Filters')));
|
||||||
|
|
||||||
HTML::formInputText(array(
|
HTML::formInputText(array(
|
||||||
'name'=>'uriPost',
|
'name'=>'uriPost',
|
||||||
'label'=>$L->g('Posts'),
|
'label'=>$L->g('Email'),
|
||||||
'value'=>$Site->uriFilters('post'),
|
'value'=>$Site->uriFilters('post'),
|
||||||
'class'=>'uk-width-1-2 uk-form-medium',
|
'class'=>'uk-width-1-2 uk-form-medium',
|
||||||
'tip'=>''
|
'tip'=>''
|
||||||
|
|
|
@ -6,7 +6,7 @@ HTML::formOpen(array('class'=>'uk-form-horizontal'));
|
||||||
|
|
||||||
// Security token
|
// Security token
|
||||||
HTML::formInputHidden(array(
|
HTML::formInputHidden(array(
|
||||||
'name'=>'token',
|
'name'=>'tokenCSRF',
|
||||||
'value'=>$Security->getToken()
|
'value'=>$Security->getToken()
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ HTML::title(array('title'=>$L->g('Settings'), 'icon'=>'cogs'));
|
||||||
HTML::formOpen(array('class'=>'uk-form-horizontal'));
|
HTML::formOpen(array('class'=>'uk-form-horizontal'));
|
||||||
|
|
||||||
HTML::formInputHidden(array(
|
HTML::formInputHidden(array(
|
||||||
'name'=>'token',
|
'name'=>'tokenCSRF',
|
||||||
'value'=>$Security->getToken()
|
'value'=>$Security->getToken()
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
|
@ -69,6 +69,9 @@ define('CLI_STATUS', 'published');
|
||||||
// Database format date
|
// Database format date
|
||||||
define('DB_DATE_FORMAT', 'Y-m-d H:i');
|
define('DB_DATE_FORMAT', 'Y-m-d H:i');
|
||||||
|
|
||||||
|
// Token time to live for login via email. The offset is defined by http://php.net/manual/en/datetime.modify.php
|
||||||
|
define('TOKEN_TTL', '+1 day');
|
||||||
|
|
||||||
// Charset, default UTF-8.
|
// Charset, default UTF-8.
|
||||||
define('CHARSET', 'UTF-8');
|
define('CHARSET', 'UTF-8');
|
||||||
|
|
||||||
|
@ -112,6 +115,7 @@ include(PATH_HELPERS.'session.class.php');
|
||||||
include(PATH_HELPERS.'redirect.class.php');
|
include(PATH_HELPERS.'redirect.class.php');
|
||||||
include(PATH_HELPERS.'sanitize.class.php');
|
include(PATH_HELPERS.'sanitize.class.php');
|
||||||
include(PATH_HELPERS.'valid.class.php');
|
include(PATH_HELPERS.'valid.class.php');
|
||||||
|
include(PATH_HELPERS.'email.class.php');
|
||||||
include(PATH_HELPERS.'filesystem.class.php');
|
include(PATH_HELPERS.'filesystem.class.php');
|
||||||
include(PATH_HELPERS.'alert.class.php');
|
include(PATH_HELPERS.'alert.class.php');
|
||||||
include(PATH_HELPERS.'paginator.class.php');
|
include(PATH_HELPERS.'paginator.class.php');
|
||||||
|
|
|
@ -18,11 +18,11 @@
|
||||||
|
|
||||||
if( $_SERVER['REQUEST_METHOD'] == 'POST' )
|
if( $_SERVER['REQUEST_METHOD'] == 'POST' )
|
||||||
{
|
{
|
||||||
$token = isset($_POST['token']) ? Sanitize::html($_POST['token']) : false;
|
$token = isset($_POST['tokenCSRF']) ? Sanitize::html($_POST['tokenCSRF']) : false;
|
||||||
|
|
||||||
if( !$Security->validateToken($token) )
|
if( !$Security->validateToken($token) )
|
||||||
{
|
{
|
||||||
Log::set(__METHOD__.LOG_SEP.'Error occurred when trying validate the token. Token ID: '.$token);
|
Log::set(__METHOD__.LOG_SEP.'Error occurred when trying validate the tokenCSRF. Token CSRF ID: '.$token);
|
||||||
|
|
||||||
// Destroy the session.
|
// Destroy the session.
|
||||||
Session::destroy();
|
Session::destroy();
|
||||||
|
@ -32,7 +32,7 @@ if( $_SERVER['REQUEST_METHOD'] == 'POST' )
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
unset($_POST['token']);
|
unset($_POST['tokenCSRF']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,8 @@ class dbSite extends dbJSON
|
||||||
'uriPost'=> array('inFile'=>false, 'value'=>'/post/'),
|
'uriPost'=> array('inFile'=>false, 'value'=>'/post/'),
|
||||||
'uriTag'=> array('inFile'=>false, 'value'=>'/tag/'),
|
'uriTag'=> array('inFile'=>false, 'value'=>'/tag/'),
|
||||||
'url'=> array('inFile'=>false, 'value'=>''),
|
'url'=> array('inFile'=>false, 'value'=>''),
|
||||||
'cliMode'=> array('inFile'=>false, 'value'=>true)
|
'cliMode'=> array('inFile'=>false, 'value'=>true),
|
||||||
|
'emailFrom'=> array('inFile'=>false, 'value'=>'')
|
||||||
);
|
);
|
||||||
|
|
||||||
function __construct()
|
function __construct()
|
||||||
|
@ -92,6 +93,11 @@ class dbSite extends dbJSON
|
||||||
return $this->db['title'];
|
return $this->db['title'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function emailFrom()
|
||||||
|
{
|
||||||
|
return $this->db['emailFrom'];
|
||||||
|
}
|
||||||
|
|
||||||
// Returns the site slogan.
|
// Returns the site slogan.
|
||||||
public function slogan()
|
public function slogan()
|
||||||
{
|
{
|
||||||
|
|
|
@ -10,7 +10,9 @@ class dbUsers extends dbJSON
|
||||||
'password'=> array('inFile'=>false, 'value'=>''),
|
'password'=> array('inFile'=>false, 'value'=>''),
|
||||||
'salt'=> array('inFile'=>false, 'value'=>'!Pink Floyd!Welcome to the machine!'),
|
'salt'=> array('inFile'=>false, 'value'=>'!Pink Floyd!Welcome to the machine!'),
|
||||||
'email'=> array('inFile'=>false, 'value'=>''),
|
'email'=> array('inFile'=>false, 'value'=>''),
|
||||||
'registered'=> array('inFile'=>false, 'value'=>'1985-03-15 10:00')
|
'registered'=> array('inFile'=>false, 'value'=>'1985-03-15 10:00'),
|
||||||
|
'tokenEmail'=> array('inFile'=>false, 'value'=>''),
|
||||||
|
'tokenEmailTTL'=>array('inFile'=>false, 'value'=>'2009-03-15 14:00')
|
||||||
);
|
);
|
||||||
|
|
||||||
function __construct()
|
function __construct()
|
||||||
|
@ -18,7 +20,7 @@ class dbUsers extends dbJSON
|
||||||
parent::__construct(PATH_DATABASES.'users.php');
|
parent::__construct(PATH_DATABASES.'users.php');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return an array with the username databases
|
// Return an array with the username databases, filtered by username.
|
||||||
public function getDb($username)
|
public function getDb($username)
|
||||||
{
|
{
|
||||||
if($this->userExists($username))
|
if($this->userExists($username))
|
||||||
|
@ -31,6 +33,18 @@ class dbUsers extends dbJSON
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return an array with the username databases, filtered by email address.
|
||||||
|
public function getByEmail($email)
|
||||||
|
{
|
||||||
|
foreach($this->db as $user) {
|
||||||
|
if($user['email']==$email) {
|
||||||
|
return $user;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Return TRUE if the user exists, FALSE otherwise.
|
// Return TRUE if the user exists, FALSE otherwise.
|
||||||
public function userExists($username)
|
public function userExists($username)
|
||||||
{
|
{
|
||||||
|
@ -42,13 +56,32 @@ class dbUsers extends dbJSON
|
||||||
return $this->db;
|
return $this->db;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setPassword($password)
|
public function generateTokenEmail($username)
|
||||||
|
{
|
||||||
|
// Random hash
|
||||||
|
$token = sha1(Text::randomText(SALT_LENGTH).time());
|
||||||
|
$this->db[$username]['tokenEmail'] = $token;
|
||||||
|
|
||||||
|
// Token time to live, defined by TOKEN_TTL
|
||||||
|
$this->db[$username]['tokenEmailTTL'] = Date::currentOffset(DB_DATE_FORMAT, TOKEN_TTL);
|
||||||
|
|
||||||
|
// Save the database
|
||||||
|
if( $this->save() === false ) {
|
||||||
|
Log::set(__METHOD__.LOG_SEP.'Error occurred when trying to save the database file.');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $token;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setPassword($username, $password)
|
||||||
{
|
{
|
||||||
$salt = Text::randomText(SALT_LENGTH);
|
$salt = Text::randomText(SALT_LENGTH);
|
||||||
$hash = sha1($password.$salt);
|
$hash = sha1($password.$salt);
|
||||||
|
|
||||||
$args['salt'] = $salt;
|
$args['username'] = $username;
|
||||||
$args['password'] = $hash;
|
$args['salt'] = $salt;
|
||||||
|
$args['password'] = $hash;
|
||||||
|
|
||||||
return $this->set($args);
|
return $this->set($args);
|
||||||
}
|
}
|
||||||
|
@ -155,4 +188,4 @@ class dbUsers extends dbJSON
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -15,6 +15,13 @@ class Date {
|
||||||
return $Date->format($format);
|
return $Date->format($format);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function currentOffset($format, $offset)
|
||||||
|
{
|
||||||
|
$Date = new DateTime();
|
||||||
|
$Date->modify($offset);
|
||||||
|
return $Date->format($format);
|
||||||
|
}
|
||||||
|
|
||||||
// Format a local time/date according to locale settings.
|
// Format a local time/date according to locale settings.
|
||||||
public static function format($date, $currentFormat, $outputFormat)
|
public static function format($date, $currentFormat, $outputFormat)
|
||||||
{
|
{
|
||||||
|
|
|
@ -7,18 +7,18 @@ class Email {
|
||||||
{
|
{
|
||||||
$headers = array();
|
$headers = array();
|
||||||
$headers[] = 'MIME-Version: 1.0';
|
$headers[] = 'MIME-Version: 1.0';
|
||||||
$headers[] = 'Content-type: text/plain; charset=utf-8';
|
$headers[] = 'Content-type: text/html; charset=utf-8';
|
||||||
$headers[] = 'From: '.$args['from'];
|
$headers[] = 'From: '.$args['from'];
|
||||||
$headers[] = 'X-Mailer: PHP/'.phpversion();
|
$headers[] = 'X-Mailer: PHP/'.phpversion();
|
||||||
|
|
||||||
$message = '<html>
|
$message = '<html>
|
||||||
<head>
|
<head>
|
||||||
<title>Bludit</title>
|
<title>BLUDIT</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div style="margin: 0px auto; border: 1px solid #2672ec; padding: 10px;">
|
<div style="margin: 0px auto; border: 1px solid #2672ec; padding: 10px;">
|
||||||
<div style="font-size: 26px; padding: 10px; background-color: #2672ec;">Bludit</div>
|
<div style="font-size: 26px; padding: 10px; background-color: #2672ec; color: #FFFFFF;">BLUDIT</div>
|
||||||
<p>'.$args['message'].'</p>
|
'.$args['message'].'
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>';
|
</html>';
|
||||||
|
|
|
@ -55,6 +55,7 @@ class Sanitize {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns the email without illegal characters.
|
||||||
public static function email($email)
|
public static function email($email)
|
||||||
{
|
{
|
||||||
return( filter_var($email, FILTER_SANITIZE_EMAIL) );
|
return( filter_var($email, FILTER_SANITIZE_EMAIL) );
|
||||||
|
|
|
@ -111,6 +111,11 @@ class Text {
|
||||||
return $text;
|
return $text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function replaceAssoc(array $replace, $text)
|
||||||
|
{
|
||||||
|
return str_replace(array_keys($replace), array_values($replace), $text);
|
||||||
|
}
|
||||||
|
|
||||||
public static function cleanUrl($string, $separator='-')
|
public static function cleanUrl($string, $separator='-')
|
||||||
{
|
{
|
||||||
// Transliterate characters to ASCII
|
// Transliterate characters to ASCII
|
||||||
|
|
|
@ -7,6 +7,7 @@ class Valid {
|
||||||
return filter_var($ip, FILTER_VALIDATE_IP);
|
return filter_var($ip, FILTER_VALIDATE_IP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns the email filtered or FALSE if the filter fails.
|
||||||
public static function email($email)
|
public static function email($email)
|
||||||
{
|
{
|
||||||
return filter_var($email, FILTER_VALIDATE_EMAIL);
|
return filter_var($email, FILTER_VALIDATE_EMAIL);
|
||||||
|
|
|
@ -59,7 +59,7 @@ class Login {
|
||||||
$password = trim($password);
|
$password = trim($password);
|
||||||
|
|
||||||
if(empty($username) || empty($password)) {
|
if(empty($username) || empty($password)) {
|
||||||
Log::set(__METHOD__.LOG_SEP.'Username or Password empty. Username: '.$username.' - Password: '.$password);
|
Log::set(__METHOD__.LOG_SEP.'Username or password empty. Username: '.$username.' - Password: '.$password);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,6 +75,8 @@ class Login {
|
||||||
{
|
{
|
||||||
$this->setLogin($username, $user['role']);
|
$this->setLogin($username, $user['role']);
|
||||||
|
|
||||||
|
Log::set(__METHOD__.LOG_SEP.'User logged succeeded by username and password - Username: '.$username);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -84,6 +86,50 @@ class Login {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function verifyUserByToken($username, $token)
|
||||||
|
{
|
||||||
|
$username = Sanitize::html($username);
|
||||||
|
$token = Sanitize::html($token);
|
||||||
|
|
||||||
|
$username = trim($username);
|
||||||
|
$token = trim($token);
|
||||||
|
|
||||||
|
if(empty($username) || empty($token)) {
|
||||||
|
Log::set(__METHOD__.LOG_SEP.'Username or Token-email empty. Username: '.$username.' - Token-email: '.$token);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$user = $this->dbUsers->getDb($username);
|
||||||
|
if($user==false) {
|
||||||
|
Log::set(__METHOD__.LOG_SEP.'Username does not exist: '.$username);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$currentTime = Date::current(DB_DATE_FORMAT);
|
||||||
|
if($user['tokenEmailTTL']<$currentTime) {
|
||||||
|
Log::set(__METHOD__.LOG_SEP.'Token-email expired: '.$username);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if($token === $user['tokenEmail'])
|
||||||
|
{
|
||||||
|
// Set the user loggued.
|
||||||
|
$this->setLogin($username, $user['role']);
|
||||||
|
|
||||||
|
// Invalidate the current token.
|
||||||
|
$this->dbUsers->generateTokenEmail($username);
|
||||||
|
|
||||||
|
Log::set(__METHOD__.LOG_SEP.'User logged succeeded by Token-email - Username: '.$username);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Log::set(__METHOD__.LOG_SEP.'Token-email incorrect.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public function fingerPrint($random=false)
|
public function fingerPrint($random=false)
|
||||||
{
|
{
|
||||||
// User agent
|
// User agent
|
||||||
|
|
|
@ -23,13 +23,13 @@ class Security extends dbJSON
|
||||||
$token = Text::randomText(8);
|
$token = Text::randomText(8);
|
||||||
$token = sha1($token);
|
$token = sha1($token);
|
||||||
|
|
||||||
Session::set('token', $token);
|
Session::set('tokenCSRF', $token);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate the token.
|
// Validate the token.
|
||||||
public function validateToken($token)
|
public function validateToken($token)
|
||||||
{
|
{
|
||||||
$sessionToken = Session::get('token');
|
$sessionToken = Session::get('tokenCSRF');
|
||||||
|
|
||||||
return ( !empty($sessionToken) && ($sessionToken===$token) );
|
return ( !empty($sessionToken) && ($sessionToken===$token) );
|
||||||
}
|
}
|
||||||
|
@ -37,12 +37,12 @@ class Security extends dbJSON
|
||||||
// Returns the token.
|
// Returns the token.
|
||||||
public function getToken()
|
public function getToken()
|
||||||
{
|
{
|
||||||
return Session::get('token');
|
return Session::get('tokenCSRF');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function printToken()
|
public function printToken()
|
||||||
{
|
{
|
||||||
echo Session::get('token');
|
echo Session::get('tokenCSRF');
|
||||||
}
|
}
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
|
@ -179,5 +179,15 @@
|
||||||
"published": "Published",
|
"published": "Published",
|
||||||
"scheduled-posts": "Scheduled posts",
|
"scheduled-posts": "Scheduled posts",
|
||||||
"statics": "Statics",
|
"statics": "Statics",
|
||||||
"name": "Name"
|
"name": "Name",
|
||||||
|
"email-account-settings":"Email account settings",
|
||||||
|
"sender-email": "Sender email",
|
||||||
|
"emails-will-be-sent-from-this-address":"Emails will be sent from this address.",
|
||||||
|
"bludit-login-access-code": "BLUDIT - Login access code",
|
||||||
|
"check-your-inbox-for-your-login-access-code":"Check your inbox for your log in access code",
|
||||||
|
"there-was-a-problem-sending-the-email":"There was a problem sending the email",
|
||||||
|
"back-to-login-form": "Back to login form",
|
||||||
|
"send-me-a-login-access-code": "Send me a login access code",
|
||||||
|
"get-login-access-code": "Get login access code",
|
||||||
|
"email-notification-login-access-code": "<p>This is a notification from your website {{WEBSITE_NAME}}</p><p>You request a login access code, follow the next link:</p><p>{{LINK}}</p>"
|
||||||
}
|
}
|
Loading…
Reference in New Issue