84 lines
2.8 KiB
PHP
84 lines
2.8 KiB
PHP
<?php
|
|
require __DIR__ . '/_bootstrap.php';
|
|
require __DIR__ . '/_codes.php';
|
|
require __DIR__ . '/_mail.php';
|
|
|
|
/**
|
|
* @OA\Post(
|
|
* path="/register.php",
|
|
* tags={"Auth"},
|
|
* summary="Register an account and send a verification code",
|
|
* description="No token is issued: the e-mail must be confirmed via email-verify.php first.",
|
|
* security={},
|
|
* @OA\RequestBody(required=true, @OA\JsonContent(
|
|
* required={"email","password"},
|
|
* @OA\Property(property="email", type="string", format="email"),
|
|
* @OA\Property(property="password", type="string", format="password", minLength=8),
|
|
* @OA\Property(property="first_name", type="string"),
|
|
* @OA\Property(property="last_name", type="string")
|
|
* )),
|
|
* @OA\Response(response=201, ref="#/components/responses/Success"),
|
|
* @OA\Response(response=422, ref="#/components/responses/ValidationError")
|
|
* )
|
|
*/
|
|
require_method('POST');
|
|
|
|
$in = body();
|
|
$email = trim((string) ($in['email'] ?? ''));
|
|
$password = (string) ($in['password'] ?? '');
|
|
|
|
debug_log("register: {$email}");
|
|
|
|
$fields = [];
|
|
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
|
$fields['email'] = ['Valid email required'];
|
|
}
|
|
if (strlen($password) < 8) {
|
|
$fields['password'] = ['At least 8 characters'];
|
|
}
|
|
if ($fields) {
|
|
debug_log('register: rejected, ' . json_encode($fields) . ' — no code is sent');
|
|
json_error(422, 'Validation failed', $fields);
|
|
}
|
|
|
|
$exists = $pdo->prepare('SELECT id, created_at, email_verified_at FROM auth_users WHERE email = ? LIMIT 1');
|
|
$exists->execute([$email]);
|
|
if ($row = $exists->fetch()) {
|
|
debug_log(sprintf(
|
|
'register: already registered — id=%s created_at=%s verified=%s. No code is sent; log in instead.',
|
|
$row['id'],
|
|
$row['created_at'],
|
|
$row['email_verified_at'] ?: 'no'
|
|
));
|
|
json_error(422, 'Validation failed', ['email' => ['Already registered']]);
|
|
}
|
|
|
|
$pdo->beginTransaction();
|
|
try {
|
|
// role_id 2 is "User"; 1 is "Admin" and must never be handed out here.
|
|
$pdo->prepare(
|
|
"INSERT INTO auth_users (email, password, first_name, last_name, role_id, status, email_verified_at, created_at, updated_at)
|
|
VALUES (?, ?, ?, ?, 2, 'Active', NULL, NOW(), NOW())"
|
|
)->execute([
|
|
$email,
|
|
password_hash($password, PASSWORD_DEFAULT),
|
|
trim((string) ($in['first_name'] ?? '')) ?: null,
|
|
trim((string) ($in['last_name'] ?? '')) ?: null,
|
|
]);
|
|
|
|
$code = issue_code($pdo, 'auth_email_verifications', $email);
|
|
$pdo->commit();
|
|
debug_log('register: account created, code ' . ($code ? 'issued' : 'THROTTLED (one per 60s)'));
|
|
} catch (Throwable $e) {
|
|
$pdo->rollBack();
|
|
debug_log('register: rolled back — ' . $e->getMessage());
|
|
throw $e;
|
|
}
|
|
|
|
if ($code) {
|
|
send_code_mail($email, $code);
|
|
}
|
|
|
|
http_response_code(201);
|
|
echo json_encode(['success' => true]);
|