# App users

An app user belongs to one app, or to one app family when sub-apps are used.
The stable identifier is the `uid`.

## App user fields

| field | type | notes |
|---|---|---|
| `id` | integer | numeric id |
| `uid` | string | public identifier, `a_...` |
| `app_id` | integer | the owning app |
| `app_username` | string | 3-32 characters: letters, digits, dot, underscore or hyphen |
| `email` | string or null | |
| `display_name` | string or null | |
| `status` | `active` or `disabled` | |
| `api_key_hint` | string or null | first characters of the current key |
| `created_at` | unix seconds | |
| `updated_at` | unix seconds | |

## Create an app user

```bash
curl -sS -X POST "$MANAGE/apps/1/users" -H "$AUTH" \
  -H "Content-Type: application/json" \
  -d '{
    "app_username": "alice",
    "password": "a-long-password",
    "email": "alice@example.com",
    "display_name": "Alice"
  }'
```

Response:

```json
{
  "id": 1,
  "uid": "a_9k2m4x",
  "app_id": 1,
  "app_username": "alice",
  "email": "alice@example.com",
  "display_name": "Alice",
  "status": "active",
  "api_key": "gak_...",
  "warning": "Store api_key now; it is not recoverable."
}
```

You can also create an app user through the account-creation API, either as a
pure API call or as a URI-style call. See [Account creation](accounts.md).

Store the `uid` in your own database. Store the `api_key` if the user needs a
long-lived credential.

## List and read

```bash
curl -sS "$MANAGE/apps/1/users" -H "$AUTH"
curl -sS "$MANAGE/apps/1/users/a_9k2m4x" -H "$AUTH"
```

## Update

```bash
curl -sS -X PATCH "$MANAGE/apps/1/users/a_9k2m4x" -H "$AUTH" \
  -H "Content-Type: application/json" \
  -d '{"display_name":"Alice A.","email":"alice@example.com"}'
```

You can also change `app_username` and `status`.

## Set a password

```bash
curl -sS -X POST "$MANAGE/apps/1/users/a_9k2m4x/password" -H "$AUTH" \
  -H "Content-Type: application/json" -d '{"password":"a-long-password"}'
```

This revokes the user's sessions.

## Disable or enable

```bash
curl -sS -X PATCH "$MANAGE/apps/1/users/a_9k2m4x" -H "$AUTH" \
  -H "Content-Type: application/json" -d '{"status":"disabled"}'
```

Disabling a user revokes their sessions.

## Rotate the user key

```bash
curl -sS -X POST "$MANAGE/apps/1/users/a_9k2m4x/rotate-key" -H "$AUTH"
```

This revokes every existing key for that user and issues one new `gak_` key.

## Delete

```bash
curl -sS -X DELETE "$MANAGE/apps/1/users/a_9k2m4x" -H "$AUTH"
```

## App user keys

```bash
curl -sS "$MANAGE/apps/1/users/a_9k2m4x/keys" -H "$AUTH"

curl -sS -X POST "$MANAGE/apps/1/users/a_9k2m4x/keys" -H "$AUTH" \
  -H "Content-Type: application/json" -d '{"label":"phone"}'

curl -sS -X DELETE "$MANAGE/apps/1/users/a_9k2m4x/keys/9" -H "$AUTH"
```

A `gak_` key can be used directly as a bearer token on the public API.

## Shared user pool

When an app has sub-apps, app users are shared across the family. A sub-app can
authenticate those users with its own `app_key` and `app_secret`, and the
returned `uid` is the same across the family.

## Usernames

App usernames are unique within an app. They are not global. Two different apps
can both have an `alice`.
