
remove dependence on jQuery add image delete Admin ui fix for mobile image updates to new style update comments
745 lines
23 KiB
PHP
745 lines
23 KiB
PHP
<?php
|
|
/**
|
|
* app/models/user.php
|
|
*
|
|
* This class is used for the manipulation of the user database table.
|
|
*
|
|
* @todo needs a re-build
|
|
* @todo finish fixing the check functions that were migrated here
|
|
* These could go in the Forms class?
|
|
*
|
|
* @version 5.0.1
|
|
* @author Joey Kimsey <Joey@thetempusproject.com>
|
|
* @link https://TheTempusProject.com
|
|
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
|
|
*/
|
|
namespace TheTempusProject\Models;
|
|
|
|
use TheTempusProject\Bedrock\Functions\Check;
|
|
use TheTempusProject\Canary\Bin\Canary as Debug;
|
|
use TheTempusProject\Bedrock\Functions\Hash;
|
|
use TheTempusProject\Bedrock\Functions\Session;
|
|
use TheTempusProject\Bedrock\Functions\Code;
|
|
use TheTempusProject\Bedrock\Classes\Config;
|
|
use TheTempusProject\Canary\Classes\CustomException;
|
|
use TheTempusProject\Classes\Email;
|
|
use TheTempusProject\Classes\DatabaseModel;
|
|
use TheTempusProject\Classes\Preferences;
|
|
use TheTempusProject\Classes\Forms;
|
|
use TheTempusProject\TheTempusProject as App;
|
|
|
|
class User extends DatabaseModel {
|
|
public $tableName = 'users';
|
|
public $modelVersion = '1.0';
|
|
public $databaseMatrix = [
|
|
[ 'registered', 'int', '10' ],
|
|
[ 'terms', 'int', '1' ],
|
|
[ 'confirmed', 'int', '1' ],
|
|
[ 'userGroup', 'int', '11' ],
|
|
[ 'lastLogin', 'int', '10' ],
|
|
[ 'username', 'varchar', '16' ],
|
|
[ 'password', 'varchar', '80' ],
|
|
[ 'email', 'varchar', '75' ],
|
|
[ 'name', 'varchar', '20' ],
|
|
[ 'confirmationCode', 'varchar', '80' ],
|
|
[ 'prefs', 'text', '' ],
|
|
];
|
|
public $searchFields = [
|
|
'username',
|
|
];
|
|
public $preferenceMatrix = [
|
|
'gender' => [
|
|
'pretty' => 'Gender',
|
|
'type' => 'select',
|
|
'default' => 'unspecified',
|
|
'options' => [
|
|
'male',
|
|
'female',
|
|
'other',
|
|
'unspecified',
|
|
],
|
|
],
|
|
'newsletter' => [
|
|
'pretty' => 'Receive our Newsletter?',
|
|
'type' => 'checkbox',
|
|
'default' => 'true',
|
|
],
|
|
'avatar' => [
|
|
'pretty' => 'Avatar',
|
|
'type' => 'file',
|
|
'default' => 'images/defaultAvatar.png',
|
|
],
|
|
'timezone' => [
|
|
'pretty' => 'Timezone',
|
|
'type' => 'timezone',
|
|
'default' => 'America/New_York',
|
|
],
|
|
'dateFormat' => [
|
|
'pretty' => 'Date Format',
|
|
'type' => 'select',
|
|
'default' => 'F j, Y',
|
|
'options' => [
|
|
'1-8-1991' => 'n-j-Y',
|
|
'8-1-1991' => 'j-n-Y',
|
|
'01-08-1991' => 'm-d-Y',
|
|
'08-01-1991' => 'd-m-Y',
|
|
'January 8, 1991' => 'F-j-Y',
|
|
'8 January, 1991' => 'j-F-Y',
|
|
'January 08, 1991' => 'F-d-Y',
|
|
'08 January, 1991' => 'd-F-Y',
|
|
'Jan 8, 1991' => 'M-j-Y',
|
|
'8 Jan 1991' => 'j-M-Y',
|
|
'Jan 08, 1991' => 'M-d-Y',
|
|
'08 Jan 1991' => 'd-M-Y',
|
|
],
|
|
],
|
|
'timeFormat' => [
|
|
'pretty' => 'Time Format',
|
|
'type' => 'select',
|
|
'default' => 'g:i:s A',
|
|
'options' => [
|
|
'3:33:33 AM' => 'g:i:s A',
|
|
'03:33:33 AM' => 'h:i:s A',
|
|
'3:33:33 am' => 'g:i:s a',
|
|
'03:33:33 am' => 'h:i:s a',
|
|
'3:33:33 (military)' => 'G:i:s',
|
|
'03:33:33 (military)' => 'H:i:s',
|
|
],
|
|
],
|
|
'pageLimit' => [
|
|
'pretty' => 'Items Displayed Per Page',
|
|
'type' => 'select',
|
|
'default' => '10',
|
|
'options' => [
|
|
'10',
|
|
'15',
|
|
'20',
|
|
'25',
|
|
'50',
|
|
],
|
|
],
|
|
'darkMode' => [
|
|
'pretty' => 'Enable Dark-Mode viewing',
|
|
'type' => 'checkbox',
|
|
'default' => 'false',
|
|
],
|
|
];
|
|
protected static $avatars;
|
|
protected static $preferences;
|
|
protected static $group;
|
|
protected static $usernames;
|
|
protected $data;
|
|
|
|
public function __construct() {
|
|
parent::__construct();
|
|
self::$user = $this;
|
|
self::$preferences = new Preferences;
|
|
self::$group = new Group;
|
|
}
|
|
|
|
public function getPreferences( $id ) {
|
|
if ( !Check::id( $id ) ) {
|
|
return false;
|
|
}
|
|
$userData = $this->get( $id );
|
|
$prefs = json_decode( $userData->prefs, true );
|
|
return $prefs;
|
|
}
|
|
|
|
public function getPreferencesDelta() {
|
|
$defaults = $this->getDefaultPreferences();
|
|
foreach ( $defaults as $key => $value ) {
|
|
if ( isset( self::$preferences[ $key ] ) ) {
|
|
$defaults[ $key ] = self::$preferences[ $key ];
|
|
}
|
|
}
|
|
return $defaults;
|
|
}
|
|
|
|
public function getDefaultPreferences() {
|
|
return self::$preferences->getDefaultPreferencesArray();
|
|
}
|
|
|
|
/**
|
|
* Check the database for a user with the same email.
|
|
*
|
|
* @param {string} [$email] - The email being tested.
|
|
* @return {bool}
|
|
*/
|
|
public function noEmailExists( $email ) {
|
|
if ( Check::email( $email ) ) {
|
|
$emailQuery = self::$db->get( $this->tableName, [ 'email', '=', $email ] );
|
|
if ( $emailQuery->count() == 0 ) {
|
|
return true;
|
|
}
|
|
}
|
|
// self::addError("Email is already in use.", $email);
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Check the database for a user with the same username.
|
|
*
|
|
* @param {string} [$data] - The string being tested.
|
|
* @return {bool}
|
|
*/
|
|
public function usernameExists( $data ) {
|
|
if ( Forms::checkUsername( $data ) ) {
|
|
$usernameResults = self::$db->get( $this->tableName, [ 'username', '=', $data ] );
|
|
if ( $usernameResults->count() ) {
|
|
return true;
|
|
}
|
|
}
|
|
// self::addError("No user exists in the DB.", $data);
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Checks username formatting.
|
|
*
|
|
* Requirements:
|
|
* - 4 - 16 characters long
|
|
* - must only contain numbers and letters: [A - Z] , [a - z], [0 - 9]
|
|
*
|
|
* @param {string} [$data] - The string being tested.
|
|
* @return {bool}
|
|
*/
|
|
public function checkUsername( $data ) {
|
|
if ( strlen( $data ) > 16 ) {
|
|
// self::addError("Username must be be 4 to 16 numbers or letters.", $data);
|
|
return false;
|
|
}
|
|
if ( strlen( $data ) < 4 ) {
|
|
// self::addError("Username must be be 4 to 16 numbers or letters.", $data);
|
|
return false;
|
|
}
|
|
if ( !ctype_alnum( $data ) ) {
|
|
// self::addError("Username must be be 4 to 16 numbers or letters.", $data);
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Find and define usernames by user ID.
|
|
*
|
|
* @param {int} [$id] - The ID of the user you are looking for.
|
|
* @return {string} - Either the username or 'unknown' will be returned.
|
|
*/
|
|
public function getUsername( $id ) {
|
|
if ( !Check::id( $id ) ) {
|
|
return false;
|
|
}
|
|
if ( !isset( self::$usernames[ $id ] ) ) {
|
|
$user = $this->get( $id );
|
|
if ( $user !== false ) {
|
|
self::$usernames[ $id ] = $user->username;
|
|
} else {
|
|
self::$usernames[ $id ] = 'Unknown';
|
|
}
|
|
}
|
|
return self::$usernames[ $id ];
|
|
}
|
|
|
|
/**
|
|
* Since we need a cache of the usernames, we use this function
|
|
* to find/return all usernames based on ID.
|
|
*
|
|
* @param {int} [$username] - The username of the user you are looking for.
|
|
* @return {int}
|
|
*/
|
|
public function getID( $username ) {
|
|
if ( !Forms::checkUsername( $username ) ) {
|
|
return false;
|
|
}
|
|
$user = $this->get( $username );
|
|
if ( $user !== false ) {
|
|
return $user->ID;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Find and define user avatar image urls.
|
|
*
|
|
* @param {int} [$id] - The ID of the user you are looking for.
|
|
* @return {string} - Either the username or 'unknown' will be returned.
|
|
*/
|
|
public function getAvatar( $id ) {
|
|
if ( !Check::id( $id ) ) {
|
|
return false;
|
|
}
|
|
if ( !isset( self::$avatars[ $id ] ) ) {
|
|
if ( $this->get( $id ) ) {
|
|
self::$avatars[ $id ] = self::data()->avatar;
|
|
} else {
|
|
self::$avatars[ $id ] = '{BASE}images/defaultAvatar.png';
|
|
}
|
|
}
|
|
return self::$avatars[ $id ];
|
|
}
|
|
|
|
/**
|
|
* Delete the specified user(s).
|
|
*
|
|
* @param {int|array} [$data] - The log ID or array of ID's to be deleted.
|
|
* @return {bool}
|
|
*/
|
|
public function delete( $idArray ) {
|
|
if ( !is_array( $idArray ) ) {
|
|
$idArray = [ $idArray ];
|
|
}
|
|
foreach ( $idArray as $id ) {
|
|
if ( App::$activeUser->ID == $id ) {
|
|
Debug::info( 'Attempting to delete own account.' );
|
|
return false;
|
|
}
|
|
$user = $this->get( $id );
|
|
if (
|
|
'Super' == $user->groupName
|
|
&& 'Super' !== App::$activeGroup->name
|
|
) {
|
|
Debug::info( 'Attempting to delete superior account.' );
|
|
return false;
|
|
}
|
|
}
|
|
return parent::delete( $idArray );
|
|
}
|
|
|
|
/**
|
|
* Attempt to authenticate a user login and set them as the active user.
|
|
*
|
|
* @param {string} [$username] - The username being used to login.
|
|
* @param {string} [$password] - The un-hashed password.
|
|
* @param {bool} [$remember] - Whether the user wishes to be remembered or not.
|
|
* @return {bool}
|
|
*/
|
|
public function logIn( $username, $password, $remember = false ) {
|
|
if ( !isset( self::$session ) ) {
|
|
self::$session = new Sessions;
|
|
}
|
|
if ( !isset( self::$log ) ) {
|
|
self::$log = new Log;
|
|
}
|
|
Debug::group( 'login', 1 );
|
|
if ( !Forms::checkUsername( $username ) ) {
|
|
Debug::warn( 'Invalid Username.' );
|
|
return false;
|
|
}
|
|
if ( !$this->get( $username ) ) {
|
|
self::$log->login( 0, "User not found: $username" );
|
|
Debug::warn( "User not found: $username" );
|
|
return false;
|
|
}
|
|
// login attempts protection.
|
|
$timeLimit = ( time() - 3600 );
|
|
$limit = Config::getValue( 'main/loginLimit' );
|
|
$user = $this->data();
|
|
if ( $limit > 0 ) {
|
|
$limitCheck = self::$db->get(
|
|
'logs',
|
|
[
|
|
'source', '=', 'login',
|
|
'AND',
|
|
'userID', '=', $user->ID,
|
|
'AND',
|
|
'time', '>=', $timeLimit,
|
|
'AND',
|
|
'action', '!=', 'pass',
|
|
]
|
|
);
|
|
if ( $limitCheck->count() >= $limit ) {
|
|
Debug::info( 'login: Limit reached.', 1 );
|
|
self::$log->login( $user->ID, 'Too many failed attempts.' );
|
|
Debug::warn( 'Too many failed login attempts, please try again later.' );
|
|
return false;
|
|
}
|
|
}
|
|
if ( !Check::password( $password ) ) {
|
|
Debug::warn( 'Invalid password.' );
|
|
self::$log->login( $user->ID, 'Invalid Password.' );
|
|
return false;
|
|
}
|
|
if ( !Hash::check( $password, $user->password ) ) {
|
|
Debug::warn( 'Pass hash does not match.' );
|
|
self::$log->login( $user->ID, 'Wrong Password.' );
|
|
return false;
|
|
}
|
|
self::$session->newSession( null, true, $remember, $user->ID );
|
|
self::$log->login( $this->data()->ID, 'pass' );
|
|
$this->update( $this->data()->ID, [ 'lastLogin' => time() ] );
|
|
Debug::gend();
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Log out the currently active user.
|
|
*/
|
|
public function logOut() {
|
|
if ( !isset( self::$session ) ) {
|
|
self::$session = new Sessions;
|
|
}
|
|
Debug::group( 'Logout', 1 );
|
|
self::$session->destroy( Session::get( 'SessionToken' ) );
|
|
App::$isLoggedIn = false;
|
|
App::$isMember = false;
|
|
App::$isMod = false;
|
|
App::$isAdmin = false;
|
|
App::$activeUser = null;
|
|
Debug::info( 'User has been logged out.' );
|
|
Debug::gend();
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Change a user password.
|
|
*
|
|
* @param {string} [$code] - The confirmation code required from the password email.
|
|
* @param {string} [$password] - The new password for the user's account.
|
|
* @return {bool}
|
|
*/
|
|
public function changePassword( $code, $password ) {
|
|
if ( !Check::password( $password ) ) {
|
|
return false;
|
|
}
|
|
$data = self::$db->get( $this->tableName, [ 'confirmationCode', '=', $code ] );
|
|
if ( $data->count() ) {
|
|
$this->data = $data->first();
|
|
$this->update(
|
|
$this->data->ID,
|
|
[ 'password' => Hash::make( $password ), 'confirmationCode' => '', ],
|
|
);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Create a list of registered users.
|
|
*
|
|
* @param {array} [$filter] - A filter to be applied to the users list.
|
|
* @return {bool|object}
|
|
*/
|
|
public function userList( $filter = null ) {
|
|
if ( ! empty( $filter ) ) {
|
|
switch ( $filter ) {
|
|
case 'newsletter':
|
|
$data = self::$db->searchColumn( $this->tableName, 'prefs', 'newsletter":"true' );
|
|
break;
|
|
default:
|
|
$data = self::$db->get( $this->tableName, '*' );
|
|
break;
|
|
}
|
|
} else {
|
|
$data = self::$db->get( $this->tableName, '*' );
|
|
}
|
|
if ( ! $data->count() ) {
|
|
return false;
|
|
}
|
|
return (object) $data->results();
|
|
}
|
|
|
|
/**
|
|
* Create a list of recently registered users.
|
|
*
|
|
* @param {int} [$limit] - How many posts you would like returned.
|
|
* @return {bool|object}
|
|
*/
|
|
public function recent( $limit = null ) {
|
|
if ( empty( $limit ) ) {
|
|
$data = self::$db->get( $this->tableName, '*' );
|
|
} else {
|
|
$data = self::$db->get( $this->tableName, [ 'ID', '>', '0' ], 'ID', 'DESC', [ 0, $limit ] );
|
|
}
|
|
if ( !$data->count() ) {
|
|
return false;
|
|
}
|
|
return (object) $data->results();
|
|
}
|
|
|
|
/**
|
|
* Check the database for a user with the same confirmation code.
|
|
*
|
|
* @param {string} [$code] - The confirmation code being checked.
|
|
* @return {bool}
|
|
*/
|
|
public function checkCode( $code ) {
|
|
$data = self::$db->get( $this->tableName, [ 'confirmationCode', '=', $code ] );
|
|
if ( $data->count() > 0 ) {
|
|
return true;
|
|
}
|
|
Debug::error( 'User confirmation code not found.' );
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Generate and save a new confirmation code for the user.
|
|
*
|
|
* @param {int} [$id] - The user ID to update the confirmation code for.
|
|
* @return {bool}
|
|
*/
|
|
public function newCode( $id ) {
|
|
$data = self::$db->get( $this->tableName, [ 'ID', '=', $id ] );
|
|
if ( $data->count() == 0 ) {
|
|
return false;
|
|
}
|
|
$this->data = $data->first();
|
|
$Ccode = md5( uniqid() );
|
|
$this->update(
|
|
$this->data->ID,
|
|
[ 'confirmationCode' => $Ccode ],
|
|
);
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Finds and confirms a user by their confirmation code.
|
|
*
|
|
* @param {string} [$code] - The confirmation code sent to the user.
|
|
* @return {bool}
|
|
*/
|
|
public function confirm( $code ) {
|
|
$data = self::$db->get( $this->tableName, [ 'confirmationCode', '=', $code ] );
|
|
if ( $data->count() ) {
|
|
$this->data = $data->first();
|
|
$this->update(
|
|
$this->data->ID,
|
|
[ 'confirmed' => 1, 'confirmationCode' => '', ],
|
|
);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Check if the specified user exists or not.
|
|
*
|
|
* @return {bool}
|
|
* @todo this function should actually check for a user
|
|
*/
|
|
public function exists() {
|
|
return ( !empty( $this->data ) ) ? true : false;
|
|
}
|
|
|
|
public function filter( $data, $params = [] ) {
|
|
foreach ( $data as $instance ) {
|
|
if ( !is_object( $instance ) ) {
|
|
$instance = (object) $data;
|
|
$end = true;
|
|
}
|
|
if ( $instance->confirmed == 1 ) {
|
|
$instance->confirmedText = 'Yes';
|
|
} else {
|
|
$instance->confirmedText = 'No';
|
|
}
|
|
$group = self::$group->findById( $instance->userGroup );
|
|
if ( !empty( $group ) ) {
|
|
$instance->groupName = $group->name;
|
|
} else {
|
|
$instance->groupName = 'Unknown';
|
|
}
|
|
$instance->prefs = json_decode( $instance->prefs, true );
|
|
$instance->gender = $instance->prefs['gender'];
|
|
$instance->avatar = $instance->prefs['avatar'];
|
|
$instance->usernamePretty = \ucfirst( $instance->username );
|
|
$out[] = $instance;
|
|
if ( !empty( $end ) ) {
|
|
$out = $out[0];
|
|
break;
|
|
}
|
|
}
|
|
return $out;
|
|
}
|
|
|
|
/**
|
|
* Get user data from an ID or username.
|
|
*
|
|
* @param {int|string} [$user] - Either the username or user ID being searched for.
|
|
* @return {bool|array}
|
|
*/
|
|
public function get( $user ) {
|
|
if ( empty( self::$group ) ) {
|
|
self::$group = new Group;
|
|
}
|
|
$user = (string) $user;
|
|
$field = ( ctype_digit( $user ) ) ? 'ID' : 'username';
|
|
if ( $field == 'username' ) {
|
|
if ( !Forms::checkUsername( $user ) ) {
|
|
Debug::info( 'modelUser->get Username improperly formatted.' );
|
|
return false;
|
|
}
|
|
} else {
|
|
if ( !Check::id( $user ) ) {
|
|
Debug::info( 'modelUser->get Invalid ID.' );
|
|
return false;
|
|
}
|
|
}
|
|
$data = self::$db->get( $this->tableName, [ $field, '=', $user ] );
|
|
if ( !$data->count() ) {
|
|
Debug::info( "modelUser->get User not found: $user" );
|
|
return false;
|
|
}
|
|
$this->data = $this->filter( $data->first() );
|
|
return $this->data;
|
|
}
|
|
|
|
/**
|
|
* Find a user by email address.
|
|
*
|
|
* @param {string} [$email] - The email being searched for.
|
|
* @return {bool}
|
|
*/
|
|
public function findByEmail( $email ) {
|
|
if ( Check::email( $email ) ) {
|
|
$data = self::$db->get( $this->tableName, [ 'email', '=', $email ] );
|
|
if ( $data->count() ) {
|
|
$this->data = $data->first();
|
|
return true;
|
|
}
|
|
}
|
|
Debug::error( "modelUser->findByEmail - User not found by email: $email" );
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Create a new user.
|
|
*
|
|
* @param {array} [$fields] - The New User's data.
|
|
* @return {bool}
|
|
*/
|
|
public function create( $fields = [] ) {
|
|
if ( empty( $fields ) ) {
|
|
return false;
|
|
}
|
|
if ( !isset( $fields['email' ] ) ) {
|
|
return false;
|
|
}
|
|
if ( !isset( $fields['prefs' ] ) ) {
|
|
$fields['prefs'] = json_encode( $this->getDefaultPreferences() );
|
|
}
|
|
if ( !isset( $fields['userGroup' ] ) ) {
|
|
$fields['userGroup'] = Config::getValue( 'group/defaultGroup' );
|
|
} else {
|
|
if ( in_array( $fields['userGroup'], [ '1', 1 ] ) ) {
|
|
if ( App::$activeGroup && 'Super' !== App::$activeGroup->name ) {
|
|
Debug::error( 'You do not have permission to do this.' );
|
|
}
|
|
}
|
|
}
|
|
if ( !isset( $fields['registered' ] ) ) {
|
|
$fields['registered'] = time();
|
|
}
|
|
if ( !isset( $fields['confirmed' ] ) ) {
|
|
$code = Code::genConfirmation();
|
|
$fields['confirmed'] = 0;
|
|
$fields['confirmationCode'] = $code;
|
|
Email::send( $fields['email'], 'confirmation', $code, [ 'template' => true ] );
|
|
}
|
|
if ( !self::$db->insert( $this->tableName, $fields ) ) {
|
|
Debug::error( 'User not created.' );
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Update a user database entry.
|
|
*
|
|
* @param {array} [$fields] - The fields to be updated.
|
|
* @param {int} [$id] - The user ID being updated.
|
|
* @return {bool}
|
|
*/
|
|
public function update( $id, $fields = [] ) {
|
|
if ( !Check::id( $id ) ) {
|
|
return false;
|
|
}
|
|
if ( !self::$db->update( $this->tableName, $id, $fields ) ) {
|
|
new CustomException( 'userUpdate' );
|
|
Debug::error( "User: $id not updated: " . var_export( $fields, true ) );
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Update a user's preferences.
|
|
*
|
|
* @param {array} [$fields] - The fields to be updated.
|
|
* @param {int} [$id] - The user ID being updated.
|
|
* @return {bool}
|
|
*/
|
|
public function updatePrefs( $fields, $id ) {
|
|
if ( !Check::id( $id ) ) {
|
|
return false;
|
|
}
|
|
$userData = $this->get( $id );
|
|
$prefsInput = $userData->prefs;
|
|
foreach ( $fields as $name => $value ) {
|
|
$prefsInput[$name] = $value;
|
|
}
|
|
$fields = [ 'prefs' => json_encode( $prefsInput ) ];
|
|
if ( !self::$db->update( $this->tableName, $id, $fields ) ) {
|
|
Debug::error( "User: $id not updated." );
|
|
return false;
|
|
}
|
|
if ( $id === App::$activeUser->ID ) {
|
|
$userData = $this->get( $id );
|
|
App::$activeUser = $userData;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Return the most recent database data.
|
|
*
|
|
* @return {array} - An array of the user data.
|
|
*/
|
|
public function data() {
|
|
return $this->data;
|
|
}
|
|
|
|
public function authorize( $username, $password ) {
|
|
if ( !isset( self::$log ) ) {
|
|
self::$log = new Log;
|
|
}
|
|
if ( !$this->get( $username ) ) {
|
|
self::$log->login( 0, "API: User not found: $username" );
|
|
return false;
|
|
}
|
|
// login attempts protection.
|
|
$timeLimit = ( time() - 3600 );
|
|
$limit = Config::getValue( 'main/loginLimit' );
|
|
$user = $this->data();
|
|
if ( $limit > 0 ) {
|
|
$limitCheck = self::$db->get(
|
|
'logs',
|
|
[
|
|
'source', '=', 'login',
|
|
'AND',
|
|
'userID', '=', $user->ID,
|
|
'AND',
|
|
'time', '>=', $timeLimit,
|
|
'AND',
|
|
'action', '!=', 'pass',
|
|
]
|
|
);
|
|
if ( $limitCheck->count() >= $limit ) {
|
|
self::$log->login( $user->ID, 'API: Too many failed attempts.' );
|
|
return false;
|
|
}
|
|
}
|
|
if ( !Check::password( $password ) ) {
|
|
self::$log->login( $user->ID, 'API: Invalid Password.' );
|
|
return false;
|
|
}
|
|
if ( !Hash::check( $password, $user->password ) ) {
|
|
self::$log->login( $user->ID, 'API: Wrong Password.' );
|
|
return false;
|
|
}
|
|
self::$log->login( $this->data()->ID, 'API: pass' );
|
|
return $user;
|
|
}
|
|
}
|