defmodule MobileIdToken do @moduledoc """ Verifies mobile OAuth `id_token` JWTs issued by Apple and Google. `verify/3` is the provider-agnostic entrypoint. It delegates to `MobileIdToken.Apple` and `MobileIdToken.Google`. """ alias MobileIdToken.{Apple, Google} @type provider :: :apple | :google @typedoc """ Verification options. - `:client_ids` - accepted `aud` values (list, comma-separated string, or single string) - `:nonce` - expected nonce (Apple expects this to be present; Google allows `nil`) The library does not read host app env vars directly; pass resolved client IDs explicitly. """ @type verify_opts :: [client_ids: [String.t()] | String.t(), nonce: String.t() | nil] @type verify_error :: :invalid_token | :missing_kid | :jwk_not_found | :invalid_signature | :invalid_issuer | :missing_client_id | :invalid_audience | :token_expired | :invalid_claims | :email_not_verified | :invalid_nonce | :jwks_unavailable | :unsupported_provider @doc """ Verifies an OAuth `id_token` for the given provider. ## Examples iex> MobileIdToken.verify(:google, token, client_ids: ["my-client-id"]) {:ok, claims} iex> MobileIdToken.verify(:apple, token, client_ids: ["com.example.app"], nonce: "abc123") {:ok, claims} """ @spec verify(provider(), String.t(), verify_opts()) :: {:ok, map()} | {:error, verify_error()} def verify(provider, id_token, opts \\ []) def verify(:apple, id_token, opts), do: Apple.verify_id_token(id_token, opts) def verify(:google, id_token, opts), do: Google.verify_id_token(id_token, opts) def verify(_provider, _id_token, _opts), do: {:error, :unsupported_provider} end