| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403 |
- <?php
- namespace App\Http\Controllers;
- use Illuminate\Http\Request;
- use Illuminate\Support\Facades\Validator;
- use Illuminate\Support\Facades\DB;
- use Illuminate\Support\Facades\Hash;
- use Illuminate\Support\Carbon;
- use Firebase\JWT\JWT;
- use Firebase\JWT\Key;
- use Exception;
- use PDOException;
- use Jenssegers\Agent\Agent;
- use ElephantIO\Client;
- class LoginController extends Controller{
- private $responseController;
- private $encryptionController;
- private $functionsController;
- private $secretKey = "ydl27x22cNsNY0z6o3Fr6XZoUvsX0QMZx6MaiwN+KCnM6APS4Xbb7GDfudOYD5uD/r8TzQElh4d4HIal5Os0XA==";
- private $publicKey = "zOgD0uF22+xg37nTmA+bg/6/E80BJYeHeByGpeTrNFw=";
- public function __construct(){
- $this->responseController = new ResponseController();
- $this->encryptionController = new EncryptionController();
- $this->functionsController = new FunctionsController;
- }
- private function getSocketClient(){
- $url = 'http://localhost:3200';
- $socketClient = new Client(Client::engine(Client::CLIENT_4X, $url));
- $socketClient->initialize();
- $socketClient->of('/');
- return $socketClient;
- }
- public function login(Request $request){
- DB::enableQueryLog();
- $validator = Validator::make($request->all(), [
- 'email' => 'required|string|email',
- 'password' => 'required|string',
- 'linea' => 'required|integer|max: 2',
- 'latitude' => 'required|numeric|between:-90,90',
- 'longitude' => 'required|numeric|between:-180,180',
- 'accuracy' => 'required|numeric|between:0,1000000',
- 'city' => 'string|max:100',
- 'state' => 'string|max:100',
- 'country' => 'required|string|max:50',
- ]);
- if($validator->fails()){
- return $this->responseController->makeResponse(
- true,
- "Se encontraron uno o más errores.",
- $this->responseController->makeErrors(
- $validator->errors()->messages()
- ),
- 401
- );
- }
- $login = $request->all();
- //Se obtiene la dirección IP de la solicitud
- $ipv = $request->ip();
- $v4 = filter_var($ipv, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) ? true : false;
- //Se obtiene el dispositivo utilizado
- $agent = new Agent();
- $device = 'Desconocido';
- if($agent->isDesktop()) $device = 'PC';
- else if($agent->device()) $device = $agent->device();
- //Se obtiene el SO utilizado y la versión del mismo
- $platform = $agent->platform() ? $agent->platform() : 'Desconocido';
- $version = 'N/A';
- if($platform != 'Desconocido') $version = $agent->version($platform);
- //Se obtiene el navegador web utilizado
- $browser = $agent->browser() ? $agent->browser() : 'Desconocido';
- //Se consulta el correo electrónico enviado
- $usr = DB::table('S002V01TUSUA')->where([
- ['USUA_COEL', '=', $login['email']],
- ['USUA_NULI', '=', $login['linea']]
- ])->first();
- if(is_null($usr)){
- return $this->responseController->makeResponse(true, "El correo electrónico no está registrado.", [], 404);
- }else if($usr->USUA_ESTA != 'Activo'){
- $statusStr = strtolower($usr->USUA_ESTA);
- return $this->responseController->makeResponse(true, "El usuario se encuentra $statusStr, por favor contacte al administrador para solucionarlo.", [], 401);
- }
-
- $now = $this->functionsController->now();
- $nowStr = $now->toDateTimeString();
- $contra = $login['password'];
- $contra = $this->encryptionController->decrypt($contra);
- if(!$contra){
- return $this->responseController->makeResponse(true, 'La contraseña no fue encriptada correctamente.', [], 400);
- }
-
- $usrContra = $usr->USUA_CONT;
- if(!Hash::check($contra, $usrContra)){
- $attempts = $usr->USUA_ININ + 1;
- $status = $attempts >= 10 ? 'Inactivo' : 'Activo';
- DB::table('S002V01TUSUA')->where('USUA_IDUS', '=', $usr->USUA_IDUS)->update([
- "USUA_ININ" => $attempts,
- "USUA_ESTA" => $status
- ]);
- return $this->responseController->makeResponse(true, "La contraseña es incorrecta, intento $attempts de 10.", [], 401);
- }
- $controlPanel = DB::table('S002V01TPACO')->where([
- ['PACO_NULI', '=', $login['linea']],
- ['PACO_IDPC', '=', $usr->USUA_PCRE]
- ])->first();
- DB::table('S002V01TUSUA')->where('USUA_IDUS', '=', $usr->USUA_IDUS)->update([
- "USUA_ININ" => 0,
- "USUA_ESTA" => 'Activo'
- ]);
- $politicsInfoRoute = str_replace("app\Http\Controllers", "", __DIR__);
- $politicsInfoRoute .= "storage\\app\\files\\security-politics.json";
- $politicsExists = file_exists($politicsInfoRoute);
- if(!$politicsExists){
- return $this->responseController->makeResponse(true, 'El archivo de políticas de seguridad no fue encontrado.', [], 404);
- }
-
- $politicsStr = file_get_contents($politicsInfoRoute);
- $politicsArr = json_decode($politicsStr, true);
- if(!array_key_exists('sessions_duration', $politicsArr)){
- return $this->responseController->makeResponse(true, 'La configuración de duración de sesiones no existe.', [], 404);
- }
- $sessionDurationConfig = $politicsArr['sessions_duration'];
- $cadDate = new Carbon($nowStr);
- $cadDate->addDays($sessionDurationConfig['days']);
- $cadDate->addHours($sessionDurationConfig['hours']);
- $cadDate->addMinutes($sessionDurationConfig['minutes']);
- $cadDate->addSeconds($sessionDurationConfig['seconds']);
- $iat = $now->timestamp;
- $cad = $cadDate->timestamp;
- $state = isset($login['state']) ? $login['state'] : '-';
- $ulco = DB::table('S002V01TBIAC')->insertGetId([
- 'BIAC_NULI' => $login['linea'],
- 'BIAC_IDUS' => $usr->USUA_IDUS,
- 'BIAC_FECO' => $nowStr,
- 'BIAC_IPV4' => $v4 ? $ipv : null,
- 'BIAC_IPV6' => !$v4 ? $ipv : null,
- 'BIAC_LATI' => $login['latitude'],
- 'BIAC_LONG' => $login['longitude'],
- 'BIAC_PREC' => $login['accuracy'],
- 'BIAC_CIUD' => $login['city'],
- 'BIAC_ESTA' => $state,
- 'BIAC_PAIS' => $login['country'],
- 'BIAC_DISP' => $device,
- 'BIAC_SIOP' => $platform,
- 'BIAC_VSOP' => $version,
- 'BIAC_NAVE' => $browser,
- ]);
- DB::table('S002V01TUSUA')->where([
- ['USUA_COEL', '=', $login['email']],
- ['USUA_NULI', '=', $login['linea']]
- ])->update(['USUA_ULCO' => $ulco]);
- //Antes de crear el token revisamos los permisos de su perfil
- $profile = DB::table('S002V01TPERF')->where([
- ['PERF_IDPE', '=', $usr->USUA_PERF],
- ['PERF_NULI', '=', $login['linea']]
- ])->get()->first();
- $permissions = $this->encryptionController->encrypt($profile->PERF_PERM);
- $payload = [
- "iss" => $login['email'],
- "aud" => "dominio.syp.mx",
- "iat" => $iat,
- "cad" => $cad
- ];
- $token = JWT::encode($payload, $this->secretKey, 'EdDSA');
- if(!array_key_exists('active_sessions_number', $politicsArr)){
- return $this->responseController->makeResponse(true, 'La configuración de sesiones máximas no existe.', [], 404);
- }
- $idUserInt = intval($usr->USUA_IDUS);
- if($idUserInt > 0){
- $this->getSocketClient()->emit('get_sessions', []);
- if($packet = $this->getSocketClient()->wait('new_session_saved')){
- $maxSessions = $politicsArr['active_sessions_number'];
- $dataStr = $packet->data;
- $dataArr = json_decode($dataStr, true);
- $sessionsCount = 0;
- foreach($dataArr as $session){
- $sessionUser = $this->encryptionController->decrypt($session['user']);
- if($sessionUser == $usr->USUA_IDUS){
- $sessionsCount++;
- }
- }
- if($sessionsCount >= $maxSessions){
- return $this->responseController->makeResponse(true, 'Número máximo de sesiones alcanzado.', [], 401);
- }
- }
- }
- //Antes de realizar el return obtenemos todos los querys ejecutados en esta consulta
- $querys = DB::getQueryLog();
- $name = $this->functionsController->joinName($usr->USUA_NOMB, $usr->USUA_APPA, $usr->USUA_APMA);
- //Se registra la acción realizada
- $idac = $this->functionsController->registerActivity(
- $login['linea'],
- 'LOGIN',
- '-',
- '-',
- 'Registro',
- "El usuario $name (" . $usr->USUA_IDUS . ") inició sesión.",
- $usr->USUA_IDUS,
- $nowStr
- );
- $this->functionsController->registerLog($querys, $usr->USUA_IDUS, $nowStr, $idac, $login['linea']);
- return $this->responseController->makeResponse(false, "EXITO.", [
- "IDUSUARIO" => $this->encryptionController->encrypt($usr->USUA_IDUS),
- "NOMBREUSUARIO" => $this->encryptionController->encrypt($usr->USUA_NOMB),
- "CORREO" => $this->encryptionController->encrypt($usr->USUA_COEL),
- "PERFIL" => $this->encryptionController->encrypt($usr->USUA_PERF),
- "PANEL" => isset($controlPanel) ? $this->encryptionController->encrypt($usr->USUA_PCRE) : null,
- "PERMISOS" => $permissions,
- "TOKEN" => $token,
- ]);
- }
- public function verifyToken(Request $request){
- DB::enableQueryLog();
- $validator = Validator::make($request->all(), [
- 'token' => 'required|string',
- 'linea' => 'required|integer',
- 'is_scada' => 'string',
- ]);
- if($validator->fails()){
- return $this->responseController->makeResponse(
- true,
- "Se encontraron uno o más errores.",
- $this->responseController->makeErrors(
- $validator->errors()->messages()
- ),
- 401
- );
- }
- $tokenInfo = $request->all();
- $isSCADA = array_key_exists('is_scada', $tokenInfo) ? true : false;
- try{
- $decoded = JWT::decode($tokenInfo['token'], new Key($this->publicKey, 'EdDSA'));
- }catch(Exception $e){
- return $this->responseController->makeResponse(false, "Token inválido", [
- "validToken" => false
- ]);
- }
- $name = "";
- $id = "";
- if($isSCADA){
- $scada = DB::table('S002V01TLISC')->where([
- ['LISC_NULI', '=', $tokenInfo['linea']],
- ['LISC_IDSC', '=', $decoded->iss],
- ])->first();
-
- if(is_null($scada)){
- return $this->responseController->makeResponse(false, "El SCADA que generó el token no está registrado en la base.", [
- "validToken" => false
- ]);
- }else if($scada->LISC_ESTA == 'Eliminado'){
- return $this->responseController->makeResponse(false, "El SCADA que generó el token está eliminado.", [
- "validToken" => false
- ]);
- }
- $name = $scada->LISC_NOSC;
- $id = $scada->LISC_IDSC;
- }else{
- $usr = DB::table('S002V01TUSUA')->where([
- ['USUA_NULI', '=', $tokenInfo['linea']],
- ['USUA_COEL', '=', $decoded->iss],
- ])->first();
- if(is_null($usr)){
- return $this->responseController->makeResponse(false, "El usuario que generó el token no está registrado en la base.", [
- "validToken" => false
- ]);
- }else if($usr->USUA_ESTA == 'Inactivo'){
- return $this->responseController->makeResponse(false, "El usuario que generó el token está desactivado.", [
- "validToken" => false
- ]);
- }else if($usr->USUA_ESTA == 'Eliminado'){
- return $this->responseController->makeResponse(false, "El usuario que generó el token está eliminado.", [
- "validToken" => false
- ]);
- }
-
- $name = $this->functionsController->joinName($usr->USUA_NOMB, $usr->USUA_APPA, $usr->USUA_APMA);
- $id = $usr->USUA_IDUS;
- }
- if($decoded->aud != "dominio.syp.mx"){
- return $this->responseController->makeResponse(false, "El token enviado fue generado en un sitio diferente.", [
- "validToken" => false
- ]);
- }
- $now = $this->functionsController->now();
- $nowTimestamp = $now->timestamp;
- if($nowTimestamp > $decoded->cad && !$isSCADA){
- return $this->responseController->makeResponse(false, "Token expirado.", [
- "validToken" => false
- ]);
- }
- //Se registra la acción realizada
- $nowStr = $now->toDateTimeString();
- $idac = $this->functionsController->registerActivity(
- $tokenInfo['linea'],
- 'LOGIN',
- '-',
- '-',
- 'Registro',
- "El usuario $name (" . $id . ") verificó su token de acceso.",
- $id,
- $nowStr
- );
- $actions = DB::getQueryLog();
- $this->functionsController->registerLog($actions, $id, $nowStr, $idac, $tokenInfo['linea']);
- return $this->responseController->makeResponse(false, "Token válido.", [
- "validToken" => true
- ]);
- }
- public function privateValidateSocketSessions() {
- $this->getSocketClient()->emit('get_sessions', []);
- if($packet = $this->getSocketClient()->wait('new_session_saved')){
- $dataStr = $packet->data;
- $dataArr = json_decode($dataStr, true);
- foreach($dataArr as $session){
- try{
- $decoded = JWT::decode($session['token'], new Key($this->publicKey, 'EdDSA'));
- }catch(Exception $e){
- $this->getSocketClient()->emit('etl_delete_session', $session);
- }
- $now = $this->functionsController->now();
- $nowTimestamp = $now->timestamp;
- if($nowTimestamp > $decoded->cad){
- $this->getSocketClient()->emit('etl_delete_session', $session);
- }
- }
- }
- }
- public function createPasword(Request $request){
- $st = base64_decode("k+SBamn2OKLNuha8s8oXkDggZG1TrHfK1m4prRT1GInKPer4qwT1DHnmaTbtVyiIoHf0cfg9hX9g6PnZ/p4Qj8I+CaQ=");
- $no = base64_decode("rOOHqbrNxRamYCqqkwyxeYUcb7M+32NY");
- $k1 = base64_decode("7tPoKAbUleTq2C/eiQ03oQ5zynj5eWQAR5h+BM0NDeY=");
- $k2 = base64_decode("xGGg6eMXd/ugXqFJfB5wQ9k5Yq/VQRaQeFh4zXmMHSo=");
- $encryption_key_dec = sodium_crypto_box_keypair_from_secretkey_and_publickey(
- $k1,
- $k2
- );
- $decrypted = sodium_crypto_box_open($st, $no, $encryption_key_dec);
- $text = base64_decode($decrypted);
- var_dump($decrypted);
- $timestamp = Carbon::now('America/Mexico_city')->timestamp;
- $id = $this->functionsController->generateID('José Luis Brito Nava', $timestamp);
- var_dump(Hash::make('SAMMX-2023'));
-
- $uuid = $this->functionsController->uuidv5('1546058f-5a25-4334-85ae-e68f2a44bbaf', 'jose.b@ittec.mx');
- return $this->responseController->makeResponse(false, $id, []);
- }
- }
|