Revived API /api/v1/captcha.
Now a new captcha is created to check for a bot.
This commit is contained in:
89
app/Services/Api/V1/CaptchaGenerateService.php
Normal file
89
app/Services/Api/V1/CaptchaGenerateService.php
Normal file
@@ -0,0 +1,89 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace App\Services\Api\V1;
|
||||
|
||||
use App\Captcha\Contracts\ImageBody;
|
||||
use App\Captcha\Contracts\ImageHead;
|
||||
use App\Captcha\Contracts\Type;
|
||||
use App\ServiceResults\Api\V1\CaptchaGenerateService\Captcha;
|
||||
use App\ServiceResults\ServiceResultError;
|
||||
use App\Services\Service;
|
||||
use Illuminate\Support\Arr;
|
||||
use App\Captcha\Config\ImageHead as ImageHeadConfig;
|
||||
use App\Captcha\Config\ImageBody as ImageBodyConfig;
|
||||
|
||||
final class CaptchaGenerateService extends Service
|
||||
{
|
||||
public function __construct(
|
||||
private readonly array $config,
|
||||
private readonly ImageHead $imageHead,
|
||||
private readonly ImageBody $imageBody
|
||||
) { }
|
||||
|
||||
public function generate(): ServiceResultError | Captcha
|
||||
{
|
||||
$types = $this->config['types'] ?? [];
|
||||
if (empty($types)) {
|
||||
$error = __('No captcha type settings!');
|
||||
report($error);
|
||||
return $this->errService($error);
|
||||
}
|
||||
|
||||
try {
|
||||
$type = Arr::random($types);
|
||||
|
||||
/** @var Type $captcha */
|
||||
$typeCaptcha = new $type['class'](
|
||||
$type['params'] ?? []
|
||||
);
|
||||
$symbols = $typeCaptcha->getSymbols();
|
||||
|
||||
$imageHeadConfig = $this->makeImageHeadConfig($this->config['image_head'] ?? []);
|
||||
$imageHead = $this->imageHead->processing($symbols, $imageHeadConfig);
|
||||
unset($imageHeadConfig);
|
||||
|
||||
$imageBodyConfig = $this->makeImageBodyConfig($this->config['image_body'] ?? []);
|
||||
$imageBody = $this->imageBody->processing($symbols, $imageBodyConfig);
|
||||
unset($imageBodyConfig);
|
||||
} catch (\Throwable $e) {
|
||||
report($e);
|
||||
return $this->errService('Captcha service error!');
|
||||
}
|
||||
|
||||
return new Captcha(
|
||||
imageHead: $imageHead,
|
||||
imageBody: $imageBody
|
||||
);
|
||||
}
|
||||
|
||||
private function makeImageHeadConfig(array $params): ImageHeadConfig
|
||||
{
|
||||
return new ImageHeadConfig(
|
||||
backgrounds: $params['backgrounds'] ?? [],
|
||||
fonts: $params['fonts'] ?? [],
|
||||
fontColors: $params['font_colors'] ?? [],
|
||||
width: $params['width'] ?? 150,
|
||||
height: $params['height'] ?? 40,
|
||||
textPaddingTop: $params['text_padding_top'] ?? 5,
|
||||
textPaddingLeft: $params['text_padding_left'] ?? 10,
|
||||
angle: $params['angle'] ?? 20,
|
||||
numberLines: $params['number_lines'] ?? 3,
|
||||
lineColors: $params['line_colors'] ?? []
|
||||
);
|
||||
}
|
||||
|
||||
private function makeImageBodyConfig(array $params): ImageBodyConfig
|
||||
{
|
||||
return new ImageBodyConfig(
|
||||
backgrounds: $params['backgrounds'] ?? [],
|
||||
fonts: $params['fonts'] ?? [],
|
||||
fontColors: $params['font_colors'] ?? [],
|
||||
width: $params['width'] ?? 300,
|
||||
height: $params['height'] ?? 240,
|
||||
angle: $params['angle'] ?? 20,
|
||||
fontSize: $params['font_size'] ?? [20, 50],
|
||||
numberLines: $params['number_lines'] ?? 3,
|
||||
lineColors: $params['line_colors'] ?? []
|
||||
);
|
||||
}
|
||||
}
|
@@ -2,96 +2,45 @@
|
||||
|
||||
namespace App\Services\Api\V1;
|
||||
|
||||
use App\Captcha\Contracts\ImageBody;
|
||||
use App\Captcha\Contracts\ImageHead;
|
||||
use App\Captcha\Contracts\Type;
|
||||
use App\Dto\Request\Api\V1\Captcha\CaptchaPublicToken;
|
||||
use App\Repositories\DataCaptchaRepository;
|
||||
use App\ServiceResults\Api\V1\CaptchaService\Captcha;
|
||||
use App\ServiceResults\ServiceResultError;
|
||||
use App\Services\Captcha\CaptchaHandler;
|
||||
use App\Services\Service;
|
||||
use Illuminate\Support\Arr;
|
||||
use App\Captcha\Config\ImageHead as ImageHeadConfig;
|
||||
use App\Captcha\Config\ImageBody as ImageBodyConfig;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
final class CaptchaService extends Service
|
||||
{
|
||||
public function __construct(
|
||||
private readonly array $config,
|
||||
private readonly ImageHead $imageHead,
|
||||
private readonly ImageBody $imageBody
|
||||
private readonly CaptchaGenerateService $captchaGenerateService,
|
||||
private readonly CaptchaHandler $captchaHandler,
|
||||
private readonly DataCaptchaRepository $dataCaptchaRepository,
|
||||
) { }
|
||||
|
||||
public function generate(): ServiceResultError | Captcha
|
||||
public function createKeyWithCaptcha(CaptchaPublicToken $captchaPublicToken, Carbon $expires): ServiceResultError | Captcha
|
||||
{
|
||||
$types = $this->config['types'] ?? [];
|
||||
if (empty($types)) {
|
||||
$error = __('No captcha type settings!');
|
||||
report($error);
|
||||
return $this->errService($error);
|
||||
}
|
||||
|
||||
try {
|
||||
$type = Arr::random($types);
|
||||
$captcha = $this->captchaGenerateService->generate();
|
||||
if ($captcha->isError()) {
|
||||
return $captcha;
|
||||
}
|
||||
|
||||
/** @var Type $captcha */
|
||||
$typeCaptcha = new $type['class'](
|
||||
$type['params'] ?? []
|
||||
);
|
||||
$symbols = $typeCaptcha->getSymbols();
|
||||
$modelCaptcha = DB::transaction(function () use ($captchaPublicToken) {
|
||||
return $this->captchaHandler->handleStore($captchaPublicToken->getCaptchaToken(), $captchaPublicToken->getHttpUserData());
|
||||
});
|
||||
|
||||
$imageHeadConfig = $this->makeImageHeadConfig($this->config['image_head'] ?? []);
|
||||
$imageHead = $this->imageHead->processing($symbols, $imageHeadConfig);
|
||||
unset($imageHeadConfig);
|
||||
|
||||
$imageBodyConfig = $this->makeImageBodyConfig($this->config['image_body'] ?? []);
|
||||
$imageBody = $this->imageBody->processing($symbols, $imageBodyConfig);
|
||||
unset($imageBodyConfig);
|
||||
|
||||
|
||||
dd($imageHead, $imageBody);
|
||||
$captchaKey = $this->dataCaptchaRepository->store($modelCaptcha, $captcha->getImageBody()->getCoordinators(), $expires);
|
||||
} catch (\Throwable $e) {
|
||||
report($e);
|
||||
return $this->errService('Captcha service error!');
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return new Captcha(
|
||||
imageBase64: $imageHead->getImage()->getImageBase64(),
|
||||
imageTextBase64: $imageBody->getImage()->getImageBase64(),
|
||||
key: 'dddd'
|
||||
);
|
||||
}
|
||||
|
||||
private function makeImageHeadConfig(array $params): ImageHeadConfig
|
||||
{
|
||||
return new ImageHeadConfig(
|
||||
backgrounds: $params['backgrounds'] ?? [],
|
||||
fonts: $params['fonts'] ?? [],
|
||||
fontColors: $params['font_colors'] ?? [],
|
||||
width: $params['width'] ?? 150,
|
||||
height: $params['height'] ?? 40,
|
||||
textPaddingTop: $params['text_padding_top'] ?? 5,
|
||||
textPaddingLeft: $params['text_padding_left'] ?? 10,
|
||||
angle: $params['angle'] ?? 20,
|
||||
numberLines: $params['number_lines'] ?? 3,
|
||||
lineColors: $params['line_colors'] ?? []
|
||||
);
|
||||
}
|
||||
|
||||
private function makeImageBodyConfig(array $params): ImageBodyConfig
|
||||
{
|
||||
return new ImageBodyConfig(
|
||||
backgrounds: $params['backgrounds'] ?? [],
|
||||
fonts: $params['fonts'] ?? [],
|
||||
fontColors: $params['font_colors'] ?? [],
|
||||
width: $params['width'] ?? 300,
|
||||
height: $params['height'] ?? 240,
|
||||
angle: $params['angle'] ?? 20,
|
||||
fontSize: $params['font_size'] ?? [20, 50],
|
||||
numberLines: $params['number_lines'] ?? 3,
|
||||
lineColors: $params['line_colors'] ?? []
|
||||
imageHead: $captcha->getImageHead()->getImage(),
|
||||
imageBody: $captcha->getImageBody()->getImage(),
|
||||
key: $captchaKey
|
||||
);
|
||||
}
|
||||
}
|
||||
|
28
app/Services/Captcha/CaptchaHandler.php
Normal file
28
app/Services/Captcha/CaptchaHandler.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace App\Services\Captcha;
|
||||
|
||||
use App\Dto\HttpUserData;
|
||||
use App\Enums\CaptchaLogType;
|
||||
use App\Models\Captcha;
|
||||
use App\Models\CaptchaToken;
|
||||
use App\Services\CaptchaLog\CaptchaLogHandler;
|
||||
use App\Services\GenerateTokenCommand\GenerateTokenUuidCommand;
|
||||
|
||||
final readonly class CaptchaHandler
|
||||
{
|
||||
public function __construct(
|
||||
private GenerateTokenUuidCommand $uuidCommand,
|
||||
private CaptchaLogHandler $captchaLogHandler
|
||||
) { }
|
||||
|
||||
public function handleStore(CaptchaToken $captchaToken, HttpUserData $httpUserData): Captcha
|
||||
{
|
||||
$captcha = $captchaToken->captchas()->create([
|
||||
'uuid' => $this->uuidCommand->unique($captchaToken->captchas()->getQuery(), 'uuid')
|
||||
]);
|
||||
$this->captchaLogHandler->handleStore($captcha, CaptchaLogType::Created, $httpUserData);
|
||||
|
||||
return $captcha;
|
||||
}
|
||||
}
|
22
app/Services/CaptchaLog/CaptchaLogHandler.php
Normal file
22
app/Services/CaptchaLog/CaptchaLogHandler.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace App\Services\CaptchaLog;
|
||||
|
||||
use App\Dto\HttpUserData;
|
||||
use App\Enums\CaptchaLogType;
|
||||
use App\Models\Captcha;
|
||||
use App\Models\CaptchaLog;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
final readonly class CaptchaLogHandler
|
||||
{
|
||||
public function handleStore(Captcha $captcha, CaptchaLogType $captchaLogType, HttpUserData $httpUserData): CaptchaLog
|
||||
{
|
||||
return $captcha->captchaLogs()->create([
|
||||
'type' => $captchaLogType,
|
||||
'ip' => $httpUserData->getClientIp(),
|
||||
'user_agent' => Str::limit($httpUserData->getUserAgent(), 255, ''),
|
||||
'referer' => Str::limit($httpUserData->getReferer(), 10000, ''),
|
||||
]);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user