# IndieAuth Authentication Endpoint Correction

**Date**: 2025-11-22
**Version**: 0.9.4
**Type**: Bug Fix

## Summary

Corrected the IndieAuth code redemption endpoint from `/token` to `/authorize` for authentication-only flows, and removed the unnecessary `grant_type` parameter.

## Problem

StarPunk was using the wrong endpoint for IndieAuth authentication. Per the IndieAuth specification:

- **Authentication-only flows** (identity verification): Use the **authorization endpoint** (`/authorize`)
- **Authorization flows** (getting access tokens): Use the **token endpoint** (`/token`)

StarPunk only needs identity verification (to check if the user is the admin), so it should POST to the authorization endpoint, not the token endpoint.

Additionally, the `grant_type` parameter is only required for token endpoint requests (OAuth 2.0 access token requests), not for authentication-only code redemption at the authorization endpoint.

### IndieAuth Spec Reference

From the IndieAuth specification:
> If the client only needs to know the user who logged in, the client will exchange the authorization code at the authorization endpoint. If the client needs an access token, the client will exchange the authorization code at the token endpoint.

## Solution

1. Changed the endpoint from `/token` to `/authorize`
2. Removed the `grant_type` parameter (not needed for authentication-only)
3. Updated debug logging to reflect "code verification" instead of "token exchange"

### Before

```python
token_exchange_data = {
    "grant_type": "authorization_code",  # Not needed for authentication-only
    "code": code,
    "client_id": current_app.config["SITE_URL"],
    "redirect_uri": f"{current_app.config['SITE_URL']}auth/callback",
    "code_verifier": code_verifier,
}

token_url = f"{current_app.config['INDIELOGIN_URL']}/token"  # Wrong endpoint
```

### After

```python
token_exchange_data = {
    "code": code,
    "client_id": current_app.config["SITE_URL"],
    "redirect_uri": f"{current_app.config['SITE_URL']}auth/callback",
    "code_verifier": code_verifier,
}

# Use authorization endpoint for authentication-only flow (identity verification)
token_url = f"{current_app.config['INDIELOGIN_URL']}/authorize"
```

## Files Modified

1. **`starpunk/auth.py`**
   - Line 410-423: Removed `grant_type`, changed endpoint to `/authorize`, added explanatory comments
   - Line 434: Updated log message from "token exchange request" to "code verification request to authorization endpoint"
   - Line 445: Updated comment to clarify authentication-only flow
   - Line 455: Updated log message from "token exchange response" to "code verification response"

2. **`starpunk/__init__.py`**
   - Version bumped from 0.9.3 to 0.9.4

3. **`CHANGELOG.md`**
   - Added 0.9.4 release notes

## Testing

- All tests pass at the same rate as before (no new failures introduced)
- 28 pre-existing test failures remain (related to OAuth metadata and h-app tests for removed functionality from v0.8.0)
- 486 tests pass

## Technical Context

The v0.9.3 fix that added `grant_type` was based on an incorrect assumption that IndieLogin.com uses the token endpoint for all code redemption. However:

1. IndieLogin.com follows the IndieAuth spec which distinguishes between authentication and authorization
2. For authentication-only (which is all StarPunk needs), the authorization endpoint is correct
3. The token endpoint is only for obtaining access tokens (which StarPunk doesn't need)

## References

- [IndieAuth Specification - Authentication](https://www.w3.org/TR/indieauth/#authentication)
- [IndieAuth Specification - Authorization Endpoint](https://www.w3.org/TR/indieauth/#authorization-endpoint)
- ADR-022: IndieAuth Authentication Endpoint Correction (if created)
