// PAM MFA verification.
//
// v1 stub: accepts any 6-digit code as valid. Real implementation
// will use FreeIPA's `ipa otptoken-find` to locate the user's
// configured OTP token and verify the supplied code against it
// (RFC 6238 TOTP). Tracked in docs/pam-plan.md §11.
//
// Why ship a stub: the plan locks MFA as optional opt-in (decision
// #1). Only `platformadmins` currently requires MFA. Stubbing means
// the request flow can land end-to-end now; we tighten verification
// before opening manual+MFA policies to anyone outside the security
// team.

export interface MfaVerifyInput {
  gscsid: string;       // requester's FreeIPA uid
  token: string;        // 6-digit OTP entered in the request form
}

export interface MfaVerifyResult {
  ok: boolean;
  reason?: string;
  /** Structured payload stored in privilege_grants.mfa_evidence */
  evidence?: {
    method: "totp";
    verified_at: string;
    stub: true;
  };
}

export async function verifyMfa(input: MfaVerifyInput): Promise<MfaVerifyResult> {
  const token = input.token?.trim() ?? "";
  if (!/^\d{6}$/.test(token)) {
    return { ok: false, reason: "invalid_format" };
  }
  // TODO(pam-mfa): replace with real TOTP verification against
  // FreeIPA otptoken (ipa otptoken-find + RFC 6238 step ±1).
  return {
    ok: true,
    evidence: {
      method: "totp",
      verified_at: new Date().toISOString(),
      stub: true,
    },
  };
}
