427 lines
13 KiB
PHP
427 lines
13 KiB
PHP
<?php
|
|
use \Firebase\JWT\JWT;
|
|
|
|
/**
|
|
* Class for identif
|
|
*/
|
|
class User{
|
|
private static $isLoggedIn;
|
|
private static $authToken;
|
|
private static $userInfo = [];
|
|
private static $userTypesTableKeys = [
|
|
'broker' => 'brokers',
|
|
'customer' => 'customers',
|
|
'commercial_lead' => 'commercial_leads',
|
|
'supplier' => 'suppliers'
|
|
];
|
|
private static $validationUsername = '';
|
|
|
|
function __construct($authToken = null){
|
|
if($authToken){
|
|
self::$authToken = str_replace('Bearer ', '', $authToken);
|
|
self::$isLoggedIn = self::validateAccessToken(self::$authToken);
|
|
}else{
|
|
self::$isLoggedIn = self::validateSession();
|
|
}
|
|
}
|
|
|
|
public function getTableByUser($userType){
|
|
return self::$userTypesTableKeys[$userType];
|
|
}
|
|
|
|
private static function validateSession(){
|
|
session_start();
|
|
if(isset($_SESSION['data'])){
|
|
self::$userInfo = $_SESSION['data'];
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
private static function validateAccessToken($authToken){
|
|
$secretKey = base64_decode(JWT_API_SECRET_KEY);
|
|
try {
|
|
$decodedJWT = JWT::decode($authToken, $secretKey, array(JWT_ALGORITHM));
|
|
self::$userInfo = (array) $decodedJWT->data;
|
|
|
|
return true;
|
|
|
|
} catch (Exception $e) {
|
|
self::$userInfo['errorMessage'] = $e->getMessage();
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* genereates a has for a password string. The value is 60 charactes MAX due to options
|
|
* @param String $password password to be hashed
|
|
* @return Sting 60 characters long hashed string
|
|
*/
|
|
public static function hashPassword($password){
|
|
$hashOptions = [
|
|
'cost' => 12
|
|
];
|
|
|
|
return password_hash($password, PASSWORD_BCRYPT, $hashOptions);
|
|
}
|
|
|
|
public static function generateApiToken($userInfo){
|
|
$tokenId = base64_encode(random_bytes(32));
|
|
$issuedAt = time();
|
|
$notBefore = $issuedAt;
|
|
$expire = $notBefore + JWT_MAX_LIFE; // 1 hour
|
|
$serverName = WIAAS_URL;
|
|
$data = [
|
|
'iat' => $issuedAt, // Issued at: time when the token was generated
|
|
'jti' => $tokenId, // Json Token Id: an unique identifier for the token
|
|
'iss' => $serverName, // Issuer
|
|
'nbf' => $notBefore, // Not before
|
|
'exp' => $expire, // Expire
|
|
'data' => $userInfo,
|
|
'type' => 'authorization_token' //Token type
|
|
];
|
|
|
|
$secretKey = base64_decode(JWT_API_SECRET_KEY);
|
|
$jwt = JWT::encode(
|
|
$data,
|
|
$secretKey,
|
|
JWT_ALGORITHM
|
|
);
|
|
|
|
return $jwt;
|
|
}
|
|
|
|
public function getRefreshToken() {
|
|
global $database;
|
|
$sql = "SELECT u.refresh_token
|
|
FROM ".TABLES['users']." u
|
|
WHERE id=".self::$userInfo['wiaas_id_user'];
|
|
$result = $database->fetchResultArray($sql);
|
|
|
|
return isset($result[0]) ? $result[0]['refresh_token'] : false;
|
|
}
|
|
|
|
private static function saveRefreshToken($userInfo, $refreshJwt){
|
|
global $database;
|
|
|
|
$sql = "UPDATE ".TABLES['users']."
|
|
SET refresh_token='$refreshJwt'
|
|
WHERE id=".$userInfo['wiaas_id_user'];
|
|
$query = $database->query($sql);
|
|
|
|
return $database->affectedRows() > 0;
|
|
}
|
|
|
|
private static function generateRefreshToken($userInfo){
|
|
global $user;
|
|
|
|
$tokenId = base64_encode(random_bytes(32));
|
|
$issuedAt = time();
|
|
$notBefore = $issuedAt;
|
|
$expire = $notBefore + (JWT_MAX_LIFE * 2); // 1 hour
|
|
$serverName = WIAAS_URL;
|
|
$data = [
|
|
'iat' => $issuedAt, // Issued at: time when the token was generated
|
|
'jti' => $tokenId, // Json Token Id: an unique identifier for the token
|
|
'iss' => $serverName, // Issuer
|
|
'nbf' => $notBefore, // Not before
|
|
'exp' => $expire, // Expire
|
|
'type' => 'refresh_token', //Token type
|
|
'data' => $userInfo
|
|
];
|
|
|
|
$secretKey = base64_decode(JWT_API_SECRET_KEY);
|
|
$jwt = JWT::encode(
|
|
$data,
|
|
$secretKey,
|
|
JWT_ALGORITHM
|
|
);
|
|
|
|
self::saveRefreshToken($userInfo, $jwt);
|
|
|
|
return $jwt;
|
|
}
|
|
|
|
public function getUserInfo() {
|
|
return self::$userInfo;
|
|
}
|
|
|
|
/**
|
|
* reutnrs if user is logged in
|
|
* @return boolean returns if a user is logged in
|
|
*/
|
|
public static function isLoggedIn(){
|
|
return self::$isLoggedIn;
|
|
}
|
|
|
|
/**
|
|
* login processing
|
|
* @param String $username username
|
|
* @param String $password password
|
|
* @return boolean true if the user is logged in
|
|
*/
|
|
public static function login($username, $password, $withToken = false){
|
|
global $database;
|
|
|
|
$username = $database->escapeValue($username);
|
|
$password = $database->escapeValue($password);
|
|
|
|
if(empty($username) OR empty($password)){
|
|
return ['status' => 'fail', 'errorMessage' => 'INVALID_USERNAME_PASSWORD'];
|
|
}
|
|
|
|
$sql = "SELECT u.id, u.username, u.password, ut.type, ut.id as idUserType, isCompanyAdmin
|
|
FROM ".TABLES['users']." u
|
|
INNER JOIN ".TABLES['rel_user_type']." rel_ut
|
|
ON rel_ut.idUser=u.id
|
|
INNER JOIN ".TABLES['user_types']." ut
|
|
ON ut.id=rel_ut.idType
|
|
WHERE u.username='".$username."'
|
|
LIMIT 1";
|
|
$query = $database->query($sql);
|
|
|
|
if($database->numRows($query) !== 1){
|
|
self::$isLoggedIn = false;
|
|
|
|
return ['status' => 'fail', 'errorMessage' => 'INVALID_USERNAME_PASSWORD'];
|
|
}
|
|
|
|
$row = $database->fetchArray($query);
|
|
if(!password_verify($password, $row['password'])){
|
|
return ['status' => 'fail', 'errorMessage' => 'INVALID_USERNAME_PASSWORD'];
|
|
}
|
|
|
|
$userTypeInfo = self::getUserTypeInfo($row['id'], $row['type']);
|
|
|
|
if(count($userTypeInfo) === 0){
|
|
return ['status' => 'fail', 'errorMessage' => 'invalid user type '.$row['type'].'. Add type in User class or add the user in the correct table!'];
|
|
}
|
|
|
|
self::$userInfo['wiaas_id_user'] = $row['id'];
|
|
self::$userInfo['wiaas_username'] = $row['username'];
|
|
self::$userInfo['wiaas_user_type'] = $row['type'];
|
|
self::$userInfo['wiaas_id_user_type'] = $row['idUserType'];
|
|
self::$userInfo['wiaas_user_full_name'] = $userTypeInfo['fullName'];
|
|
self::$userInfo['wiaas_is_company_admin'] = $row['isCompanyAdmin'] === '1' ? true : false;
|
|
|
|
self::$isLoggedIn = true;
|
|
|
|
if($withToken){
|
|
self::$authToken = self::generateApiToken(self::$userInfo);
|
|
$refreshToken = self::generateRefreshToken(self::$userInfo);
|
|
|
|
return ['status' => 'success', 'accessToken' => self::$authToken, 'refreshToken' => $refreshToken];
|
|
}else{
|
|
$_SESSION['data'] = self::$userInfo;
|
|
|
|
return ['status' => 'success'];
|
|
}
|
|
|
|
}
|
|
|
|
public function refreshToken($refreshToken, $lastActivity){
|
|
$inactivity = time() - (intval($lastActivity) / 1000);
|
|
$maxInactivity = 30 * 60; // 30 minutes
|
|
|
|
if($inactivity > $maxInactivity){//session expires if invactivity is more than 30 minutes
|
|
return ['status' => 'error', 'errorMessage' => 'EXPIRED_SESSION'];
|
|
}
|
|
|
|
if(self::validateAccessToken($refreshToken)){
|
|
self::$authToken = self::generateApiToken(self::$userInfo);
|
|
$refreshToken = self::generateRefreshToken(self::$userInfo);
|
|
|
|
return ['status' => 'success', 'accessToken' => self::$authToken, 'refreshToken' => $refreshToken];
|
|
}
|
|
|
|
return ['status' => 'error', 'errorMessage' => 'INVALID_REFRESH_TOKEN', 'extra' => $this->getErrorMessage()];
|
|
}
|
|
|
|
public static function setLastActivity(){
|
|
$_SESSION['LAST_ACTIVITY'] = time();
|
|
}
|
|
|
|
public static function getLastActivity(){
|
|
return $_SESSION['LAST_ACTIVITY'];
|
|
}
|
|
|
|
/**
|
|
* get extra info for connected user by user type
|
|
* @param Int $idUser id of the user
|
|
* @param string $userType the type of the user
|
|
* @return [Array] retruns an empty array if no info or an array with the info
|
|
*/
|
|
private static function getUserTypeInfo($idUser, $userType){
|
|
global $database;
|
|
|
|
if(!array_key_exists($userType, self::$userTypesTableKeys)){
|
|
return [];
|
|
}
|
|
|
|
$sql = "SELECT info.name AS fullName
|
|
FROM ".TABLES[self::$userTypesTableKeys[$userType]]." info
|
|
WHERE idUser=".$idUser."
|
|
LIMIT 1";
|
|
$query = $database->query($sql);
|
|
|
|
if($database->numRows($query) !== 1){
|
|
return [];
|
|
}
|
|
|
|
$row = $database->fetchArray($query);
|
|
|
|
return $row;
|
|
}
|
|
|
|
public function logout(){
|
|
session_unset();
|
|
session_destroy();
|
|
|
|
header("location:index.php");
|
|
}
|
|
|
|
/**
|
|
* get the logged username
|
|
* @return String Username
|
|
*/
|
|
public function getUser(){
|
|
return isset(self::$userInfo['wiaas_username']) ? self::$userInfo['wiaas_username'] : false;
|
|
}
|
|
|
|
/**
|
|
* get the logged id user
|
|
* @return String id suer
|
|
*/
|
|
public function getUserId(){
|
|
return isset(self::$userInfo['wiaas_id_user']) ? self::$userInfo['wiaas_id_user'] : 0;
|
|
}
|
|
|
|
/**
|
|
* get the logged user full name
|
|
* @return String full name
|
|
*/
|
|
public function getUserFullName(){
|
|
return isset(self::$userInfo['wiaas_user_full_name']) ? self::$userInfo['wiaas_user_full_name'] : false;
|
|
}
|
|
|
|
/**
|
|
* get the user type
|
|
* @return String returns the user type
|
|
*/
|
|
public function getUserType(){
|
|
return isset(self::$userInfo['wiaas_user_type']) ? self::$userInfo['wiaas_user_type'] : false;
|
|
}
|
|
|
|
/**
|
|
* get the user type id
|
|
* @return String returns the user type id
|
|
*/
|
|
public function getIdUserType(){
|
|
return isset(self::$userInfo['wiaas_id_user_type']) ? self::$userInfo['wiaas_id_user_type'] : 0;
|
|
}
|
|
|
|
public function getErrorMessage(){
|
|
return isset(self::$userInfo['errorMessage']) ? self::$userInfo['errorMessage'] : '';
|
|
}
|
|
|
|
|
|
/**
|
|
* checks whether the token from the url provided is valid or not
|
|
* @param String $token the token to check the url for
|
|
* @return String confirmation message
|
|
*/
|
|
public function checkPasswordToken($token) {
|
|
global $database;
|
|
|
|
$sql = "SELECT u.username
|
|
FROM ".TABLES['users']." u
|
|
WHERE u.token='".$database->escapeValue($token)."'
|
|
AND u.tokenTS <= DATE_ADD(u.tokenTS , INTERVAL 5 DAY)";
|
|
|
|
$result = $database->query($sql);
|
|
if($database->numRows($result) !== 1) {
|
|
return 'error';
|
|
}
|
|
|
|
self::$validationUsername = $database->fetchArray($result)['username'];
|
|
|
|
return 'success';
|
|
}
|
|
|
|
/**
|
|
* gets the username of the user that wants to reset the password
|
|
* @return String username
|
|
*/
|
|
public function getSetPasswordUsername() {
|
|
return self::$validationUsername;
|
|
}
|
|
|
|
/**
|
|
* Resets the password for the user with the right token number
|
|
* @param Array $passwords the new and confirmed passwords
|
|
* @return Array with confirmation message
|
|
*/
|
|
public function resetPassword($passwords) {
|
|
global $database;
|
|
$data = [];
|
|
|
|
if(self::$validationUsername) {
|
|
$data = UtilsModel::changePassword($passwords, self::$validationUsername);
|
|
$data['username'] = self::$validationUsername;
|
|
self::$validationUsername = '';
|
|
} else {
|
|
$data['messages'][] = [
|
|
'code' => 'error',
|
|
'message' => 'USER_NOT_SET'
|
|
];
|
|
}
|
|
|
|
return $data;
|
|
}
|
|
|
|
/**
|
|
* generatates a new password for the user given
|
|
* @param String $mail email of the user
|
|
* @return String confirtmation message
|
|
*/
|
|
public static function forgotPassword($mail) {
|
|
global $database;
|
|
$mail = $database->escapeValue($mail);
|
|
$now = new DateTime();
|
|
$now = $now->format('Y-m-d H:i:s');
|
|
$data = [];
|
|
|
|
$sql = "SELECT
|
|
u.username,
|
|
u.mail,
|
|
IF(
|
|
ADDTIME(u.tokenTS, '00:05') > '".$now."',
|
|
0,
|
|
1
|
|
) AS allowPasswordGeneration
|
|
FROM ".TABLES['users']." u
|
|
WHERE mail = '".$mail."'";
|
|
|
|
$userInfo = $database->fetchResultArray($sql);
|
|
|
|
if(count($userInfo) == 0) {
|
|
$data[] = 'NO_USER';
|
|
}
|
|
|
|
foreach ($userInfo as $info) {
|
|
if($info['allowPasswordGeneration'] == 1) {
|
|
$messageData = UtilsModel::generateTokenForUserPassword(json_encode($info));
|
|
|
|
$data[] = 'SIGN_IN';
|
|
} else {
|
|
$data[] = 'CHANGE_LATER';
|
|
}
|
|
}
|
|
|
|
return $data;
|
|
}
|
|
}
|