Compare commits

5 Commits

Author SHA1 Message Date
88cee05963 Merge pull request 'Version 1.' (#1) from develop into main
Reviewed-on: #1
2023-12-03 01:16:14 +06:00
032185b52c Add instructions to README.md. 2023-12-03 01:06:09 +06:00
d9e9564ea8 Fix typo in 'user_agent' key assignment.
A typo in the key assignment for 'user_agent' in the CaptchaService has been fixed. The key was previously incorrectly typed as 'user_ageng'. This issue was causing problems with HTTP posts where user agent data was not being properly passed due to the misspelt key.
2023-12-03 00:58:47 +06:00
c39f6ba4d7 Validation is ready. 2023-12-03 00:46:06 +06:00
250c1a9f8d The LICENSE file was renamed to LICENSE.md. 2023-12-02 19:59:51 +06:00
7 changed files with 232 additions and 0 deletions

View File

View File

@@ -1,2 +1,33 @@
# captcha-rule-for-laravel # captcha-rule-for-laravel
Laravel 10. Rule Validation для сервиса https://git.kor-elf.net/kor-elf/service-captcha.
Параметры в .env.
# CAPTCHA_API_DOMAIN
Указываем адрес к сервису для проверки от робота.
Примеры: http://captcha.localhost:9008, https://captcha.localhost, http://captcha.localhost
# CAPTCHA_PRIVATE_TOKEN
Указываем приватный токен, для проверки со стороны сервера.
# CAPTCHA_CURL_TIMEOUT
Curl timeout в секундах.
По умолчанию: 10
# CAPTCHA_ENABLE_BLADE_CAPTCHA
Включает Blade::directive "captcha" (@captcha).
По умолчанию: true
# CAPTCHA_PUBLIC_TOKEN
Указываем публичный токен, который мы получаем от сервиса для проверки от робота.
# CAPTCHA_STATIC_PATH
Указываем путь к статике.
Примеры: /captcha, https://captcha.localhost/captcha
По умолчанию: env('CAPTCHA_API_DOMAIN') . '/captcha'

40
composer.json Normal file
View File

@@ -0,0 +1,40 @@
{
"name": "kor-elf/captcha-rule-for-laravel",
"description": "Validation Rule Captcha for Laravel",
"license": "MIT",
"type": "library",
"keywords": [
"captcha",
"laravel",
"validation"
],
"homepage": "https://git.kor-elf.net/kor-elf/captcha-rule-for-laravel",
"authors": [
{
"name": "Leonid Nikitin",
"email": "i@kor-elf.net",
"homepage": "https://git.kor-elf.net/kor-elf",
"role": "Developer"
}
],
"require": {
"php": "^8.2",
"illuminate/support": "^10.0",
"guzzlehttp/guzzle": "^7.0.1"
},
"extra": {
"laravel": {
"providers": [
"korElf\\CaptchaRuleForLaravel\\CaptchaProvider"
]
}
},
"autoload": {
"psr-4": {
"korElf\\CaptchaRuleForLaravel\\": "src/"
},
"files": [
"src/helpers.php"
]
}
}

58
config/captcha.php Normal file
View File

@@ -0,0 +1,58 @@
<?php
/**
* Copyright (c) 2023
* author: Leonid Nikitin - i@kor-elf.net
* web: https://git.kor-elf.net/kor-elf
* Initial version created on: 02.12.2023
* MIT license: https://git.kor-elf.net/kor-elf/captcha-rule-for-laravel/src/branch/main/LICENSE.md
*/
return [
/*
* Указываем адрес к сервису для проверки от робота.
* Примеры: http://captcha.localhost:9008, https://captcha.localhost, http://captcha.localhost
*/
'api_domain' => env('CAPTCHA_API_DOMAIN'),
/*
* Приватный токен для проверки получаемого ключа после успешной проверки от бота.
*/
'api_private_token' => env('CAPTCHA_PRIVATE_TOKEN'),
/*
* Curl timeout в секундах.
*/
'curl_timeout' => (int) env('CAPTCHA_CURL_TIMEOUT', 10),
/*
* Включает Blade::directive "captcha".
*/
'enable_blade_captcha' => (bool) env('CAPTCHA_ENABLE_BLADE_CAPTCHA', true),
/*
* Публичный токен для начало проверки я не робот.
*/
'api_public_token' => env('CAPTCHA_PUBLIC_TOKEN'),
/**
* Указываем путь к статике, на данный момент это к стилям.
* Примеры: /captcha, https://captcha.localhost/captcha
*/
'static_path' => env('CAPTCHA_STATIC_PATH', env('CAPTCHA_API_DOMAIN') . '/captcha'),
/*
* Используется в переводах.
*/
'error_message_key' => 'validation.captcha',
/*
* Имя Validator::extendImplicit.
*/
'rule_name' => 'captcha',
/*
* Name в input после успешной проверки.
*/
'captcha_verified_name' => 'captcha-verified',
];

60
src/CaptchaProvider.php Normal file
View File

@@ -0,0 +1,60 @@
<?php declare(strict_types=1);
namespace korElf\CaptchaRuleForLaravel;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Blade;
use Illuminate\Contracts\Foundation\Application;
final class CaptchaProvider extends ServiceProvider
{
public function boot(): Void
{
$this->addValidationRule();
$this->publishes([
__DIR__ . '/../config/captcha.php' => config_path('captcha.php'),
], 'config');
if (config('captcha.enable_blade_captcha')) {
Blade::directive('captcha', function () {
return "<?php echo \korElf\CaptchaRuleForLaravel\htmlCaptcha(); ?>";
});
}
}
/**
* Extends Validator to include a captcha type
*/
public function addValidationRule(): Void
{
$message = trans(config('captcha.error_message_key'));
Validator::extendImplicit(config('captcha.rule_name'), function ($attribute, $value) {
if (!is_string($value)) {
return false;
}
return app(CaptchaService::class)->validate($value, request()->userAgent());
}, $message);
}
/**
* Register the service provider.
*
* @return void
*/
public function register(): Void
{
$this->mergeConfigFrom(
__DIR__ . '/../config/captcha.php',
'captcha'
);
$this->app->singleton(CaptchaService::class, function (Application $app) {
return new CaptchaService(
privateToken: config('captcha.api_private_token', ''),
domainApi: config('captcha.api_domain', ''),
curlTimeout: config('captcha.curl_timeout', ''),
);
});
}
}

35
src/CaptchaService.php Normal file
View File

@@ -0,0 +1,35 @@
<?php declare(strict_types=1);
namespace korElf\CaptchaRuleForLaravel;
use Illuminate\Support\Facades\Http;
final readonly class CaptchaService
{
public function __construct(
private string $privateToken,
private string $domainApi,
private int $curlTimeout = 10,
) { }
public function validate(string $token, ?string $userAgent = null): bool
{
try {
$post = [];
if (!is_null($userAgent)) {
$post['user_agent'] = $userAgent;
}
$response = Http::withHeaders([
'private-token' => $this->privateToken,
])
->timeout($this->curlTimeout)
->post($this->domainApi . '/api/v1/captcha/' . $token, $post);
return ($response->json('status') === true);
} catch (\Throwable $e) {
}
return false;
}
}

8
src/helpers.php Normal file
View File

@@ -0,0 +1,8 @@
<?php declare(strict_types=1);
namespace korElf\CaptchaRuleForLaravel;
function htmlCaptcha(): string
{
return '<div class="captcha-service-kor-elf" data-domain="' . config('captcha.api_domain') . '" data-static-path="' . config('captcha.static_path') . '" data-token="' . config('captcha.api_public_token') . '" data-captcha-verified-name="' . config('captcha.captcha_verified_name') . '"></div><script src="' . config('captcha.static_path') . '/script.js" async></script>';
}