defmodule WhoNeedHelp.GoogleAuthFake do @behaviour WhoNeedHelp.GoogleAuth @impl true def enabled?, do: true @impl true def authorize_url(redirect_uri) do {:ok, %{ url: "https://accounts.google.example/authorize?" <> URI.encode_query(%{"redirect_uri" => redirect_uri, "state" => "google-test-state"}), session_params: %{ state: "google-test-state", nonce: "google-test-nonce", code_verifier: "google-test-verifier" } }} end @impl true def callback(_redirect_uri, params, %{state: state}) do cond do params["state"] != state -> {:error, :invalid_state} params["code"] in [nil, ""] -> {:error, :missing_code} params["email_verified"] == "false" -> {:error, :email_not_verified} true -> email = params["email"] || "google-user@example.com" {:ok, %{ provider_uid: params["uid"] || "google-user-42", email: email, email_verified: true, display_name: params["name"] || "Google Neighbor", hosted_domain: normalize_hosted_domain(params["hd"]) }} end end @impl true def client_id, do: {:ok, "google-native-test-client.apps.googleusercontent.com"} @impl true def verify_id_token(id_token, nonce) do with ["native-test", encoded_nonce, provider_uid, encoded_email, encoded_name] <- String.split(id_token, ":", parts: 5), {:ok, token_nonce} <- Base.url_decode64(encoded_nonce, padding: false), true <- token_nonce == nonce, {:ok, email} <- Base.url_decode64(encoded_email, padding: false), {:ok, name} <- Base.url_decode64(encoded_name, padding: false) do {:ok, %{ provider_uid: provider_uid, email: String.downcase(email), email_verified: true, display_name: name, hosted_domain: nil }} else _invalid_or_replayed -> {:error, :invalid_id_token} end end defp normalize_hosted_domain(domain) when is_binary(domain) do case domain |> String.trim() |> String.downcase() do "" -> nil normalized -> normalized end end defp normalize_hosted_domain(_domain), do: nil end