Compare commits

...

6 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
328f420bf1
Update copyright information in LICENSE.
The author name in the copyright section of the LICENSE has been updated for accuracy. Previously, it displayed a nickname 'kor-elf' but now it includes the full name 'Leonid Nikitin' as well as the nickname. Ensuring correct, complete, and clear author attributions contributes to the maintainability and transparency of the project.
2023-11-26 23:32:41 +06:00
7 changed files with 233 additions and 1 deletions

View File

@ -1,6 +1,6 @@
MIT License
Copyright (c) 2023 kor-elf
Copyright (c) 2023 Leonid Nikitin (kor-elf)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

View File

@ -1,2 +1,33 @@
# 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>';
}