# `MobDev.GooglePlay.OAuth`
[🔗](https://github.com/genericjam/mob_dev/blob/main/lib/mob_dev/google_play/oauth.ex#L1)

OAuth2 browser-based authorization for Google APIs.

Opens the user's default browser to Google's consent screen, then listens
on a random localhost port for the authorization code callback. No external
CLI tool (gcloud, etc.) is required — only a browser.

## OAuth client registration

This module ships with placeholder client credentials. Before `authorize/1`
will work you must register a Google OAuth "Desktop app" client:

  1. Go to https://console.cloud.google.com/apis/credentials
  2. Click **Create credentials → OAuth client ID**
  3. Application type: **Desktop app** — name it `mob_dev CLI`
  4. Click **Create** — note the **Client ID** and **Client secret**
  5. Fill in `@default_client_id` and `@default_client_secret` in this file

For installed CLI tools, the client_secret is not actually secret — this
follows Google's documented guidance for desktop applications (the same
model used by the gcloud CLI). The token is only obtainable by a user who
explicitly grants consent via their browser.

You can also override with environment variables:
`GOOGLE_OAUTH_CLIENT_ID` / `GOOGLE_OAUTH_CLIENT_SECRET`.

# `authorize`

```elixir
@spec authorize(keyword()) :: {:ok, String.t()} | {:error, String.t()}
```

Runs the browser-based OAuth2 flow and returns a bearer access token.

Opens the user's browser to the Google consent screen, then waits up to
`timeout_ms` milliseconds (default 120 000) for the callback redirect.

Options:
- `:scopes` — list of OAuth scope strings (required)
- `:timeout_ms` — callback wait timeout in ms (default: 120_000)

Returns `{:ok, access_token}` or `{:error, reason}`.

# `build_auth_url`

```elixir
@spec build_auth_url(String.t(), [String.t()], String.t()) :: String.t()
```

Builds the Google OAuth2 authorization URL.

Pure function — useful for testing and for displaying the URL in case
the automatic browser open fails.

# `parse_callback_request`

```elixir
@spec parse_callback_request(String.t()) :: {:ok, String.t()} | {:error, String.t()}
```

Parses the authorization code from an OAuth callback HTTP request line.

The request line has the form:
    GET /callback?code=AUTH_CODE&scope=... HTTP/1.1

Returns `{:ok, code}` or `{:error, reason}`.

# `setup_scopes`

```elixir
@spec setup_scopes() :: [String.t()]
```

Returns the scopes requested during the setup wizard OAuth flow.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
