import { d as defineEventHandler, aG as requireFeature, $ as getAuthRequestContext, c as createError, j as getQuery, aH as consumeLoginState, aI as findSsoProviderById, aJ as exchangeCodeForTokens, aK as verifyIdToken, aL as fetchOidcUserInfo, aM as mapClaimsToProfile, aN as resolveSsoLogin, a3 as tryGetTenantContext, a4 as getDefaultTenantId, a5 as isMfaEnabledGlobally, a6 as getAdminMfaState, a7 as isMfaRequiredForRole, a8 as issueMfaChallenge, a2 as emitAdminLoginFailed, aO as getRequestHeader, a9 as MFA_CHALLENGE_TTL_SECONDS, aP as sendRedirect, aa as generateAdminJWTForTenant, ab as emitAdminAfterLogin } from '../../../../../../nitro/nitro.mjs';
import { g as getServerBaseUrl, b as buildSsoCallbackUrl } from '../../../../../../_/url-helpers.mjs';
import 'node:crypto';
import 'jsonwebtoken';
import 'node:fs';
import 'node:module';
import 'node:path';
import 'node:url';
import 'node:http';
import 'node:https';
import 'node:events';
import 'node:buffer';
import 'pino';
import 'drizzle-orm/better-sqlite3';
import 'drizzle-orm/node-postgres';
import 'drizzle-orm/mysql2';
import 'better-sqlite3';
import 'pg';
import 'mysql2/promise';
import 'drizzle-orm';
import 'fs';
import 'path';
import 'prom-client';
import 'bcryptjs';
import '@node-rs/argon2';
import 'node:async_hooks';
import 'crypto';
import 'node:dns';
import 'node:util';
import 'node:net';
import 'fs/promises';
import 'url';
import 'semver';

function buildSpaRedirect(base, token, redirectAfter) {
  const params = new URLSearchParams({ token });
  if (redirectAfter) {
    params.set("redirect", redirectAfter);
  }
  return `${base}/admin/sso/callback#${params.toString()}`;
}
function buildSpaMfaRedirect(base, challengeToken, purpose, redirectAfter) {
  const params = new URLSearchParams({ challenge: challengeToken, purpose });
  if (redirectAfter) {
    params.set("redirect", redirectAfter);
  }
  return `${base}/admin/sso/callback#${params.toString()}`;
}
function buildSpaErrorRedirect(base, message) {
  const params = new URLSearchParams({ error: message });
  return `${base}/admin/login?${params.toString()}`;
}
const callback_get = defineEventHandler(async (event) => {
  var _a, _b, _c, _d, _e, _f;
  await requireFeature("enterprise.sso", event);
  const slug = (_a = event.context.params) == null ? void 0 : _a.slug;
  const reqCtx = getAuthRequestContext(event);
  const baseUrl = getServerBaseUrl(event);
  if (!slug || typeof slug !== "string") {
    throw createError({
      statusCode: 400,
      statusMessage: "Bad Request",
      message: "Provider slug is required"
    });
  }
  const query = getQuery(event);
  try {
    if (query.error) {
      throw new Error(
        `Identity provider returned error: ${query.error}` + (query.error_description ? ` (${query.error_description})` : "")
      );
    }
    const code = typeof query.code === "string" ? query.code : null;
    const state = typeof query.state === "string" ? query.state : null;
    if (!code || !state) {
      throw new Error("Missing code or state in callback");
    }
    const loginState = await consumeLoginState(state);
    if (!loginState) {
      throw new Error("Login state expired or invalid (possible CSRF)");
    }
    const provider = await findSsoProviderById(loginState.providerId);
    if (!provider || !provider.isEnabled) {
      throw new Error("SSO provider not found or disabled");
    }
    if (provider.slug !== slug) {
      throw new Error("Provider slug mismatch");
    }
    if (provider.type === "saml") {
      throw new Error("SAML callback is not supported on this endpoint");
    }
    const config = provider.config;
    const callbackUrl = buildSsoCallbackUrl(event, provider.slug);
    const tokens = await exchangeCodeForTokens({
      config,
      code,
      redirectUri: callbackUrl,
      codeVerifier: (_b = loginState.codeVerifier) != null ? _b : void 0
    });
    const idTokenClaims = await verifyIdToken({
      config,
      idToken: tokens.id_token,
      nonce: loginState.nonce
    });
    const userInfo = await fetchOidcUserInfo(config, tokens.access_token);
    const profile = mapClaimsToProfile(config, idTokenClaims, userInfo);
    const result = await resolveSsoLogin(provider, profile);
    const tenant = tryGetTenantContext(event);
    const tenantId = (_c = tenant == null ? void 0 : tenant.id) != null ? _c : await getDefaultTenantId();
    const mfaEnabled = isMfaEnabledGlobally();
    const mfaState = mfaEnabled ? await getAdminMfaState(result.user.id) : null;
    const mfaRequired = mfaEnabled && isMfaRequiredForRole(result.user.role);
    if (mfaEnabled && ((mfaState == null ? void 0 : mfaState.enabled) || mfaRequired)) {
      const purpose = (mfaState == null ? void 0 : mfaState.enabled) ? "login" : "enroll";
      const challengeToken = issueMfaChallenge({
        sub: result.user.id,
        username: result.user.username,
        email: result.user.email,
        role: result.user.role,
        tid: tenantId,
        purpose,
        baseAmr: ["sso"]
      });
      await emitAdminLoginFailed(result.user.email, "mfa_required", reqCtx);
      const accept2 = (_d = getRequestHeader(event, "accept")) != null ? _d : "";
      if (accept2.includes("application/json")) {
        return {
          success: true,
          data: {
            mfaRequired: true,
            mfaPurpose: purpose,
            challengeToken,
            challengeExpiresIn: MFA_CHALLENGE_TTL_SECONDS
          }
        };
      }
      return sendRedirect(
        event,
        buildSpaMfaRedirect(baseUrl, challengeToken, purpose, loginState.redirectAfter),
        302
      );
    }
    const adminToken = generateAdminJWTForTenant(
      {
        id: result.user.id,
        username: result.user.username,
        email: result.user.email,
        role: result.user.role
      },
      tenantId
    );
    await emitAdminAfterLogin(
      result.user.id,
      result.user.email,
      result.user.username,
      result.user.role,
      reqCtx
    );
    const accept = (_e = getRequestHeader(event, "accept")) != null ? _e : "";
    if (accept.includes("application/json")) {
      return {
        success: true,
        data: {
          token: adminToken,
          user: {
            id: result.user.id,
            username: result.user.username,
            email: result.user.email,
            firstName: result.user.firstName,
            lastName: result.user.lastName,
            role: result.user.role
          },
          provisioned: result.wasProvisioned,
          identityLinked: result.identityLinked
        }
      };
    }
    return sendRedirect(
      event,
      buildSpaRedirect(baseUrl, adminToken, loginState.redirectAfter),
      302
    );
  } catch (error) {
    const message = error instanceof Error ? error.message : "SSO callback failed";
    console.error(`[GET /api/admin/auth/sso/${slug}/callback] Error:`, message);
    await emitAdminLoginFailed(`sso:${slug}`, "sso_error", reqCtx);
    const accept = (_f = getRequestHeader(event, "accept")) != null ? _f : "";
    if (accept.includes("application/json")) {
      throw createError({
        statusCode: 401,
        statusMessage: "SSO Login Failed",
        message
      });
    }
    return sendRedirect(event, buildSpaErrorRedirect(baseUrl, message), 302);
  }
});

export { callback_get as default };
//# sourceMappingURL=callback.get.mjs.map
