Version 0.7.0 #1
							
								
								
									
										27
									
								
								app/Dto/HttpUserData.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								app/Dto/HttpUserData.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
				
			|||||||
 | 
					<?php declare(strict_types=1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Dto;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					final readonly class HttpUserData
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public function __construct(
 | 
				
			||||||
 | 
					        private ?string $clientIp = null,
 | 
				
			||||||
 | 
					        private ?string $userAgent = null,
 | 
				
			||||||
 | 
					        private ?string $referer = null
 | 
				
			||||||
 | 
					    ) { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function getClientIp(): ?string
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $this->clientIp;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function getUserAgent(): ?string
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $this->userAgent;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function getReferer(): ?string
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $this->referer;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										25
									
								
								app/Dto/Request/Api/V1/Captcha/CaptchaPublicToken.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								app/Dto/Request/Api/V1/Captcha/CaptchaPublicToken.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,25 @@
 | 
				
			|||||||
 | 
					<?php declare(strict_types=1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Dto\Request\Api\V1\Captcha;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Dto\HttpUserData;
 | 
				
			||||||
 | 
					use App\Dto\Request\Dto;
 | 
				
			||||||
 | 
					use App\Models\CaptchaToken;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					final readonly class CaptchaPublicToken extends Dto
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public function __construct(
 | 
				
			||||||
 | 
					        private CaptchaToken $captchaToken,
 | 
				
			||||||
 | 
					        private HttpUserData $httpUserData
 | 
				
			||||||
 | 
					    ) { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function getCaptchaToken(): CaptchaToken
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $this->captchaToken;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function getHttpUserData(): HttpUserData
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $this->httpUserData;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										8
									
								
								app/Enums/CaptchaLogType.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								app/Enums/CaptchaLogType.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
				
			|||||||
 | 
					<?php declare(strict_types=1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Enums;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum CaptchaLogType: int
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    case Created = 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -0,0 +1,8 @@
 | 
				
			|||||||
 | 
					<?php declare(strict_types=1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Exceptions\Repositories;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					final class DataCaptchaRepositoryException extends \Exception
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -2,6 +2,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace App\Http\Controllers\Api\V1;
 | 
					namespace App\Http\Controllers\Api\V1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Http\Requests\Api\V1\Captcha\CaptchaRequest;
 | 
				
			||||||
use App\Http\Resources\Api\V1\Captcha;
 | 
					use App\Http\Resources\Api\V1\Captcha;
 | 
				
			||||||
use App\Services\Api\V1\CaptchaService;
 | 
					use App\Services\Api\V1\CaptchaService;
 | 
				
			||||||
use Illuminate\Http\JsonResponse;
 | 
					use Illuminate\Http\JsonResponse;
 | 
				
			||||||
@@ -12,9 +13,11 @@ final class CaptchaController extends Controller
 | 
				
			|||||||
        private readonly CaptchaService $captchaService
 | 
					        private readonly CaptchaService $captchaService
 | 
				
			||||||
    ) { }
 | 
					    ) { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function getCaptcha(): JsonResponse
 | 
					    public function getCaptcha(CaptchaRequest $request): JsonResponse
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $result = $this->captchaService->generate();
 | 
					        $captchaPublicToken = $request->getDto();
 | 
				
			||||||
 | 
					        $expires = now()->addSeconds(config('captcha.waiting_for_captcha_verification_in_seconds'));
 | 
				
			||||||
 | 
					        $result = $this->captchaService->createKeyWithCaptcha($captchaPublicToken, $expires);
 | 
				
			||||||
        if (!$result->isSuccess()) {
 | 
					        if (!$result->isSuccess()) {
 | 
				
			||||||
            return response()->json($result->getData())->setStatusCode($result->getCode());
 | 
					            return response()->json($result->getData())->setStatusCode($result->getCode());
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										57
									
								
								app/Http/Requests/Api/V1/Captcha/CaptchaRequest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								app/Http/Requests/Api/V1/Captcha/CaptchaRequest.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,57 @@
 | 
				
			|||||||
 | 
					<?php declare(strict_types=1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Http\Requests\Api\V1\Captcha;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Contracts\FormRequestDto;
 | 
				
			||||||
 | 
					use App\Dto\HttpUserData;
 | 
				
			||||||
 | 
					use App\Dto\Request\Api\V1\Captcha\CaptchaPublicToken;
 | 
				
			||||||
 | 
					use App\Models\CaptchaToken;
 | 
				
			||||||
 | 
					use App\Repositories\CaptchaTokenRepository;
 | 
				
			||||||
 | 
					use Illuminate\Foundation\Http\FormRequest;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					final class CaptchaRequest extends FormRequest implements FormRequestDto
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    private readonly CaptchaToken $captchaToken;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Determine if the user is authorized to make this request.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function authorize(CaptchaTokenRepository $captchaTokenRepository): bool
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (!$this->hasHeader('public-token')) {
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        $captchaToken = $captchaTokenRepository->getCaptchaTokenByPublicToken($this->header('public-token'));
 | 
				
			||||||
 | 
					        if (is_null($captchaToken)) {
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->captchaToken = $captchaToken;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Get the validation rules that apply to the request.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function rules(): array
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return [
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function getDto(): CaptchaPublicToken
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $httpUserData = new HttpUserData(
 | 
				
			||||||
 | 
					            $this->getClientIp(),
 | 
				
			||||||
 | 
					            $this->userAgent(),
 | 
				
			||||||
 | 
					            $this->header('referer')
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return new CaptchaPublicToken(
 | 
				
			||||||
 | 
					            $this->captchaToken,
 | 
				
			||||||
 | 
					            $httpUserData
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -23,8 +23,16 @@ final class Captcha extends JsonResource
 | 
				
			|||||||
    public function toArray(Request $request): array
 | 
					    public function toArray(Request $request): array
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return [
 | 
					        return [
 | 
				
			||||||
            'image_base64'      => $this->resource->getImageBase64(),
 | 
					            'image_head' => [
 | 
				
			||||||
            'image_text_base64' => $this->resource->getImageTextBase64(),
 | 
					                'base64' => $this->resource->getImageHead()->getImageBase64(),
 | 
				
			||||||
 | 
					                'width'  => $this->resource->getImageHead()->getWidth(),
 | 
				
			||||||
 | 
					                'height' => $this->resource->getImageHead()->getHeight(),
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            'image_body' => [
 | 
				
			||||||
 | 
					                'base64' => $this->resource->getImageBody()->getImageBase64(),
 | 
				
			||||||
 | 
					                'width'  => $this->resource->getImageBody()->getWidth(),
 | 
				
			||||||
 | 
					                'height' => $this->resource->getImageBody()->getHeight(),
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
            'captcha_key' => $this->resource->getKey()
 | 
					            'captcha_key' => $this->resource->getKey()
 | 
				
			||||||
        ];
 | 
					        ];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										37
									
								
								app/Models/Captcha.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								app/Models/Captcha.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,37 @@
 | 
				
			|||||||
 | 
					<?php declare(strict_types=1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Models;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use Illuminate\Database\Eloquent\Factories\HasFactory;
 | 
				
			||||||
 | 
					use Illuminate\Database\Eloquent\Model;
 | 
				
			||||||
 | 
					use Illuminate\Database\Eloquent\Relations\HasMany;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					final class Captcha extends Model
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    use HasFactory;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected $table = 'captchas';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * The attributes that are mass assignable.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @var array
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    protected $fillable = [
 | 
				
			||||||
 | 
					        'uuid',
 | 
				
			||||||
 | 
					    ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * The attributes that should be hidden for serialization.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @var array<int, string>
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    protected $hidden = [
 | 
				
			||||||
 | 
					        'uuid',
 | 
				
			||||||
 | 
					    ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function captchaLogs(): HasMany
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $this->hasMany(CaptchaLog::class);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										37
									
								
								app/Models/CaptchaLog.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								app/Models/CaptchaLog.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,37 @@
 | 
				
			|||||||
 | 
					<?php declare(strict_types=1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Models;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Enums\CaptchaLogType;
 | 
				
			||||||
 | 
					use Illuminate\Database\Eloquent\Factories\HasFactory;
 | 
				
			||||||
 | 
					use Illuminate\Database\Eloquent\Model;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					final class CaptchaLog extends Model
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    use HasFactory;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected $table = 'captcha_logs';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const UPDATED_AT = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * The attributes that are mass assignable.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @var array
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    protected $fillable = [
 | 
				
			||||||
 | 
					        'type',
 | 
				
			||||||
 | 
					        'ip',
 | 
				
			||||||
 | 
					        'user_agent',
 | 
				
			||||||
 | 
					        'referer',
 | 
				
			||||||
 | 
					    ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * The attributes that should be cast.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @var array
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    protected $casts = [
 | 
				
			||||||
 | 
					        'type' => CaptchaLogType::class,
 | 
				
			||||||
 | 
					    ];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -4,6 +4,7 @@ namespace App\Models;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
 | 
					use Illuminate\Database\Eloquent\Factories\HasFactory;
 | 
				
			||||||
use Illuminate\Database\Eloquent\Model;
 | 
					use Illuminate\Database\Eloquent\Model;
 | 
				
			||||||
 | 
					use Illuminate\Database\Eloquent\Relations\HasMany;
 | 
				
			||||||
use Illuminate\Database\Eloquent\SoftDeletes;
 | 
					use Illuminate\Database\Eloquent\SoftDeletes;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
final class CaptchaToken extends Model
 | 
					final class CaptchaToken extends Model
 | 
				
			||||||
@@ -30,4 +31,9 @@ final class CaptchaToken extends Model
 | 
				
			|||||||
        'public_token',
 | 
					        'public_token',
 | 
				
			||||||
        'private_token',
 | 
					        'private_token',
 | 
				
			||||||
    ];
 | 
					    ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function captchas(): HasMany
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $this->hasMany(Captcha::class);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,7 +10,7 @@ use App\Captcha\Images\Body;
 | 
				
			|||||||
use App\Captcha\Images\Head;
 | 
					use App\Captcha\Images\Head;
 | 
				
			||||||
use App\Captcha\Images\ImageManager;
 | 
					use App\Captcha\Images\ImageManager;
 | 
				
			||||||
use App\Captcha\Images\Lines;
 | 
					use App\Captcha\Images\Lines;
 | 
				
			||||||
use App\Services\Api\V1\CaptchaService;
 | 
					use App\Services\Api\V1\CaptchaGenerateService;
 | 
				
			||||||
use App\Services\CaptchaToken\CaptchaTokenHandler;
 | 
					use App\Services\CaptchaToken\CaptchaTokenHandler;
 | 
				
			||||||
use App\Services\GenerateTokenCommand\GenerateTokenUlidCommand;
 | 
					use App\Services\GenerateTokenCommand\GenerateTokenUlidCommand;
 | 
				
			||||||
use App\Services\GenerateTokenCommand\GenerateTokenUuidCommand;
 | 
					use App\Services\GenerateTokenCommand\GenerateTokenUuidCommand;
 | 
				
			||||||
@@ -39,8 +39,8 @@ final class AppServiceProvider extends ServiceProvider
 | 
				
			|||||||
            return new CreateSearchInstanceCommand(Search::class);
 | 
					            return new CreateSearchInstanceCommand(Search::class);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->app->bind(CaptchaService::class, function (Application $app) {
 | 
					        $this->app->bind(CaptchaGenerateService::class, function (Application $app) {
 | 
				
			||||||
            return new CaptchaService(
 | 
					            return new CaptchaGenerateService(
 | 
				
			||||||
                config: config('captcha', []),
 | 
					                config: config('captcha', []),
 | 
				
			||||||
                imageHead: $app->make(ImageHead::class),
 | 
					                imageHead: $app->make(ImageHead::class),
 | 
				
			||||||
                imageBody: $app->make(ImageBody::class)
 | 
					                imageBody: $app->make(ImageBody::class)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -36,4 +36,9 @@ final readonly class CaptchaTokenRepository
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        return $this->createSearchInstanceCommand->execute($query);
 | 
					        return $this->createSearchInstanceCommand->execute($query);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function getCaptchaTokenByPublicToken(string $token): ?CaptchaToken
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return CaptchaToken::query()->where('public_token', '=', $token)->first();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										31
									
								
								app/Repositories/DataCaptchaRepository.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								app/Repositories/DataCaptchaRepository.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,31 @@
 | 
				
			|||||||
 | 
					<?php declare(strict_types=1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Repositories;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Exceptions\Repositories\DataCaptchaRepositoryException;
 | 
				
			||||||
 | 
					use App\Models\Captcha;
 | 
				
			||||||
 | 
					use App\Services\GenerateTokenCommand\GenerateTokenUlidCommand;
 | 
				
			||||||
 | 
					use Carbon\Carbon;
 | 
				
			||||||
 | 
					use Illuminate\Support\Facades\Cache;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					final readonly class DataCaptchaRepository
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public function __construct(
 | 
				
			||||||
 | 
					        private GenerateTokenUlidCommand $generateTokenUlidCommand,
 | 
				
			||||||
 | 
					    ) { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function store(Captcha $captcha, array $coordinators, Carbon $expires): string
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $key = $this->generateTokenUlidCommand->execute() . '_' . time();
 | 
				
			||||||
 | 
					        $data = [
 | 
				
			||||||
 | 
					            'id' => $captcha->id,
 | 
				
			||||||
 | 
					            'coordinators' => $coordinators
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!Cache::driver('redis')->add($key, $data, $expires) ) {
 | 
				
			||||||
 | 
					            throw new DataCaptchaRepositoryException('Could not create cache for captcha: ' . $captcha->id . ' key: ' . $key);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $key;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										25
									
								
								app/ServiceResults/Api/V1/CaptchaGenerateService/Captcha.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								app/ServiceResults/Api/V1/CaptchaGenerateService/Captcha.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,25 @@
 | 
				
			|||||||
 | 
					<?php declare(strict_types=1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\ServiceResults\Api\V1\CaptchaGenerateService;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Captcha\Dto\ImageBody;
 | 
				
			||||||
 | 
					use App\Captcha\Dto\ImageHead;
 | 
				
			||||||
 | 
					use App\ServiceResults\ServiceResult;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					final class Captcha extends ServiceResult
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public function __construct(
 | 
				
			||||||
 | 
					        private readonly ImageHead $imageHead,
 | 
				
			||||||
 | 
					        private readonly ImageBody $imageBody
 | 
				
			||||||
 | 
					    ) { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function getImageHead(): ImageHead
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $this->imageHead;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function getImageBody(): ImageBody
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $this->imageBody;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -2,35 +2,27 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace App\ServiceResults\Api\V1\CaptchaService;
 | 
					namespace App\ServiceResults\Api\V1\CaptchaService;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Captcha\Dto\Image;
 | 
				
			||||||
use App\ServiceResults\ServiceResult;
 | 
					use App\ServiceResults\ServiceResult;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
final class Captcha extends ServiceResult
 | 
					final class Captcha extends ServiceResult
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    public function __construct(
 | 
					    public function __construct(
 | 
				
			||||||
        private readonly string $imageBase64,
 | 
					        private readonly Image $imageHead,
 | 
				
			||||||
        private readonly string $imageTextBase64,
 | 
					        private readonly Image $imageBody,
 | 
				
			||||||
        private readonly string $key
 | 
					        private readonly string $key
 | 
				
			||||||
    ) { }
 | 
					    ) { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    public function getImageHead(): Image
 | 
				
			||||||
     * @return string
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public function getImageBase64(): string
 | 
					 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return $this->imageBase64;
 | 
					        return $this->imageHead;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    public function getImageBody(): Image
 | 
				
			||||||
     * @return string
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public function getImageTextBase64(): string
 | 
					 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return $this->imageTextBase64;
 | 
					        return $this->imageBody;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * @return string
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public function getKey(): string
 | 
					    public function getKey(): string
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return $this->key;
 | 
					        return $this->key;
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										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;
 | 
					namespace App\Services\Api\V1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use App\Captcha\Contracts\ImageBody;
 | 
					use App\Dto\Request\Api\V1\Captcha\CaptchaPublicToken;
 | 
				
			||||||
use App\Captcha\Contracts\ImageHead;
 | 
					use App\Repositories\DataCaptchaRepository;
 | 
				
			||||||
use App\Captcha\Contracts\Type;
 | 
					 | 
				
			||||||
use App\ServiceResults\Api\V1\CaptchaService\Captcha;
 | 
					use App\ServiceResults\Api\V1\CaptchaService\Captcha;
 | 
				
			||||||
use App\ServiceResults\ServiceResultError;
 | 
					use App\ServiceResults\ServiceResultError;
 | 
				
			||||||
 | 
					use App\Services\Captcha\CaptchaHandler;
 | 
				
			||||||
use App\Services\Service;
 | 
					use App\Services\Service;
 | 
				
			||||||
use Illuminate\Support\Arr;
 | 
					use Carbon\Carbon;
 | 
				
			||||||
use App\Captcha\Config\ImageHead as ImageHeadConfig;
 | 
					use Illuminate\Support\Facades\DB;
 | 
				
			||||||
use App\Captcha\Config\ImageBody as ImageBodyConfig;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
final class CaptchaService extends Service
 | 
					final class CaptchaService extends Service
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    public function __construct(
 | 
					    public function __construct(
 | 
				
			||||||
        private readonly array $config,
 | 
					        private readonly CaptchaGenerateService $captchaGenerateService,
 | 
				
			||||||
        private readonly ImageHead $imageHead,
 | 
					        private readonly CaptchaHandler $captchaHandler,
 | 
				
			||||||
        private readonly ImageBody $imageBody
 | 
					        private readonly DataCaptchaRepository $dataCaptchaRepository,
 | 
				
			||||||
    ) { }
 | 
					    ) { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function generate(): ServiceResultError | Captcha
 | 
					    public function createKeyWithCaptcha(CaptchaPublicToken $captchaPublicToken, Carbon $expires): ServiceResultError | Captcha
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $types = $this->config['types'] ?? [];
 | 
					        try {
 | 
				
			||||||
        if (empty($types)) {
 | 
					            $captcha = $this->captchaGenerateService->generate();
 | 
				
			||||||
            $error = __('No captcha type settings!');
 | 
					            if ($captcha->isError()) {
 | 
				
			||||||
            report($error);
 | 
					                return $captcha;
 | 
				
			||||||
            return $this->errService($error);
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        try {
 | 
					            $modelCaptcha = DB::transaction(function () use ($captchaPublicToken) {
 | 
				
			||||||
            $type = Arr::random($types);
 | 
					                return $this->captchaHandler->handleStore($captchaPublicToken->getCaptchaToken(), $captchaPublicToken->getHttpUserData());
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            /** @var Type $captcha */
 | 
					            $captchaKey = $this->dataCaptchaRepository->store($modelCaptcha, $captcha->getImageBody()->getCoordinators(), $expires);
 | 
				
			||||||
            $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);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            dd($imageHead, $imageBody);
 | 
					 | 
				
			||||||
        } catch (\Throwable $e) {
 | 
					        } catch (\Throwable $e) {
 | 
				
			||||||
            report($e);
 | 
					            report($e);
 | 
				
			||||||
            return $this->errService('Captcha service error!');
 | 
					            return $this->errService('Captcha service error!');
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return new Captcha(
 | 
					        return new Captcha(
 | 
				
			||||||
            imageBase64: $imageHead->getImage()->getImageBase64(),
 | 
					            imageHead: $captcha->getImageHead()->getImage(),
 | 
				
			||||||
            imageTextBase64: $imageBody->getImage()->getImageBase64(),
 | 
					            imageBody: $captcha->getImageBody()->getImage(),
 | 
				
			||||||
            key: 'dddd'
 | 
					            key: $captchaKey
 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    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'] ?? []
 | 
					 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										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, ''),
 | 
				
			||||||
 | 
					        ]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -1,6 +1,7 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
return [
 | 
					return [
 | 
				
			||||||
 | 
					    'waiting_for_captcha_verification_in_seconds' => env('WAITING_FOR_CAPTCHA_VERIFICATION_IN_SECONDS', 900),
 | 
				
			||||||
    'imageClass' => \App\Captcha\Images\Image::class,
 | 
					    'imageClass' => \App\Captcha\Images\Image::class,
 | 
				
			||||||
    'types' => [
 | 
					    'types' => [
 | 
				
			||||||
        'string' => [
 | 
					        'string' => [
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										44
									
								
								database/migrations/2023_08_27_163058_create_captcha.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								database/migrations/2023_08_27_163058_create_captcha.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,44 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use Illuminate\Database\Migrations\Migration;
 | 
				
			||||||
 | 
					use Illuminate\Database\Schema\Blueprint;
 | 
				
			||||||
 | 
					use Illuminate\Support\Facades\Schema;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					return new class extends Migration
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Run the migrations.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function up(): void
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        Schema::create('captchas', function (Blueprint $table) {
 | 
				
			||||||
 | 
					            $table->id();
 | 
				
			||||||
 | 
					            $table->uuid('uuid');
 | 
				
			||||||
 | 
					            $table->unsignedBigInteger('captcha_token_id')->index();
 | 
				
			||||||
 | 
					            $table->foreign('captcha_token_id')->references('id')->on('captcha_tokens');
 | 
				
			||||||
 | 
					            $table->timestamps();
 | 
				
			||||||
 | 
					            $table->index('created_at');
 | 
				
			||||||
 | 
					            $table->unique(['uuid', 'captcha_token_id']);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        Schema::create('captcha_logs', function (Blueprint $table) {
 | 
				
			||||||
 | 
					            $table->id();
 | 
				
			||||||
 | 
					            $table->unsignedBigInteger('captcha_id')->index();
 | 
				
			||||||
 | 
					            $table->foreign('captcha_id')->references('id')->on('captchas');
 | 
				
			||||||
 | 
					            $table->unsignedInteger('type')->index();
 | 
				
			||||||
 | 
					            $table->ipAddress('ip')->nullable();
 | 
				
			||||||
 | 
					            $table->string('user_agent')->nullable();
 | 
				
			||||||
 | 
					            $table->text('referer')->nullable();
 | 
				
			||||||
 | 
					            $table->timestamp('created_at')->index();
 | 
				
			||||||
 | 
					            $table->index(['captcha_id', 'type']);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Reverse the migrations.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function down(): void
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        Schema::dropIfExists('captcha_logs');
 | 
				
			||||||
 | 
					        Schema::dropIfExists('captchas');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
@@ -157,20 +157,42 @@
 | 
				
			|||||||
            "Captcha": {
 | 
					            "Captcha": {
 | 
				
			||||||
                "type": "object",
 | 
					                "type": "object",
 | 
				
			||||||
                "properties": {
 | 
					                "properties": {
 | 
				
			||||||
                    "image_base64": {
 | 
					                    "image_head": {
 | 
				
			||||||
                        "type": "string",
 | 
					                        "type": "array",
 | 
				
			||||||
                        "format": "byte"
 | 
					                        "items": {
 | 
				
			||||||
 | 
					                            "$ref": "#/components/schemas/Image",
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
                    },
 | 
					                    },
 | 
				
			||||||
                    "image_text_base64": {
 | 
					                    "image_body": {
 | 
				
			||||||
                        "type": "string",
 | 
					                        "type": "array",
 | 
				
			||||||
                        "format": "byte"
 | 
					                        "items": {
 | 
				
			||||||
 | 
					                            "$ref": "#/components/schemas/Image"
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
                    },
 | 
					                    },
 | 
				
			||||||
                    "captcha_key": {
 | 
					                    "captcha_key": {
 | 
				
			||||||
                        "type": "string"
 | 
					                        "type": "string"
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
                "required": [
 | 
					                "required": [
 | 
				
			||||||
                    "image_base64", "image_text_base64", "captcha_key"
 | 
					                    "image_head", "image_body", "captcha_key"
 | 
				
			||||||
 | 
					                ]
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "Image": {
 | 
				
			||||||
 | 
					                "type": "object",
 | 
				
			||||||
 | 
					                "properties": {
 | 
				
			||||||
 | 
					                    "base64": {
 | 
				
			||||||
 | 
					                        "type": "string",
 | 
				
			||||||
 | 
					                        "format": "byte"
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                    "width": {
 | 
				
			||||||
 | 
					                        "type": "integer"
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                    "height": {
 | 
				
			||||||
 | 
					                        "type": "integer"
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                "required": [
 | 
				
			||||||
 | 
					                    "base64", "width", "height"
 | 
				
			||||||
                ]
 | 
					                ]
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            "CaptchaVerification": {
 | 
					            "CaptchaVerification": {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user