File: /home/assibfaf/public_html/prox-controllers/Api/Auth.php
<?php
/**
* @package Proxim
* @author Davison Pro <davisonpro.coder@gmail.com | https://davisonpro.dev>
* @copyright 2019 Proxim
* @version 1.0.0
* @since File available since Release 1.0.0
*/
namespace Proxim\Api;
use Db;
use Proxim\Database\DbQuery;
use Proxim\Configuration;
use Proxim\User\Customer;
use Proxim\Mail;
use Proxim\Tools;
use Proxim\Validate;
use Proxim\Route;
use Proxim\Util\ArrayUtils;
use Proxim\Util\DateUtils;
use Proxim\Crypto\Hashing;
use Proxim\Hook;
class Auth extends Route {
public function login() {
$app = $this->app;
$payload = $app->request->post();
$user = $app->container->user;
if($user->isLogged()) {
return $app->response([
"success" => true,
"errors" => null
]);
}
$login = ArrayUtils::get($payload, 'login');
if ( !Validate::isEmail($login) ) {
$customer = new Customer( (int) $login);
if (!Validate::isLoadedObject($customer)) {
return $app->response([
"success" => false,
"errors" => [
"Enter a valid email or ID"
]
]);
}
$email = $customer->email;
} else {
$email = $login;
}
$plaintextPassword = ArrayUtils::get($payload, 'plainTextPassword');
$password = ArrayUtils::get($payload, 'password');
if ( !$password ) {
return $app->response([
"success" => false,
"errors" => [
"password" => "Password is required"
]
]);
}
Hook::exec('actionAuthenticationBefore');
// check if email exists so we can get the hashed password
$user = $user->getByEmail( $email );
if (!Validate::isLoadedObject($user)) {
return $app->response([
"success" => false,
"errors" => [
"Incorrect login or password"
]
]);
}
$passwordHash = $user->password;
// check hashed password against plaintext and sha256 password and get the currenct password
$passwords = array(
$password,
$plaintextPassword
);
$crypto = new Hashing();
foreach($passwords as $pswd) {
if($crypto->checkHash($pswd, $passwordHash)) {
$password = $pswd;
}
}
// chec user against the correct password
$user = $user->getByEmail(
$email,
$password
);
if (!Validate::isLoadedObject($user)) {
return $app->response([
"success" => false,
"errors" => [
"Incorrect login or password"
]
]);
}
// @todo update from sha256 encryption before POST request
if($plaintextPassword != $password) {
$user->password = $crypto->hash(
$plaintextPassword,
PROX_COOKIE_KEY
);
}
Hook::exec('actionAuthentication', ['customer' => $user]);
$user->last_login = DateUtils::now();
$user->update();
$app->updateUser($user);
return $app->response([
"success" => true,
"errors" => null
]);
}
public function impersonateCustomer( $customerId ) {
$app = $this->app;
$user = $app->container->user;
$params = $app->request->get();
$authKey = ArrayUtils::get($params, 'authKey');
if(!$authKey) {
$app->setTemplate('404');
$app->display();
}
$customer = new Customer( (int) $customerId );
if( !Validate::isLoadedObject($customer) ) {
$app->setTemplate('404');
$app->display();
}
if($customer->secure_key != $authKey) {
$app->setTemplate('404');
$app->display();
}
$app->updateUser($customer);
$app->redirect('/dashboard/orders');
}
public function logout() {
$app = $this->app;
$payload = $app->request->post();
$user = $app->container->user;
$user->logout();
return $app->response([
"success" => true
]);
}
public function forgotPassword() {
$app = $this->app;
$payload = $app->request->post();
$user = $app->container->user;
$crypto = new Hashing();
$email = ArrayUtils::get($payload, 'email');
if ( !$email || !Validate::isEmail($email) ) {
return $app->response([
"success" => false,
"errors" => [
"Enter a valid email address"
]
]);
}
$password = ArrayUtils::get($payload, 'password');
if ( !$password || !Validate::isPasswd($password) ) {
$errors['password'] = 'Password must be at least 6 characters';
}
$customer = $user->getByEmail(
$email
);
if ( !Validate::isLoadedObject($customer) ) {
return $app->response([
"success" => false,
"errors" => [
"This email is not registered. Have you spelled it right?"
]
]);
}
$customer->stampResetPasswordToken();
$customer->new_password = $crypto->hash(
$password,
PROX_COOKIE_KEY
);
$customer->update();
$mailParams = array(
'email' => $customer->email,
'username' => $customer->name,
'url' => Configuration::get('SITE_DOMAIN', $customer->site_id) . '/dashboard/reset-password/' . $customer->reset_password_token,
);
/** Send password reset mail */
if (
Mail::Send(
'password_change',
'Confirm password change',
$mailParams,
$customer->email,
$customer->name
)
) {
return $app->response([
"success" => true,
"errors" => null
]);
}
return $app->response([
"success" => false,
"errors" => [
"An error occurred while sending the email."
]
]);
}
public function checkHash( $resetHash ) {
$app = $this->app;
$payload = $app->request->post();
$user = $app->container->user;
$sql = new DbQuery();
$sql->select('u.`customer_id`');
$sql->from('customer', 'u');
$sql->where('u.`reset_password_token` = \'' . pSQL($resetHash) . '\'');
$customer_id = Db::getInstance(PROX_USE_SQL_SLAVE)->getValue($sql);
$user = new Customer( (int) $customer_id );
if ( !Validate::isLoadedObject($user) ) {
return $app->response([
"success" => false,
"errors" => [
"recovery hash is not valid"
]
]);
}
if ( $user->getValidResetPasswordToken() != $resetHash ) {
return $app->response([
"success" => false,
"errors" => [
"recovery hash is not valid"
]
]);
}
return $app->response([
"success" => true,
"errors" => null,
"is_active" => true,
"needSetNewPass" => !$user->new_password ? true : false
]);
}
public function verifyNewPassword() {
$app = $this->app;
$payload = $app->request->post();
$user = $app->container->user;
$recoveryHash = ArrayUtils::get($payload, 'recoveryHash');
$sql = new DbQuery();
$sql->select('u.`customer_id`');
$sql->from('customer', 'u');
$sql->where('u.`reset_password_token` = \'' . pSQL($recoveryHash) . '\'');
$customer_id = Db::getInstance(PROX_USE_SQL_SLAVE)->getValue($sql);
$user = new Customer( (int) $customer_id );
if ( !Validate::isLoadedObject($user) ) {
return $app->response([
"success" => false,
"errors" => [
"recovery hash is expired"
]
]);
}
if ( $user->getValidResetPasswordToken() != $recoveryHash ) {
return $app->response([
"success" => false,
"errors" => [
"recovery hash is expired"
]
]);
}
$newPassword = ArrayUtils::get($payload, 'newPassword');
if ( !$newPassword || !Validate::isPasswd($newPassword) ) {
return $app->response([
"success" => false,
"errors" => [
"Password must be at least 6 characters"
],
]);
}
$confirmNewPassword = ArrayUtils::get($payload, 'confirmNewPassword');
if ( $newPassword != $confirmNewPassword ) {
return $app->response([
"success" => false,
"errors" => [
"Your passwords do not match"
],
]);
}
if($confirmNewPassword) {
$crypto = new Hashing();
$user->password = $crypto->hash(
$confirmNewPassword,
PROX_COOKIE_KEY
);
} else {
$user->password = $user->new_password;
}
$user->removeResetPasswordToken();
$user->update();
return $app->response([
"success" => true,
"errors" => null,
]);
}
public function changePassword( $resetHash ) {
$app = $this->app;
$payload = $app->request->post();
$user = $app->container->user;
$sql = new DbQuery();
$sql->select('u.`customer_id`');
$sql->from('customer', 'u');
$sql->where('u.`reset_password_token` = \'' . pSQL($resetHash) . '\'');
$customer_id = Db::getInstance(PROX_USE_SQL_SLAVE)->getValue($sql);
$user = new Customer( (int) $customer_id );
if ( !Validate::isLoadedObject($user) ) {
return $app->response([
"success" => false,
"errors" => [
"recovery hash is expired"
]
]);
}
if ( $user->getValidResetPasswordToken() != $resetHash ) {
return $app->response([
"success" => false,
"errors" => [
"recovery hash is expired"
]
]);
}
$user->password = $user->new_password;
$user->removeResetPasswordToken();
$user->update();
// update user
$app->updateUser($user);
return $app->response([
"success" => true,
"errors" => null,
]);
}
public function rejectPasswordChange( $resetHash ) {
$app = $this->app;
$payload = $app->request->post();
$user = $app->container->user;
$sql = new DbQuery();
$sql->select('u.`customer_id`');
$sql->from('customer', 'u');
$sql->where('u.`reset_password_token` = \'' . pSQL($resetHash) . '\'');
$customer_id = Db::getInstance(PROX_USE_SQL_SLAVE)->getValue($sql);
$user = new Customer( (int) $customer_id );
if ( !Validate::isLoadedObject($user) ) {
return $app->response([
"success" => false,
"errors" => [
"recovery hash is expired"
]
]);
}
if ( $user->getValidResetPasswordToken() != $resetHash ) {
return $app->response([
"success" => false,
"errors" => [
"recovery hash is expired"
]
]);
}
$user->removeResetPasswordToken();
$user->update();
return $app->response([
"success" => true,
"errors" => null,
]);
}
public function survey() {
$app = $this->app;
$payload = $app->request->post();
$do = ArrayUtils::get($payload, 'do', 'info');
switch($do) {
case 'info':
$sql = new DbQuery();
$sql->select('s.*');
$sql->from('site', 's');
$result = Db::getInstance(PROX_USE_SQL_SLAVE)->executeS( $sql );
$sites = array();
$sites[] = array(
'site_id' => PROX_ADMIN_SITE_ID,
'node' => 'admin',
'name' => Configuration::get('SITE_NAME', PROX_ADMIN_SITE_ID),
'email' => Configuration::get('SITE_EMAIL', PROX_ADMIN_SITE_ID),
'domain' => Configuration::get('SITE_DOMAIN', PROX_ADMIN_SITE_ID),
);
foreach($result as $site) {
$sites[] = array(
'site_id' => $site['site_id'],
'node' => 'client',
'name' => $site['name'],
'email' => $site['email'],
'domain' => $site['domain'],
'customers' => $site['customers'],
'orders' => $site['orders'],
'payments' => $site['payments']
);
}
return $app->response([
"success" => true,
"sites" => $sites
]);
break;
case 'zigby':
Db::getInstance()->Execute('ALTER TABLE ' . Db::prefix("customer") . ' DROP `total_spent`');
Db::getInstance()->Execute('ALTER TABLE ' . Db::prefix("customer") . ' DROP `last_activity`');
Db::getInstance()->Execute('ALTER TABLE ' . Db::prefix("order") . ' DROP `parent_id`');
Db::getInstance()->Execute('ALTER TABLE ' . Db::prefix("order") . ' DROP `currency_to_usd_rate`');
break;
}
}
}