Fix IndieAuth client discovery for production authentication

Add h-app microformats markup to base.html to enable IndieLogin.com
to verify StarPunk as a legitimate OAuth client. Without this markup,
IndieLogin returns "client_id is not registered" error, blocking all
production authentication.

The h-app markup provides client identification per IndieAuth legacy
standard, which is widely supported by authorization servers including
IndieLogin.com.

Changes:
- Add h-app microformats div to base.html footer (hidden)
- Update version to v0.6.1 (patch release per ADR-008)
- Update CHANGELOG.md with v0.6.1 release notes
- Add 6 comprehensive tests for h-app markup (all passing)
- Create ADR-016 documenting client discovery decision
- Create architecture analysis report
- Create implementation report

Tests: 456 total, 455 passing (99.78%)
New tests: 6 for h-app microformats (100% passing)

Fixes critical bug preventing production authentication.

Related: Phase 3 Authentication implementation, ADR-016

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-19 11:44:35 -07:00
parent 3e9639f17b
commit 6a29b0199e
7 changed files with 1465 additions and 2 deletions

View File

@@ -392,3 +392,46 @@ class TestTemplateVariables:
assert response.status_code == 200
# Should have URLs like /admin, /admin/login, etc.
assert b"href=" in response.data
class TestIndieAuthClientDiscovery:
"""Test IndieAuth client discovery (h-app microformats)"""
def test_h_app_microformats_present(self, client):
"""Verify h-app client discovery markup exists"""
response = client.get("/")
assert response.status_code == 200
assert b'class="h-app"' in response.data
def test_h_app_contains_url_and_name_properties(self, client):
"""Verify h-app contains u-url and p-name properties"""
response = client.get("/")
assert response.status_code == 200
assert b'class="u-url p-name"' in response.data
def test_h_app_contains_site_url(self, client, app):
"""Verify h-app contains correct site URL"""
response = client.get("/")
assert response.status_code == 200
assert app.config["SITE_URL"].encode() in response.data
def test_h_app_contains_site_name(self, client, app):
"""Verify h-app contains site name"""
response = client.get("/")
assert response.status_code == 200
site_name = app.config.get("SITE_NAME", "StarPunk").encode()
assert site_name in response.data
def test_h_app_is_hidden(self, client):
"""Verify h-app has hidden attribute for visual hiding"""
response = client.get("/")
assert response.status_code == 200
# h-app div should have hidden attribute
assert b'class="h-app" hidden' in response.data
def test_h_app_is_aria_hidden(self, client):
"""Verify h-app has aria-hidden for screen reader hiding"""
response = client.get("/")
assert response.status_code == 200
# h-app div should have aria-hidden="true"
assert b'aria-hidden="true"' in response.data