126 lines
5.9 KiB
PHP
126 lines
5.9 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Api;
|
|
|
|
use App\Exceptions\DuplicateGameAccountException;
|
|
use App\Exceptions\InviteCodeException;
|
|
use App\Http\Controllers\Controller;
|
|
use App\Http\Requests\RegisterGameAccountRequest;
|
|
use App\Services\AzerothCoreAccountRegistrar;
|
|
use App\Services\InviteCodeService;
|
|
use Illuminate\Http\JsonResponse;
|
|
use OpenApi\Attributes as OA;
|
|
use Throwable;
|
|
|
|
class LauncherRegistrationController extends Controller
|
|
{
|
|
#[OA\Post(
|
|
path: '/api/launcher/register',
|
|
summary: 'Зарегистрировать игровой аккаунт',
|
|
description: 'Создаёт игровой аккаунт AzerothCore. Инвайт-код обязателен, если на сервере включена регистрация по приглашениям.',
|
|
tags: ['Launcher Auth'],
|
|
requestBody: new OA\RequestBody(
|
|
required: true,
|
|
content: new OA\JsonContent(
|
|
required: ['username', 'email', 'password', 'password_confirmation', 'terms'],
|
|
properties: [
|
|
new OA\Property(property: 'username', type: 'string', minLength: 3, maxLength: 32, pattern: '^[A-Za-z0-9]+$', example: 'Player'),
|
|
new OA\Property(property: 'email', type: 'string', format: 'email', maxLength: 255, example: 'player@example.com'),
|
|
new OA\Property(property: 'invite_code', type: 'string', minLength: 6, maxLength: 32, nullable: true, example: 'ABCD-EFGH-IJKL'),
|
|
new OA\Property(property: 'password', type: 'string', minLength: 8, maxLength: 32, example: 'Secret123'),
|
|
new OA\Property(property: 'password_confirmation', type: 'string', minLength: 8, maxLength: 32, example: 'Secret123'),
|
|
new OA\Property(property: 'terms', type: 'boolean', example: true, description: 'Согласие с правилами сервера и пользовательским соглашением'),
|
|
],
|
|
),
|
|
),
|
|
responses: [
|
|
new OA\Response(
|
|
response: 201,
|
|
description: 'Аккаунт создан',
|
|
content: new OA\JsonContent(
|
|
properties: [
|
|
new OA\Property(property: 'message', type: 'string', example: 'Игровой аккаунт успешно создан.'),
|
|
new OA\Property(
|
|
property: 'account',
|
|
properties: [
|
|
new OA\Property(property: 'id', type: 'integer', example: 77),
|
|
new OA\Property(property: 'username', type: 'string', example: 'PLAYER'),
|
|
],
|
|
type: 'object',
|
|
),
|
|
],
|
|
),
|
|
),
|
|
new OA\Response(
|
|
response: 422,
|
|
description: 'Ошибка валидации, занятый логин или неверный инвайт-код',
|
|
content: new OA\JsonContent(
|
|
properties: [
|
|
new OA\Property(property: 'message', type: 'string', example: 'Такой игровой аккаунт уже существует.'),
|
|
new OA\Property(
|
|
property: 'errors',
|
|
type: 'object',
|
|
additionalProperties: new OA\AdditionalProperties(
|
|
type: 'array',
|
|
items: new OA\Items(type: 'string'),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
new OA\Response(
|
|
response: 500,
|
|
description: 'Внутренняя ошибка регистрации',
|
|
content: new OA\JsonContent(
|
|
properties: [
|
|
new OA\Property(property: 'message', type: 'string', example: 'Не удалось создать аккаунт. Попробуй снова позже.'),
|
|
],
|
|
),
|
|
),
|
|
new OA\Response(response: 429, description: 'Слишком много запросов'),
|
|
],
|
|
)]
|
|
public function store(
|
|
RegisterGameAccountRequest $request,
|
|
AzerothCoreAccountRegistrar $registrar,
|
|
InviteCodeService $inviteCodes,
|
|
): JsonResponse {
|
|
try {
|
|
$register = fn (): array => $registrar->register(
|
|
$request->string('username')->toString(),
|
|
$request->string('email')->toString(),
|
|
$request->string('password')->toString(),
|
|
);
|
|
|
|
$account = config('moonwell.registration.require_invite_code')
|
|
? $inviteCodes->redeemForRegistration(
|
|
$request->string('invite_code')->toString(),
|
|
$request->string('username')->toString(),
|
|
$register,
|
|
)
|
|
: $register();
|
|
} catch (DuplicateGameAccountException|InviteCodeException $exception) {
|
|
return response()->json([
|
|
'message' => $exception->getMessage(),
|
|
'errors' => [
|
|
$exception->field => [$exception->getMessage()],
|
|
],
|
|
], 422);
|
|
} catch (Throwable $exception) {
|
|
report($exception);
|
|
|
|
return response()->json([
|
|
'message' => 'Не удалось создать аккаунт. Попробуй снова позже.',
|
|
], 500);
|
|
}
|
|
|
|
return response()->json([
|
|
'message' => 'Игровой аккаунт успешно создан.',
|
|
'account' => [
|
|
'id' => $account['id'],
|
|
'username' => $account['username'],
|
|
],
|
|
], 201);
|
|
}
|
|
}
|