# Athena Auth API examples

Curl samples for **Better Auth–style** routes relative to **`/api/auth`** (default). Request/response JSON field names match the TypeScript-oriented API (**camelCase**), e.g. `newPassword`, `redirectTo`.

**Note:** Root [`openapi.yaml`](../openapi.yaml) is synced to the current Athena Auth route surface. These scripts and [`tests/compat/`](../tests/compat/) remain the fastest route-contract check for real request/response flows.

## Prerequisites

- A running server (default origin `http://localhost:3000`).
- `curl`.
- Optional: `jq` for pretty-printed JSON (scripts still work without it).

## Environment

| Variable | Default | Meaning |
|----------|---------|---------|
| `ATHENA_AUTH_ORIGIN` | `http://localhost:3000` | Scheme + host (+ optional port), **no** trailing slash |
| `ATHENA_AUTH_BASE` | `$ORIGIN/api/auth` | Full prefix for auth routes (overrides the default join if set) |
| `ATHENA_AUTH_COOKIE_JAR` | `/tmp/athena-auth-examples.cookies` (or `%TMP%` on Windows via Git Bash) | Cookie store for cookie-based session demos |
| `TOKEN` | — | Session JWT from sign-up / sign-in responses (`token` field) |
| `API_KEY_ID` | — | For `/api-key/get`, `/api-key/update`, `/api-key/delete` |
| `RAW_API_KEY` | — | Plain key string for `POST /api-key/verify` |
| `PROVIDER_ID` | — | OAuth account provider id for `/refresh-token` and `/get-access-token` |
| `TOTP_CODE` | — | For `/two-factor/verify-totp` |
| `RESET_TOKEN` | — | Password reset token (from email or dev logs) |
| `PASSKEY_REGISTRATION_BODY_JSON` | — | Full JSON body for `POST /passkey/verify-registration` |
| `PASSKEY_AUTHENTICATION_BODY_JSON` | — | Full JSON body for `POST /passkey/verify-authentication` |

## Session: Bearer vs cookies

- Many responses include a **`token`** string; pass it as `Authorization: Bearer <token>` (see compat tests).
- If your server sets a **session cookie** on sign-in, use the same cookie jar for `get-session` / `sign-out`: set `ATHENA_AUTH_COOKIE_JAR` and use scripts that pass `-c`/`-b` (see `sign_in_email_cookies.sh`).

## REST Client (VS Code)

See [`http/`](http/) for `.http` files using `@BASE`.

## Curl scripts

Run from repo root (or any directory); scripts resolve `lib/common.sh` via their own path.

### Probes (core)

| Script | Description |
|--------|-------------|
| [`curl/probe_ok.sh`](curl/probe_ok.sh) | `GET /ok` |
| [`curl/probe_error.sh`](curl/probe_error.sh) | `GET /error` |

### Sign-in and session

| Script | Description |
|--------|-------------|
| [`curl/sign_up_email.sh`](curl/sign_up_email.sh) | `POST /sign-up/email` |
| [`curl/sign_in_email.sh`](curl/sign_in_email.sh) | `POST /sign-in/email` |
| [`curl/sign_in_email_cookies.sh`](curl/sign_in_email_cookies.sh) | Same, stores cookies in jar |
| [`curl/sign_in_username.sh`](curl/sign_in_username.sh) | `POST /sign-in/username` |
| [`curl/get_session_get.sh`](curl/get_session_get.sh) | `GET /get-session` (needs `TOKEN`) |
| [`curl/get_session_post.sh`](curl/get_session_post.sh) | `POST /get-session` (needs `TOKEN`) |
| [`curl/get_session_cookies.sh`](curl/get_session_cookies.sh) | `GET /get-session` using cookie jar |
| [`curl/sign_out.sh`](curl/sign_out.sh) | `POST /sign-out` (needs `TOKEN`) |
| [`curl/sign_out_cookies.sh`](curl/sign_out_cookies.sh) | `POST /sign-out` with cookie jar |

### Passwords and email verification

| Script | Description |
|--------|-------------|
| [`curl/forget_password.sh`](curl/forget_password.sh) | `POST /forget-password` |
| [`curl/reset_password.sh`](curl/reset_password.sh) | `POST /reset-password` (needs `RESET_TOKEN`) |
| [`curl/reset_password_get.sh`](curl/reset_password_get.sh) | `GET /reset-password/{token}` |
| [`curl/change_password.sh`](curl/change_password.sh) | `POST /change-password` (needs `TOKEN`) |
| [`curl/set_password.sh`](curl/set_password.sh) | `POST /set-password` (needs `TOKEN`) |
| [`curl/send_verification_email.sh`](curl/send_verification_email.sh) | `POST /send-verification-email` (body: `email`, optional `callbackURL`) |
| [`curl/verify_email.sh`](curl/verify_email.sh) | `GET /verify-email` (query placeholders) |

### User and sessions management

| Script | Description |
|--------|-------------|
| [`curl/update_user.sh`](curl/update_user.sh) | `POST /update-user` (needs `TOKEN`) |
| [`curl/change_email.sh`](curl/change_email.sh) | `POST /change-email` (needs `TOKEN`) |
| [`curl/change_email_verify.sh`](curl/change_email_verify.sh) | `GET /change-email/verify` (needs `VERIFY_TOKEN`) |
| [`curl/delete_user.sh`](curl/delete_user.sh) | `POST /delete-user` (needs `TOKEN`) |
| [`curl/list_sessions.sh`](curl/list_sessions.sh) | `GET /list-sessions` (needs `TOKEN`; plugin config) |
| [`curl/revoke_session.sh`](curl/revoke_session.sh) | `POST /revoke-session` (needs `TOKEN` and `SESSION_TOKEN` = session token to revoke) |
| [`curl/revoke_sessions.sh`](curl/revoke_sessions.sh) | `POST /revoke-sessions` |
| [`curl/revoke_other_sessions.sh`](curl/revoke_other_sessions.sh) | `POST /revoke-other-sessions` |

### OAuth (stub)

| Script | Description |
|--------|-------------|
| [`curl/sign_in_social.sh`](curl/sign_in_social.sh) | `POST /sign-in/social` — minimal body; configure provider server-side |
| [`curl/link_social.sh`](curl/link_social.sh) | `POST /link-social` (needs `TOKEN`) |
| [`curl/list_accounts.sh`](curl/list_accounts.sh) | `GET /list-accounts` (needs `TOKEN`) |
| [`curl/refresh_token.sh`](curl/refresh_token.sh) | `POST /refresh-token` (needs `TOKEN`, `PROVIDER_ID`) |
| [`curl/get_access_token.sh`](curl/get_access_token.sh) | `POST /get-access-token` (needs `TOKEN`, `PROVIDER_ID`) |

### Two-factor (stubs)

| Script | Description |
|--------|-------------|
| [`curl/two_factor_get_totp_uri.sh`](curl/two_factor_get_totp_uri.sh) | `POST /two-factor/get-totp-uri` |
| [`curl/two_factor_enable.sh`](curl/two_factor_enable.sh) | `POST /two-factor/enable` |
| [`curl/two_factor_disable.sh`](curl/two_factor_disable.sh) | `POST /two-factor/disable` |
| [`curl/two_factor_verify_totp.sh`](curl/two_factor_verify_totp.sh) | `POST /two-factor/verify-totp` (needs `TOKEN`, `TOTP_CODE`) |

### Passkeys

| Script | Description |
|--------|-------------|
| [`curl/passkey_generate_register_options.sh`](curl/passkey_generate_register_options.sh) | `GET /passkey/generate-register-options` |
| [`curl/passkey_generate_authenticate_options.sh`](curl/passkey_generate_authenticate_options.sh) | `POST /passkey/generate-authenticate-options` |
| [`curl/passkey_verify_registration.sh`](curl/passkey_verify_registration.sh) | `POST /passkey/verify-registration` (needs `TOKEN`, `PASSKEY_REGISTRATION_BODY_JSON`) |
| [`curl/passkey_verify_authentication.sh`](curl/passkey_verify_authentication.sh) | `POST /passkey/verify-authentication` (needs `PASSKEY_AUTHENTICATION_BODY_JSON`) |

`PASSKEY_REGISTRATION_BODY_JSON` and `PASSKEY_AUTHENTICATION_BODY_JSON` should be raw JSON request bodies captured/generated from a browser WebAuthn ceremony.

### API keys

| Script | Description |
|--------|-------------|
| [`curl/api_key_create.sh`](curl/api_key_create.sh) | `POST /api-key/create` (needs `TOKEN`) |
| [`curl/api_key_list.sh`](curl/api_key_list.sh) | `GET /api-key/list` |
| [`curl/api_key_get.sh`](curl/api_key_get.sh) | `GET /api-key/get?id=` (needs `TOKEN`, `API_KEY_ID`) |
| [`curl/api_key_update.sh`](curl/api_key_update.sh) | `POST /api-key/update` |
| [`curl/api_key_delete.sh`](curl/api_key_delete.sh) | `POST /api-key/delete` |
| [`curl/api_key_verify.sh`](curl/api_key_verify.sh) | `POST /api-key/verify` |

### Organizations (sample)

| Script | Description |
|--------|-------------|
| [`curl/organization_create.sh`](curl/organization_create.sh) | `POST /organization/create` (needs `TOKEN`) |
| [`curl/organization_list.sh`](curl/organization_list.sh) | `GET /organization/list` |
| [`curl/organization_check_slug.sh`](curl/organization_check_slug.sh) | `POST /organization/check-slug` |

### Legacy wrapper

| Script | Description |
|--------|-------------|
| [`api_usage.sh`](api_usage.sh) | Runs a short demo chain via the scripts above |

## Rust examples

Compile-checked examples:

| File | Run |
|------|-----|
| [`auth_builder_minimal.rs`](auth_builder_minimal.rs) | `cargo run --example auth_builder_minimal` |
| [`auth_core_ok.rs`](auth_core_ok.rs) | `cargo run --example auth_core_ok` |
