<?php
namespace App\Controller;
use Imperium\Config\iConfig;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Imperium\StaticUtils\Utils as Utils;
use Ramsey\Uuid\Uuid;
use Symfony\Component\HttpFoundation\JsonResponse;
use Imperium\InterfaceData\imp_emails\Emails;
use Imperium\InterfaceData\imperium\Ip_Comptes as httpIp_Comptes;
use Imperium\AppsApi\Utils\Utils as ApiUtils;
use Imperium\AppsApi\Auth\Lecture as ApiAuth;
use App\Entity\User;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Imperium\InterfaceToken\userToken;
use Imperium\InterfaceToken\cookieToken;
class AuthController extends AbstractController
{
private $session;
protected $tokenStorage;
public function __construct(SessionInterface $session,TokenStorageInterface $tokenStorage)
{
iConfig::initConfig();
$this->tokenStorage = $tokenStorage;
$this->session = $session;
}
public function get_signin(Request $request)
{
$params = [];
// if(isset($_SESSION['users'])) unset($_SESSION['users']);
// unset the callback session if it is set
if(isset($_SESSION['callback'])) unset($_SESSION['callback']);
if(isset($_SESSION['callback_signin'])) unset($_SESSION['callback_signin']);
// if callback is set in the query it is registred for further use when the user is authenticated
if($request->query->has('callback')){
$callback = $request->get('callback');
// Output the domain
$_SESSION['callback'] = $callback;
$_SESSION['callback_signin'] = $callback;
}
// if User sessions is allerady set TAB listACCounts is activated
if(isset($_SESSION['users']) && count($_SESSION['users'])){
$params['TAB'] = "list_accounts";
}
// if the user is redirected to reset his password
if($request->query->has('reset_password') && $request->query->has('token') && $request->query->get('token') != "" && $request->query->get('reset_password') == "true"){
$response = ApiAuth::verifyToken(['token'=>$request->query->get('token')]);
if($response->status == 200){
if(isset($_SESSION['reset_password'])) unset($_SESSION['reset_password']);
$_SESSION['reset_password'] = [
"IdCompte" => $response->payload->compteid,
"Email" => $response->payload->email,
"ExpireIn" => time() + 300
];
// $res = ApiAuth::revokeToken(['token'=>$request->query->get('token'),"revoked_by"=>$response->payload->compteid]);
$params['TAB'] = "resetpass_password";
}else{
return $this->render('error/409.html.twig');
}
}
return $this->render('auth/login.html.twig',$params);
}
public function signin_email(Request $request)
{
$validators = [];
if( !$request->request->has('email') || empty($request->get('email'))){
$validators['email'] = "Email is requireds";
}
if(count($validators)>0){
throw (new JsonResponse(['code'=>'error','status'=>422,"title" => "Confirmation Erreur","message"=>"The data provided was invalid","data"=>$validators],422))->send();
}
$email = $request->get('email');
$body["args"] = [
"email" => $email
];
$compte = ApiAuth::getCompteByEmail($body);
// Verify email From Register Section
if($request->request->has('register') && $compte->compte != null){
return new JsonResponse(["status" => 422 , "code" => "error" , "message" => "Compte existe deja"],422);
}else if( $request->request->has('register') && $compte->compte == null){
return new JsonResponse(["status" => 200 , "code" => "success"]);
}
// Verify email For Login Section
if($compte->compte != null && !$request->request->has('register')){
$authMethodes = [];
if($compte->compte->Ip_Comptes->AuthPwd != null){
$authMethodes['password'] = true;
}
if($compte->compte->Ip_Comptes->AuthFactors != null){
$authMethodes['twofa'] = $compte->compte->Ip_Comptes->AuthFactors->Code;
}
return new JsonResponse(["status" => 200 , "code" => "success" , "data" => [
"X_NOM" => $compte->compte->Conso_Perso->X_NOM,
"X_PRENOM" => $compte->compte->Conso_Perso->X_PRENOM,
"authMethodes" => $authMethodes,
]]);
}
return new JsonResponse(["status" => 404 , "code" => "error" , "message" => "Compte n'existe pas"],404);
}
public function signin_account(Request $request)
{
$validators = [];
if( (!$request->request->has('password') || empty($request->get('password')) ) && ( !$request->request->has('otp') || empty($request->get('otp'))) ){
$validators['password'] = "otp or password is requireds";
}
if( !$request->request->has('email') || empty($request->get('email'))){
$validators['fields'] = "some fields is requireds";
}
if(count($validators)>0){
// return new JsonResponse(['code'=>'error','status'=>422,"message"=>"The data provided was invalid","data"=>$validators],422);
throw (new JsonResponse(['code'=>'error','status'=>422,"title" => "Confirmation Erreur","message"=>"The data provided was invalid","data"=>$validators],422))->send();
}
$email = $request->get('email');
$body["args"] = [
"email" => $email
];
$compte = ApiAuth::getCompteByEmail($body);
// Verify email For Login Section
if($compte->compte != null){
if($compte->compte->Ip_Comptes->Validite == 0){
$params=[];
$IdCompte=Utils::CryptNum($compte->compte->Ip_Comptes->IdCompte);
$params["IdCompte"]=$IdCompte;
$params['message'] = "Veuillez vérifier la boîte e-mail pour activer votre compte";
throw (new JsonResponse(['code'=>'error','status'=>422,"message"=>"Compte Invalide","data"=>$params],200))->send();
}
}
$params = [];
$params['username'] = $request->get('email');
$params['password'] = $request->get('password');
$params['otp'] = $request->get('otp');
$params['expiresAfter'] = 864000;
$response = ApiAuth::usersSignin($params);
if( isset($response->token) ){
$compte = ApiAuth::usersVerify(['token'=>$response->token,"revoke"=>false]);
if( $compte->status == 401 ){
return new JsonResponse(['status'=>401,"code"=>"unauthorized","title"=>"unauthorized","message"=>"unauthorized"],401);
}
$data_session = [];
$data_session['user'] = $compte->user;
$data_session['uuid'] = Uuid::uuid4()->toString();
$data_session['session'] = (object) [
'token'=>$response->token,
'agent'=>$_SERVER['HTTP_USER_AGENT']
];
if( !isset($_SESSION['users']) ){
$_SESSION['users'] = [];
array_push($_SESSION['users'],$data_session);
}else{
$user = array_column($_SESSION['users'],"user");
$ids = array_column($user,"id");
$search_in_array = array_search($compte->user->id, $ids);
if( $search_in_array === false ){
array_push($_SESSION['users'],$data_session);
}else{
// Token renewal
$_SESSION['users'][$search_in_array]['session']->token = $response->token;
}
}
if( $this->session->get('user') == null ){
self::loadSession($compte->user->id,$params['username'],$params['password'],$this,$request);
}
$session = [
'X_NOM'=>$this->session->get('user')->X_NOM,
'X_PRENOM'=>$this->session->get('user')->X_PRENOM,
'IdCompte'=>Utils::DecryptJWT([
'secret_key' => iConfig::getCryptSecretKey(),
'secret_iv' => iConfig::getCryptSecretIv(),
'text' => $this->session->get('user')->IdCompte
]),
'pic_profile'=>$this->session->get('user')->pic_profile
];
$data = Utils::recursiveCryptingJWT("cryptJWT",['id'],$_SESSION['users']);
$data = [];
$response = ApiAuth::usersSignin(['token'=>$response->token,"expiresAfter"=>864000]);
$token = $response->token;
if(isset($_SESSION['callback_signin'])){
$callback_signin = $_SESSION['callback_signin'];
if( strpos($callback_signin, "?") !== false ){
$data["redirect"] = $callback_signin . "&token=" . $token;
}else{
$data["redirect"] = $callback_signin . "?token=" . $token;
}
unset($_SESSION['callback']);
unset($_SESSION['callback_signin']);
}
$data["token"] = $token;
return new JsonResponse(["status" => 200 , "code" => "success" , "message" => "Connected Suscessfully" ,"data" => $data,"session"=>$session]);
}
if($params['password']!= "") $messageError = "Password is incorrect";
if($params['otp']!= "") $messageError = "otp is incorrect";
if($response->status == 401){
// $messageError = "Email is Blocked";
if($response->code == "credentials_invalid"){
$messageError = "Email or Password is incorrect";
}
if($response->code == "email_blocked"){
$messageError = "Email is blocked";
}
if($response->code == "email_disabled"){
$messageError = "Email is disabled";
}
}
return new JsonResponse(["status" => 404 , "code" => "error" , "message" => $messageError],404);
}
public function send_relance(Request $request)
{
$IdCompte = $request->get('IdCompte');
$password = $request->get('password');
$email = $request->get('email');
$first_Emails = (new Emails())->first(["EMAIL"=>$email]);
if($first_Emails){
$body["args"] = [
"IdEmail" =>$first_Emails->IDEMAIL,
];
$body["operatedBy"] = Utils::DCryptNum($IdCompte);
$response = ApiAuth::sendRelance($body);
if($response->status == 200){
return new JsonResponse(["status" => 200 , "code" => "success" , "message" => " bien renvoyer "]);
}
if($response->status == 422){
return new JsonResponse(["status" => 422 , "code" => "error" , "message" => $response->message],422);
}
}
return new JsonResponse(["status" => 500 , "code" => "error" , "message" => "unknown error please try again"],500);
}
public function get_list_accounts(Request $request)
{
if(isset($_SESSION['users']) && count($_SESSION['users'])){
return new JsonResponse(["status" => 200 , "code" => "success" , "message" => "List Accounts" , "data" => $_SESSION['users']]);
}
return new JsonResponse(["status" => 404 , "code" => "error" , "message" => "List Accounts introuvable"]);
}
public function connect_with_registred_account(Request $request)
{
$validators = [];
if( !$request->request->has('uuid') || empty($request->get('uuid'))){
$validators['uuid'] = "the uuid field is mandatory";
}
if(count($validators)>0){
throw (new JsonResponse(['code'=>'error','status'=>422,"message"=>"The data provided was invalid","data"=>$validators],422))->send();
}
$uuid = $request->get('uuid');
$ids = isset($_SESSION['users']) ? array_column($_SESSION['users'],"uuid") :[];
$search_in_array = array_search($uuid, $ids);
$http_user_agent = $_SERVER['HTTP_USER_AGENT'];
if( $search_in_array !== false ){
$token = $_SESSION['users'][$search_in_array]['session']->token;
$agent_session = $_SESSION['users'][$search_in_array]['session']->agent;
$compte = ApiAuth::usersVerify(['token'=>$token,"revoke"=>false]);
$user = Utils::recursiveCryptingJWT("cryptJWT",['id'],$_SESSION['users'][$search_in_array]);
if( $compte->status == 401 ){
return new JsonResponse(['status'=>401,"code"=>"unauthorized","title"=>"unauthorized","message"=>"unauthorized","data"=>[
"email" => $user["user"]->username
]],401);
}
$data = Utils::recursiveCryptingJWT("cryptJWT",['id'],$_SESSION['users']);
if( $agent_session == $http_user_agent ){
// Todo create new token in order to login in app by token account
$response = ApiAuth::usersSignin(['token'=>$token,"expiresAfter"=>864000]);
$token = $response->token;
if( empty($token) || $token == "" ){
throw (new JsonResponse(['code'=>'error','status'=>422,"message"=>"unknown error please try again","data"=>$validators],422))->send();
}
$json_response = ['status'=>200,"code"=>"success","message"=>"success","data"=>$data,'token'=>$token];
if( isset( $_SESSION['callback_signin'] ) ) {
$host_params = "token=$token";
if( strpos($_SESSION['callback_signin'], "?") !== false ){
$json_response['redirect'] = $_SESSION['callback_signin']."&$host_params";
}else{
$json_response['redirect'] = $_SESSION['callback_signin']."?$host_params";
}
unset($_SESSION['callback']);
unset($_SESSION['callback_signin']);
}
return new JsonResponse($json_response);
}else{
return new JsonResponse(['status'=>1003,"code"=>"http_user_agent","title"=>"agent","message"=>"agent","data"=>[
"email" => $user["user"]->username
]]);
}
}else{
return new JsonResponse(['status'=>401,"code"=>"unauthorized",
"title"=>"Session Expired",
"message"=>"Session Expired"],401);
}
}
public function register_account(Request $request)
{
$validators = [];
$birthday = null;
if( $request->request->has('day') && !empty($request->get('day'))
&& $request->request->has('month') || !empty($request->get('month'))
&& $request->request->has('year') || !empty($request->get('year')) ){
$birthday = $request->get('year')."-".$request->get('month')."-".$request->get('day');
}
$phone = null;
$telMode = null;
$ville = null;
$langue = null;
if( $request->request->has('ville') && !empty($request->get('ville'))){
$ville = Utils::DCryptNum($request->get('ville'));
}
if($request->request->has('langue') && !empty($request->get('langue'))){
$langue = Utils::DCryptNum($request->get('langue'));
}
if( $request->request->has('phone') && !empty($request->get('phone')) && $request->request->has('tel_mode') || !empty($request->get('tel_mode')) ){
$phone = $request->get('phone');
$telMode = Utils::DCryptNum($request->get('tel_mode'));
}
$fields = ['email','prenom','nom','password','pays'];
foreach ($fields as $key => $field) {
if( !$request->request->has($field) || empty($request->get($field)) ){
$validators[$field] = "The $field is required";
}
}
if(count($validators)>0){
throw (new JsonResponse(['code'=>'error','status'=>422,"message"=>"The data provided was invalid","data"=>$validators],422))->send();
}
$compte = [];
$compte['email'] = $request->get('email');
$compte['firstName'] = $request->get('prenom');
$compte['lastName'] = $request->get('nom');
$compte['password'] = $request->get('password');
$compte['country'] = Utils::DCryptNum($request->get('pays'));
$compte['city'] = $ville;
$compte['language'] = $langue;
$compte['birthday'] = $birthday;
$compte['verificationMode'] = "email";
$tel_code = $telMode;
if($tel_code != null){
$pays = ApiUtils::GetPays(["query"=>["NumPays"=>$tel_code]]);
$pays = reset($pays);
$compte['phone'] = $pays->TELCode.$request->get('phone');
}
$response = ApiAuth::createCompte($compte);
if($response->status == 200){
return new JsonResponse(['code'=>'success','status'=>200,"message"=>"Registred successfully"],200);
}
return new JsonResponse(['code'=>'error','status'=>500,"message"=>"Some thing went wrong"],500);
}
public function verify_account(Request $request)
{
$validators = [];
if( !$request->request->has('type') ){
$validators['type'] = "The type verification is required";
}
if(count($validators)>0){
throw (new JsonResponse(['code'=>'error','status'=>422,"message"=>"The data provided was invalid","data"=>$validators],422))->send();
}
$type = $request->get("type");
if(in_array($type,["email","email_otp"]) && $request->request->has("email")){
$args = [];
$args['args']['email'] = $request->get('email');
// $args['args']['email'] = "laatarsisalaheddine1@gmail.com"; // TODO : remove this line
$args['args']['IdCompte'] = crc32($args['args']['email']);
$response = ApiAuth::generateEmailOtp($args);
if($response->status == 200){
if(isset($_SESSION['otp'])) unset($_SESSION['otp']);
$_SESSION['otp'] = $response->data->otp;
return new JsonResponse(['code'=>'success','status'=>200,"message"=>"OTP sent successfully","data"=>["type"=>$type]],200);
}
}
return new JsonResponse(['code'=>'error','status'=>404,"message"=>"Invalid request"],404);
}
public function validate_account(Request $request)
{
$validators = [];
if( !isset($_SESSION['otp']) || !$request->request->has('otp') ){
$validators['otp'] = "The otp is required";
}
if( isset($_SESSION['otp']) && $request->get('otp') != $_SESSION['otp'] ){
$validators['otp'] = "The OTP Provided is not valid";
}
if(count($validators)>0){
throw (new JsonResponse(['code'=>'error','status'=>422,"message"=>"The data provided was invalid","data"=>$validators],422))->send();
}
return new JsonResponse(['code'=>'success','status'=>200,"message"=>"Validated successfully"],200);
}
public function send_password_reset(Request $request)
{
$validators = [];
if( !$request->request->has('email') || empty($request->get('email'))){
$validators['email'] = "Email is requireds";
}
if(count($validators)>0){
throw (new JsonResponse(['code'=>'error','status'=>422,"title" => "Confirmation Erreur","message"=>"The data provided was invalid","data"=>$validators],422))->send();
}
$email = $request->get('email');
$body["args"] = [
"email" => $email
];
$compte = ApiAuth::getCompteByEmail($body);
if( $compte->compte != null ){
$body["args"] = [
"Email" => $email
];
$body["channels"] = ["mail"];
$response = ApiAuth::reqResetPassword($body);
if($response->status == 200){
return new JsonResponse(['code'=>'success','status'=>200,"message"=>"Email sent successfully"],200);
}
return new JsonResponse(["status" => 500 , "code" => "error" , "message" => "Some thing went wrong"],500);
}
return new JsonResponse(["status" => 404 , "code" => "error" , "message" => "Compte n'existe pas"],404);
}
public function submit_password_reset(Request $request)
{
if(!isset($_SESSION['reset_password']) && $_SESSION['reset_password']["ExpireIn"] < time()){
return new JsonResponse(["status" => 401 , "code" => "error" , "message" => "Operation Expired"],401);
}
$password = $request->get('password');
$IdCompte = $_SESSION['reset_password']['IdCompte'];
$body["args"] = [
"IdCompte" => $IdCompte,
"newPassword" => $password
];
$body["channels"] = ["mail"];
$response = ApiAuth::resetPassword($body);
if($response->status == 200){
// dd($request->get('token'));
$res = ApiAuth::revokeToken(['token'=>$request->get('token'),"revoked_by"=>$IdCompte]);
return new JsonResponse(["status" => 200 , "code" => "success" , "message" => "Password changed successfuly"],200);
}
return new JsonResponse(["status" => 500 , "code" => "error" , "message" => "some thing went wrong"],500);
}
public function get_compte_connect(Request $request)
{
$session = [];
if( $this->session->get('user') != null ){
$session = [
'X_NOM'=>$this->session->get('user')->X_NOM,
'X_PRENOM'=>$this->session->get('user')->X_PRENOM,
'IdCompte'=>Utils::DecryptJWT([
'secret_key' => iConfig::getCryptSecretKey(),
'secret_iv' => iConfig::getCryptSecretIv(),
'text' => $this->session->get('user')->IdCompte
]),
'pic_profile'=>$this->session->get('user')->pic_profile
];
}
return new JsonResponse(["status" => 200 , "code" => "success" , "message" => "Compte Connected","session"=>$session]);
}
public function switch_compte(Request $request)
{
$validators = [];
$validators = [];
if( !$request->request->has('password') || empty($request->get('password')) ){
$validators['password'] = "otp or password is requireds";
}
if( !$request->request->has('email') || empty($request->get('email'))){
$validators['fields'] = "some fields is requireds";
}
if(count($validators)>0){
// return new JsonResponse(['code'=>'error','status'=>422,"message"=>"The data provided was invalid","data"=>$validators],422);
throw (new JsonResponse(['code'=>'error','status'=>422,"title" => "Confirmation Erreur","message"=>"The data provided was invalid","data"=>$validators],422))->send();
}
$params = [];
$params['username'] = $request->get('email');
$params['password'] = $request->get('password');
$params['expiresAfter'] = 864000;
$response = ApiAuth::usersSignin($params);
if( isset($response->token) ){
$compte = ApiAuth::usersVerify(['token'=>$response->token,"revoke"=>false]);
self::loadSession($compte->user->id,$params['username'],$params['password'],$this,$request);
$session = [
'X_NOM'=>$this->session->get('user')->X_NOM,
'X_PRENOM'=>$this->session->get('user')->X_PRENOM,
'IdCompte'=>$this->session->get('user')->IdCompte,
'pic_profile'=>$this->session->get('user')->pic_profile
];
$json_response = ['status'=>200,"code"=>"success","message"=>"compte switched","session"=>$session];
return new JsonResponse($json_response);
}
return new JsonResponse(["status" => 404 , "code" => "error" , "message" => "username or password incorrect"],404);
}
public function disconnect_compte(Request $request)
{
$connectedUser = $this->session->get('user');
// matcherd user from users
$user = array_filter($_SESSION['users'] , function($object) use ($connectedUser){
if( $connectedUser->IdCompte == $object["user"]->id){
return $object;
}
});
$index = array_keys($user);
// remove user from users session
unset($_SESSION['users'][$index[0]]);
$_SESSION['users'] = array_values($_SESSION['users']);
$user = reset($user);
$data["user_uuid"] = $user["uuid"];
$this->session->remove('user');
$this->tokenStorage->setToken(null);
return new JsonResponse(["status" => 200 , "code" => "success" , "message" => "Compte Disconnected" , "data" => $data],200);
}
protected static function loadSession($IdCompte,$identifiant,$password,$current,$request)
{
$current->tokenStorage->setToken(null);
// $request->getSession()->invalidate();
$compte = ApiAuth::compteDetail($IdCompte);
$current->session->set('user', $compte->data->compte );
$current->session->set('compteid', $compte->data->compte->IdCompte );
$current->session->set('user_image', $compte->data->compte->pic_profile);
$user = new User();
$user->setId($compte->data->compte->IdCompte);
$user->setUserName($compte->data->compte->X_NOM.' '.$compte->data->compte->X_PRENOM);
$user->setEmail($identifiant);
$user->setFirstName($compte->data->compte->X_PRENOM);
$user->setLastName($compte->data->compte->X_NOM);
$user->setUserImage($compte->data->compte->pic_profile);
$user->setRoles(['ROLE_ADMIN']);
//Create session for symfony
$token = new UsernamePasswordToken($user, null, 'main', ['ROLE_ADMIN']);
$current->tokenStorage->setToken($token);
$request->getSession()->set('_security_main', serialize($token));
$dispatcher = new EventDispatcher();
$event = new InteractiveLoginEvent($request, $token);
$dispatcher->dispatch($event);
try {
//generate user token
$uToken = new userToken(null,$current->session);
$userToken = $uToken->authenticate($identifiant, $password);
} catch ( \Exception $th) {
error_log( $th->getMessage() , 0);
}
// try {
// // must check $userToken->status == 200 before continue
// //push cookie
// $cToken = new cookieToken(null,$current->session);
// $cToken->user_token = $userToken->token;
// $cToken->set('lastName',$compte->data->compte->X_NOM);
// $cToken->set('firstName',$compte->data->compte->X_PRENOM);
// $cToken->push();
// } catch ( \Exception $th) {
// error_log( $th->getMessage() , 0);
// }
//test if request is xhr
if ($request->isXmlHttpRequest()){
return new JsonResponse(['message' => 'authenticated' , 'code' => 'authenticated' , 'status' => 200], 200);
}
}
public function get_apps(Request $request)
{
try {
$body=[];
$results = ApiUtils::GetApps($body);
$results = Utils::recursiveCryptingJWT('cryptJWT',
["ClientId", "IdApps", "IdAppsCat", "IdAppsParent", "IdEse", "IdServerSmtpIn", "IdServerSmtpOut"],$results);
return new JsonResponse($results);
} catch (Exception $e) {
return new JsonResponse(['error' => $e->getMessage()], 400);
}
}
}