diff --git a/bootstrap/secure.php b/bootstrap/secure.php index 4ee1ec7..714beb3 100644 --- a/bootstrap/secure.php +++ b/bootstrap/secure.php @@ -2,7 +2,7 @@ $secure_config = [ 'web_auth_type' => 'email_code', // login_password, email_code - 'token_type' => 'JWT', // random_bytes, md5, crypt, hash, JWT + 'token_type' => 'crypt', // random_bytes, md5, crypt, hash, JWT 'token_expired_time' => "+30 days", // +1 day ]; diff --git a/kernel/helpers/Html.php b/kernel/helpers/Html.php index f85f115..369290f 100644 --- a/kernel/helpers/Html.php +++ b/kernel/helpers/Html.php @@ -17,6 +17,12 @@ class Html return "$title"; } + public static function a(string $link, array $params = []): string + { + $paramsStr = self::createParams($params); + return ""; + } + /** * @param array $data * @return string diff --git a/kernel/helpers/RESTClient.php b/kernel/helpers/RESTClient.php index 2706b01..c77cf1b 100644 --- a/kernel/helpers/RESTClient.php +++ b/kernel/helpers/RESTClient.php @@ -2,13 +2,17 @@ namespace kernel\helpers; +use GuzzleHttp\Exception\GuzzleException; use http\Client; class RESTClient { - public static function request(string $url, string $method = 'GET') + /** + * @throws GuzzleException + */ + public static function request(string $url, string $method = 'GET'): \Psr\Http\Message\ResponseInterface { $client = new \GuzzleHttp\Client(); return $client->request($method, $url, [ @@ -18,4 +22,31 @@ class RESTClient ]); } + /** + * @throws GuzzleException + */ + public static function request_without_auth(string $url, string $method = 'GET'): \Psr\Http\Message\ResponseInterface + { + $client = new \GuzzleHttp\Client(); + return $client->request($method, $url); + } + + /** + * @throws GuzzleException + */ + public static function post(string $url, array $data = [], bool $auth = true): \Psr\Http\Message\ResponseInterface + { + $headers = []; + if ($auth){ + $headers = [ + 'Authorization' => 'Bearer ' . $_ENV['MODULE_SHOP_TOKEN'] + ]; + } + $client = new \GuzzleHttp\Client(); + return $client->request("POST", $url, [ + 'form_params' => $data, + 'headers' => $headers, + ]); + } + } \ No newline at end of file diff --git a/kernel/modules/module_shop_client/controllers/ModuleShopClientController.php b/kernel/modules/module_shop_client/controllers/ModuleShopClientController.php index ac2eb11..a83f465 100644 --- a/kernel/modules/module_shop_client/controllers/ModuleShopClientController.php +++ b/kernel/modules/module_shop_client/controllers/ModuleShopClientController.php @@ -15,6 +15,8 @@ use kernel\Mailing; use kernel\modules\module_shop_client\services\ModuleShopClientService; use kernel\Request; use kernel\services\ModuleService; +use kernel\services\ModuleShopService; +use kernel\services\TokenService; use PHPMailer\PHPMailer\Exception; class ModuleShopClientController extends AdminController @@ -129,19 +131,50 @@ class ModuleShopClientController extends AdminController $request = new Request(); $address = $request->post("email"); - $mailing = new Mailing(); - $mailing->send_html("login_by_code.php", ['code' => mt_rand(100000, 999999)], [ - 'address' => $address, - 'subject' => "Код авторизации", - "from_name" => $_ENV['APP_NAME'] - ]); +// $mailing = new Mailing(); +// $mailing->send_html("login_by_code.php", ['code' => mt_rand(100000, 999999)], [ +// 'address' => $address, +// 'subject' => "Код авторизации", +// "from_name" => $_ENV['APP_NAME'] +// ]); - $this->cgView->render('enter_code.php', ['email' => $address]); + $moduleShopService = new ModuleShopService(); + $result = $moduleShopService->email_auth($address); + + if ($result['status'] == 'success'){ + $this->cgView->render('enter_code.php', ['email' => $address]); + } + + $this->cgView->render('module_shop_error_connection.php', ['email' => $address]); } public function actionCodeCheck(): void { - Debug::dd(123); + $request = new Request(); + $code = $request->post("code"); + +// $mailing = new Mailing(); +// $mailing->send_html("login_by_code.php", ['code' => mt_rand(100000, 999999)], [ +// 'address' => $address, +// 'subject' => "Код авторизации", +// "from_name" => $_ENV['APP_NAME'] +// ]); + + $moduleShopService = new ModuleShopService(); + $result = $moduleShopService->code_check($code); + + if (isset($result['access_token'])){ + + $envFile = \EnvEditor\EnvFile::loadFrom(ROOT_DIR . "/.env"); + + $envFile->setValue("MODULE_SHOP_TOKEN", $result['access_token']); + + $envFile->saveTo(ROOT_DIR . "/.env"); + + $this->cgView->render('success_login.php'); + } + + $this->cgView->render('module_shop_error_connection.php'); } } \ No newline at end of file diff --git a/kernel/modules/module_shop_client/views/success_login.php b/kernel/modules/module_shop_client/views/success_login.php new file mode 100644 index 0000000..927f680 --- /dev/null +++ b/kernel/modules/module_shop_client/views/success_login.php @@ -0,0 +1,9 @@ +run(); + +echo \kernel\helpers\Html::h(2, "Авторизация прошла успешно"); +echo \kernel\helpers\Html::a("/admin", ['class' => 'btm btm-primary']); + diff --git a/kernel/modules/secure/controllers/SecureRestController.php b/kernel/modules/secure/controllers/SecureRestController.php index a78c259..7e82699 100644 --- a/kernel/modules/secure/controllers/SecureRestController.php +++ b/kernel/modules/secure/controllers/SecureRestController.php @@ -94,7 +94,7 @@ class SecureRestController extends RestController } $res = [ - "code" => $secretCode->code, + "status" => "success", "code_expires_at" => $secretCode->code_expires_at, ]; @@ -105,23 +105,26 @@ class SecureRestController extends RestController /** * @throws Exception */ - public function actionCodeCheck(): void + #[NoReturn] public function actionCodeCheck(): void { $request = new Request(); + $code = $request->post("code"); - if (isset($_COOKIE['user_email'])) { - $user = User::where('email', $_COOKIE["user_email"])->first(); - if (!$user) { - throw new exception("User not found."); - } - $code = $request->post("code"); - $secretCode = SecureService::getByField("user_id", $user->id); - if ($secretCode->code == $code && time() <= strtotime($secretCode->code_expires_at)) { - setcookie('user_id', $user->id, time() + 60 * 60 * 24, '/', $_SERVER['SERVER_NAME'], false); - } else { - throw new exception("incorrect code"); + $model = SecretCode::where("code", $code)->first(); + if (time() <= strtotime($model->code_expires_at)) { + $user = $this->model->where("id", $model->user_id)->first(); + if ($user){ + $user->access_token_expires_at = date("Y-m-d H:i:s", strtotime(App::$secure['token_expired_time'])); + $user->access_token = SecureService::generateAccessToken(); + $user->save(); + $this->renderApi([ + "access_token" => $user->access_token, + "access_token_expires_at" => $user->access_token_expires_at, + ]); } } + + $this->renderApi(['status' => 'error', 'message' => 'incorrect code']); } } diff --git a/kernel/modules/secure/services/SecureService.php b/kernel/modules/secure/services/SecureService.php index ca5e264..b47f4d4 100644 --- a/kernel/modules/secure/services/SecureService.php +++ b/kernel/modules/secure/services/SecureService.php @@ -2,11 +2,13 @@ namespace kernel\modules\secure\services; +use kernel\App; use kernel\FormModel; use kernel\helpers\Debug; use kernel\modules\secure\models\SecretCode; use kernel\modules\user\models\User; use kernel\modules\user\service\UserService; +use kernel\services\TokenService; class SecureService { @@ -38,4 +40,15 @@ class SecureService return SecretCode::where($field, $value)->first(); } + public static function generateAccessToken(): string + { + return match (App::$secure['token_type']) { + "JWT" => TokenService::JWT($_ENV['SECRET_KEY'], 'HS256'), + "md5" => TokenService::md5(), + "crypt" => TokenService::crypt(), + "hash" => TokenService::hash('sha256'), + default => TokenService::random_bytes(20), + }; + } + } \ No newline at end of file diff --git a/kernel/services/ModuleShopService.php b/kernel/services/ModuleShopService.php new file mode 100644 index 0000000..72562ad --- /dev/null +++ b/kernel/services/ModuleShopService.php @@ -0,0 +1,36 @@ +url = $_ENV['MODULE_SHOP_URL']; + $this->token = $_ENV['MODULE_SHOP_TOKEN']; + } + + /** + * @throws GuzzleException + */ + public function email_auth(string $email) + { + $request = RESTClient::post($this->url . "/api/secure/email_auth", ['email' => $email], false); + + return json_decode($request->getBody()->getContents(), true); + } + + public function code_check(string $code) + { + $request = RESTClient::post($this->url . "/api/secure/code_check", ['code' => $code], false); + + return json_decode($request->getBody()->getContents(), true); + } + +} \ No newline at end of file