> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tktchurch.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Token Operations

> Handle refresh tokens, token info, and social authentication

This endpoint handles various token-related operations including token refresh, token information retrieval, and social authentication through JWT tokens.

### Request Body

<ParamField body="grant_type" type="string" required={true}>
  The type of token operation to perform:

  * `refresh_token`: Get new access token using refresh token
  * `token_info`: Get information about an access token
  * `id_token`: Authenticate with a social provider's ID token
</ParamField>

<ParamField body="refresh_token" type="string" required={false}>
  Required when `grant_type` is "refresh\_token". The refresh token to use for obtaining a new access token.
</ParamField>

<ParamField body="access_token" type="string" required={false}>
  Required when `grant_type` is "token\_info". The access token to get information about.
</ParamField>

<ParamField body="id_token" type="string" required={false}>
  Required when `grant_type` is "id\_token". The ID token from a social provider.
</ParamField>

### Response

<ResponseField name="access_token" type="string">
  JWT access token (for refresh\_token and id\_token grant types)
</ResponseField>

<ResponseField name="refresh_token" type="string">
  JWT refresh token (for refresh\_token and id\_token grant types)
</ResponseField>

<ResponseField name="expires_in" type="integer">
  Token expiration time in seconds (default: 3600)
</ResponseField>

<ResponseField name="token_type" type="string">
  Type of token (always "bearer")
</ResponseField>

<ResponseField name="is_new_user" type="boolean" required={false}>
  Only present for id\_token grant type. Indicates if a new user was created.
</ResponseField>

### Token Info Response

When using `token_info` grant type, the response includes:

<ResponseField name="sub" type="string">
  User ID associated with the token
</ResponseField>

<ResponseField name="scopes" type="array">
  List of permissions granted to the token.
</ResponseField>

<ResponseField name="exp" type="string">
  Token expiration timestamp
</ResponseField>

<ResponseField name="iat" type="string">
  Token issued at timestamp
</ResponseField>

<ResponseField name="user" type="object">
  <Expandable title="User Object">
    <ResponseField name="id" type="string" required={false}>
      User's unique identifier (UUID)
    </ResponseField>

    <ResponseField name="email" type="string" required={true}>
      User's email address
    </ResponseField>

    <ResponseField name="firstName" type="string" required={false}>
      User's first name
    </ResponseField>

    <ResponseField name="lastName" type="string" required={false}>
      User's last name
    </ResponseField>

    <ResponseField name="status" type="string" required={true}>
      User's account status. One of:

      * `active`: User is active and can access the system
      * `inactive`: User is inactive (unverified email or deactivated account)
      * `suspended`: User is temporarily suspended
    </ResponseField>

    <ResponseField name="provider" type="string" required={true}>
      Authentication provider. One of:

      * `local`: Local authentication using email and password
      * `google`: Google OAuth authentication
      * `facebook`: Facebook OAuth authentication
      * `apple`: Apple Sign In authentication
    </ResponseField>

    <ResponseField name="providerInfo" type="object" required={false}>
      Provider-specific user information

      <Expandable title="Provider Info">
        <ResponseField name="providerId" type="string" required={false}>
          The provider's unique identifier for the user
        </ResponseField>

        <ResponseField name="displayName" type="string" required={false}>
          The user's display name from the provider
        </ResponseField>

        <ResponseField name="photoUrl" type="string" required={false}>
          URL to the user's profile photo
        </ResponseField>

        <ResponseField name="email" type="string" required={false}>
          The user's email from the provider
        </ResponseField>
      </Expandable>
    </ResponseField>

    <ResponseField name="lastLoginAt" type="string" required={false}>
      Timestamp of last login
    </ResponseField>

    <ResponseField name="roles" type="array" required={false}>
      List of user roles

      <Expandable title="Role Object">
        <ResponseField name="id" type="string" required={false}>
          Role identifier (UUID)
        </ResponseField>

        <ResponseField name="name" type="string" required={true}>
          Role name
        </ResponseField>

        <ResponseField name="description" type="string" required={true}>
          Role description
        </ResponseField>

        <ResponseField name="permissions" type="array" required={true}>
          List of permissions granted to this role
        </ResponseField>

        <ResponseField name="isSystem" type="boolean" required={true}>
          Whether this is a system-defined role
        </ResponseField>
      </Expandable>
    </ResponseField>

    <ResponseField name="createdAt" type="string" required={false}>
      Account creation timestamp
    </ResponseField>
  </Expandable>
</ResponseField>

### Social Authentication Flow

When using `id_token` grant type, the endpoint:

1. **Token Verification**:
   * Verifies the ID token signature using provider's JWKS
   * Validates token claims (iss, aud, exp, iat)
   * Extracts user information from token payload

2. **Provider Validation**:
   * Google tokens must be issued by `https://accounts.google.com`
   * Apple tokens must be issued by `https://appleid.apple.com`
   * Client ID validation against environment configuration

3. **Account Processing**:
   * Checks for existing account with email
   * Link the account to the provider if it exists, ensuring the primary provider matches before establishing the connection.
   * Creates new account if email is new
   * Assigns default member role to new accounts

### Error Responses

<ResponseField name="error" type="object">
  Error details when the request fails

  <Expandable title="Error Object">
    <ResponseField name="status" type="integer">
      HTTP status code
    </ResponseField>

    <ResponseField name="reason" type="string">
      Error message explaining why the request failed
    </ResponseField>
  </Expandable>
</ResponseField>

<Note>
  Common error cases:

  * 400 Bad Request: Missing required fields or invalid grant type
  * 401 Unauthorized: Invalid/expired tokens or provider verification failed
  * 403 Forbidden: Provider not linked or insufficient permissions
</Note>

<RequestExample>
  ```bash Request theme={null}
  curl -X POST "https://api.tktchurch.com/v1/auth/token" \
    -H "Content-Type: application/json" \
    -d '{
      "grant_type": "refresh_token",
      "refresh_token": "eyJhbGciOiJIUzI1NiIs..."
    }'
  ```
</RequestExample>

<ResponseExample>
  ```json 200 Refresh Token Success theme={null}
  {
    "access_token": "eyJhbGciOiJIUzI1NiIs...",
    "refresh_token": "eyJhbGciOiJIUzI1NiIs...",
    "expires_in": 3600,
    "token_type": "bearer"
  }
  ```

  ```json 200 Token Info Success theme={null}
  {
    "sub": "123e4567-e89b-12d3-a456-426614174000",
    "scopes": ["event:read", "user:read"],
    "exp": "2024-01-01T00:00:00Z",
    "iat": "2023-12-31T00:00:00Z",
    "user": {
      "id": "123e4567-e89b-12d3-a456-426614174000",
      "email": "user@example.com",
      "firstName": "John",
      "lastName": "Doe",
      "status": "active",
      "provider": "google",
      "providerInfo": {
        "providerId": "google123",
        "displayName": "John Doe",
        "photoUrl": "https://example.com/photo.jpg",
        "email": "user@example.com"
      },
      "lastLoginAt": "2024-01-20T08:30:00Z",
      "roles": [
        {
          "id": "456e4567-e89b-12d3-a456-426614174000",
          "name": "Member",
          "description": "Regular church member",
          "permissions": ["event:read", "newsletter:read", "livestream:read"],
          "isSystem": true
        }
      ],
      "createdAt": "2023-12-01T00:00:00Z"
    }
  }
  ```

  ```json 200 Social Auth Success theme={null}
  {
    "access_token": "eyJhbGciOiJIUzI1NiIs...",
    "refresh_token": "eyJhbGciOiJIUzI1NiIs...",
    "expires_in": 3600,
    "token_type": "bearer",
    "is_new_user": false
  }
  ```

  ```json 400 Bad Request theme={null}
  {
    "error": {
      "status": 400,
      "reason": "Refresh token is required"
    }
  }
  ```

  ```json 401 Invalid Token theme={null}
  {
    "error": {
      "status": 401,
      "reason": "Invalid refresh token"
    }
  }
  ```

  ```json 403 Provider Not Linked theme={null}
  {
    "error": {
      "status": 403,
      "reason": "Provider not linked. Use /auth/link-provider to link this provider."
    }
  }
  ```
</ResponseExample>
