aegida-console / app / api / auth / login / route.ts
route.ts
Raw
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
  );
}