import { signAuthToken, toAuthIdentity } from "@/lib/auth/server";
import type { AuthIdentity } from "@/lib/auth/types";
import {
UserServiceAuthError,
authenticateWithUserService,
} from "@/lib/auth/user-service";
import { getPool } from "@/lib/db/pool";
import { upsertExternalUser } from "@/lib/db/users";
const noStoreHeaders = { "Cache-Control": "no-store" };
export async function POST(request: Request): Promise<Response> {
let body: unknown;
try {
body = await request.json();
} catch {
return Response.json(
{ error: "Некорректный запрос" },
{ status: 400, headers: noStoreHeaders },
);
}
if (!isCredentials(body)) {
return Response.json(
{ error: "Некорректный запрос" },
{ status: 400, headers: noStoreHeaders },
);
}
let profile: Awaited<ReturnType<typeof authenticateWithUserService>>;
try {
profile = await authenticateWithUserService(
body.email.trim(),
body.password,
request.signal,
);
} catch (error) {
return Response.json(
{
error:
error instanceof UserServiceAuthError && error.reason === "invalid_credentials"
? "Неверная почта или пароль"
: "Сервис аутентификации временно недоступен",
},
{
status:
error instanceof UserServiceAuthError && error.reason === "invalid_credentials"
? 401
: 503,
headers: noStoreHeaders,
},
);
}
let user: AuthIdentity;
try {
user = toAuthIdentity(await upsertExternalUser(getPool(), profile));
} catch {
return Response.json(
{ error: "Сервис аутентификации временно недоступен" },
{ status: 503, headers: noStoreHeaders },
);
}
const token = await signAuthToken(user);
return Response.json({ token, user }, { headers: noStoreHeaders });
}
function isCredentials(value: unknown): value is { email: string; password: string } {
return (
typeof value === "object" &&
value !== null &&
"email" in value &&
"password" in value &&
typeof value.email === "string" &&
value.email.trim().length > 0 &&
typeof value.password === "string" &&
value.password.trim().length > 0
);
}