/**
 * jwt-exp — defensive decoder for JWT `exp` claims.
 *
 * Why this exists:
 *
 *   The wizard's `~/.ampli.json` stores ONE `expiresAt` field per stored
 *   token entry. Until 2026-04, that field was stamped with one of three
 *   numbers depending on which code path persisted the entry:
 *
 *     - `bin.ts` login subcommand: `Date.now() + 3600 * 1000` (1 hour
 *       hardcode — accidentally aligned to id_token TTL)
 *     - `oauth.ts` initial OAuth flow: `Date.now() + tokenResponse.expires_in
 *       * 1000` (access_token TTL — 24 hours from Ory)
 *     - `setup-utils.ts` hosted-signup flow: another 1-hour hardcode
 *
 *   The wizard authenticates with the id_token (not the access_token) for
 *   every `fetchAmplitudeUser` / `getAPIKey` call. The id_token's TTL is
 *   1 hour (Ory default for OIDC); the access_token's TTL is 24 hours.
 *   Storing the access_token TTL meant the proactive-refresh trigger at
 *   `tryRefreshToken` could miss a stale id_token by up to 23 hours.
 *
 *   This module pulls `exp` directly from the id_token JWT so the stored
 *   `expiresAt` reflects the binding constraint (id_token expiry) rather
 *   than whichever number happened to be in scope at the call site.
 *
 * Security note:
 *
 *   We do NOT verify the JWT signature here. The wizard receives these
 *   tokens directly from Ory over TLS and only uses them as bearer
 *   credentials in subsequent requests; signature validation is the
 *   server's job. This decoder is for reading our own already-trusted
 *   tokens, not for accepting tokens from external callers.
 */
/**
 * Decode the `exp` claim from a JWT and return it as Unix epoch ms.
 *
 * Returns `null` when the token can't be decoded, doesn't carry an
 * `exp` claim, or the claim is outside a sane range. The caller should
 * fall back to a TTL it computes another way (server `expires_in`, or
 * a conservative hardcoded default) — never throw.
 *
 * @param token Compact JWT (`<header>.<payload>.<signature>`)
 * @param now Reference time for sanity checks. Override for tests.
 */
export declare function decodeJwtExpiryMs(token: string | undefined | null, now?: number): number | null;
/**
 * Decode the issuer (`iss`) of a JWT and map it to an Amplitude zone.
 *
 * Account zone (where the user's OAuth identity lives) is independent of
 * the env's data zone (where ingested events go). The bearer's `iss`
 * is the only authoritative signal for which MCP host will accept it —
 * resolveZone reflects the data-zone the user picked, not the
 * account zone.
 *
 * Picking an EU env in a US-account org used to derive `mcp.eu.amplitude.com`
 * from the resolved zone, then pass a US-issued bearer to it, and EU
 * MCP 401'd with `invalid_token`. Routing MCP off this helper keeps the
 * bearer's zone authoritative, so the data-zone choice doesn't bleed
 * into auth.
 *
 * Returns `null` for unparseable / unknown-issuer tokens so callers can
 * fall back to their existing zone fallback. Never throws.
 */
export declare function decodeJwtZone(token: string | undefined | null): 'us' | 'eu' | null;
/**
 * Decode the `iss` (issuer) and `aud` (audience) claims from a JWT.
 *
 * Used by `getStoredToken` to drop tokens that were issued by a different
 * OAuth client than the one this wizard build is configured to use. This
 * catches the "user upgraded from an old wizard version" case where the
 * stored token still passes the expiry check but was minted against a
 * client_id that's no longer in the running build's `AMPLITUDE_ZONE_SETTINGS`.
 *
 * Returns `null` for unparseable tokens so callers can fall back to the
 * pre-existing behavior (treat the token as opaquely usable). Never throws.
 */
export declare function decodeJwtIssAud(token: string | undefined | null): {
    iss: string | null;
    aud: string[] | null;
} | null;
/**
 * Convenience helper for the common write-time pattern: prefer the
 * id_token's `exp`, fall back to a server-supplied `expires_in`
 * (seconds), fall back to a 1-hour conservative default.
 *
 * Returns Unix epoch ms.
 */
export declare function resolveStoredExpiryMs(opts: {
    /** OIDC id_token, when available. Authoritative when present. */
    idToken?: string | null;
    /** OAuth `expires_in` from the token endpoint, in seconds. */
    expiresInSeconds?: number;
    /** Reference time for sanity checks. Override for tests. */
    now?: number;
}): number;
