Files
casadoc/public/userportal/api/login.php
T
2026-07-27 21:04:07 +03:00

69 lines
2.4 KiB
PHP

<?php
require __DIR__ . '/_bootstrap.php';
/**
* @OA\Post(
* path="/login.php",
* tags={"Auth"},
* summary="Log in, issue bearer token",
* security={},
* @OA\RequestBody(required=true, @OA\JsonContent(
* required={"login","password","device_name"},
* @OA\Property(property="login", type="string", description="e-mail or username"),
* @OA\Property(property="password", type="string", format="password"),
* @OA\Property(property="device_name", type="string", example="iPhone 15")
* )),
* @OA\Response(response=200, description="Success", @OA\JsonContent(
* @OA\Property(property="data", type="object",
* @OA\Property(property="token", type="string"),
* @OA\Property(property="user", ref="#/components/schemas/User")
* )
* )),
* @OA\Response(response=401, ref="#/components/responses/Unauthorized"),
* @OA\Response(response=403, description="E-mail not verified (code email_not_verified)",
* @OA\JsonContent(ref="#/components/schemas/Error")),
* @OA\Response(response=422, ref="#/components/responses/ValidationError")
* )
*/
require_method('POST');
$in = body();
$login = trim((string) ($in['login'] ?? ''));
$pass = (string) ($in['password'] ?? '');
$device = trim((string) ($in['device_name'] ?? ''));
$fields = [];
if ($login === '') { $fields['login'] = ['Required']; }
if ($pass === '') { $fields['password'] = ['Required']; }
if ($device === '') { $fields['device_name'] = ['Required']; }
if ($fields) {
json_error(422, 'Validation failed', $fields);
}
$stmt = $pdo->prepare('SELECT * FROM auth_users WHERE email = ? OR username = ? LIMIT 1');
$stmt->execute([$login, $login]);
$user = $stmt->fetch();
if (!$user || !password_verify($pass, (string) $user['password'])) {
json_error(401, 'Invalid credentials');
}
// Distinct code so the app opens the verification screen instead of blaming the password.
if (empty($user['email_verified_at'])) {
json_error(403, 'E-mail is not verified', null, 'email_not_verified');
}
$plain = bin2hex(random_bytes(32));
$config = require __DIR__ . '/config.php';
$expires = (new DateTimeImmutable("+{$config['token_ttl_days']} days"))->format('Y-m-d H:i:s');
$pdo->prepare(
'INSERT INTO api_tokens (user_id, name, token, expires_at, created_at)
VALUES (?, ?, ?, ?, NOW())'
)->execute([$user['id'], $device, hash('sha256', $plain), $expires]);
json_data([
'token' => $plain,
'user' => present_user($user),
]);