Files
2026-06-04 02:41:08 -04:00

128 lines
4.5 KiB
PHP

<?php
namespace App\Services\Auth;
use App\Models\Configuration;
use App\Models\Role;
use App\Models\User;
use App\Models\UserRole;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Validator;
use PHPOpenSourceSaver\JWTAuth\Facades\JWTAuth;
/**
* Handles direct public API registration requests that bypass the captcha flow.
*/
class ApiRegistrationService
{
public function registerResponse(Request $request): JsonResponse
{
$requestData = $request->all();
if ($request->isJson() && ($requestData === [] || $requestData === null)) {
$decoded = json_decode((string) $request->getContent(), true);
$requestData = is_array($decoded) ? $decoded : [];
}
$validator = Validator::make($requestData, [
'firstname' => ['required', 'string', 'min:2', 'max:30'],
'lastname' => ['required', 'string', 'min:2', 'max:30'],
'email' => ['required', 'email'],
'password' => ['required', 'string', 'min:8'],
'cellphone' => ['required', 'string', 'min:10', 'max:20'],
'gender' => ['nullable', 'string'],
'address_street' => ['nullable', 'string'],
'city' => ['nullable', 'string'],
'state' => ['nullable', 'string'],
'zip' => ['nullable', 'string'],
'role' => ['nullable', 'string'],
]);
if ($validator->fails()) {
return response()->json([
'status' => false,
'message' => 'Validation failed',
'errors' => $validator->errors()->toArray(),
], 422);
}
/** @var array<string, mixed> $data */
$data = $validator->validated();
if (User::query()->where('email', $data['email'])->exists()) {
return response()->json([
'status' => false,
'message' => 'Email already registered',
], 422);
}
$schoolYear = Configuration::getConfig('school_year');
$semester = Configuration::getConfig('semester');
$userData = [
'firstname' => $data['firstname'],
'lastname' => $data['lastname'],
'email' => $data['email'],
'password' => pbkdf2_hash((string) $data['password']),
'cellphone' => $data['cellphone'],
'gender' => $data['gender'] ?? null,
'address_street' => $data['address_street'] ?? '',
'city' => $data['city'] ?? '',
'state' => $data['state'] ?? '',
'zip' => $data['zip'] ?? '',
'school_year' => $schoolYear,
'semester' => $semester ?? '',
'status' => 'active',
'is_verified' => 0,
'accept_school_policy' => 0,
];
try {
$userId = null;
$rolesForResponse = [];
DB::transaction(function () use ($userData, $data, &$userId, &$rolesForResponse): void {
$user = User::query()->create($userData);
$userId = (int) $user->id;
if (($data['role'] ?? '') === 'parent') {
$role = Role::query()->where('name', 'parent')->first();
if ($role) {
UserRole::query()->create([
'user_id' => $userId,
'role_id' => (int) $role->id,
]);
$rolesForResponse = ['parent'];
}
}
});
$user = User::query()->findOrFail($userId);
$token = JWTAuth::fromUser($user);
$fullName = trim((string) $user->firstname.' '.(string) $user->lastname);
return response()->json([
'status' => true,
'message' => 'Registration successful. Please verify your email.',
'token' => $token,
'user' => [
'id' => $userId,
'name' => $fullName,
'email' => $userData['email'],
'roles' => $rolesForResponse,
],
], 201);
} catch (\Throwable $e) {
Log::error('Registration error: '.$e->getMessage());
return response()->json([
'status' => false,
'message' => 'Registration failed. Please try again.',
], 500);
}
}
}