- Remove leading slash when constructing URLs with SITE_URL
- SITE_URL already includes trailing slash per IndieAuth spec
- Fixes malformed Location header in Micropub responses
- Fixes malformed URLs in Microformats2 query responses
Changes:
- starpunk/micropub.py line 312: f"{site_url}notes/{note.slug}"
- starpunk/micropub.py line 383: f"{site_url}notes/{note.slug}"
- Added comments explaining SITE_URL trailing slash convention
- Updated version to 1.0.1 in starpunk/__init__.py
- Updated CHANGELOG.md with v1.0.1 release notes
Fixes double slash issue reported after v1.0.0 release.
Per ADR-039 and docs/releases/v1.0.1-hotfix-plan.md
Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
40 KiB
Changelog
All notable changes to StarPunk will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
Unreleased
[1.0.1] - 2025-11-25
Fixed
- Micropub Location header no longer contains double slash in URL
- Microformats2 query response URLs no longer contain double slash
Technical Details
Fixed URL construction in micropub.py to account for SITE_URL having a trailing slash (required for IndieAuth spec compliance). Changed from f"{site_url}/notes/{slug}" to f"{site_url}notes/{slug}" at two locations (lines 312 and 383). Added comments explaining the trailing slash convention.
[1.0.0] - 2025-11-24
Released
First production-ready release of StarPunk! A minimal, self-hosted IndieWeb CMS with full IndieAuth and Micropub compliance.
This milestone represents the completion of all V1 features:
- Full W3C IndieAuth specification compliance with endpoint discovery
- Complete W3C Micropub specification implementation for posting
- Robust database migrations with race condition protection
- Production-ready containerized deployment
- Comprehensive test coverage (536 tests passing)
StarPunk is now ready for production use as a personal IndieWeb publishing platform.
Summary of V1 Features
All features from release candidates (rc.1 through rc.5) are now stable:
IndieAuth Implementation
- External IndieAuth provider support (delegates to IndieLogin.com or similar)
- Dynamic endpoint discovery from user profile (ADMIN_ME)
- W3C IndieAuth specification compliance
- HTTP Link header and HTML link element discovery
- Endpoint caching (1 hour TTL) with graceful fallback
- Token verification caching (5 minutes TTL)
Micropub Implementation
- Full Micropub endpoint for creating posts
- Support for JSON and form-encoded requests
- Bearer token authentication with scope validation
- Content validation and sanitization
- Proper HTTP status codes and error responses
- Location header with post URL
Database & Migrations
- Automatic database migration system
- Migration race condition protection with database locking
- Exponential backoff retry logic for multi-worker deployments
- Safe container startup with gunicorn workers
Production Deployment
- Production-ready containerized deployment (Podman/Docker)
- Health check endpoint for monitoring
- Gunicorn WSGI server with multi-worker support
- Secure non-root user execution
- Reverse proxy configurations (Caddy/Nginx)
Configuration Changes from RC Releases
TOKEN_ENDPOINTenvironment variable deprecated (endpoints discovered automatically)ADMIN_MEmust be a valid profile URL with IndieAuth link elements
Standards Compliance
- W3C IndieAuth Specification (Section 4.2: Discovery by Clients)
- W3C Micropub Specification
- OAuth 2.0 Bearer Token Authentication
- Microformats2 Semantic HTML
- RSS 2.0 Feed Syndication
Testing
- 536 tests passing (99%+ pass rate)
- 87% overall code coverage
- Comprehensive endpoint discovery tests
- Complete Micropub integration tests
- Migration system tests
Documentation
Complete documentation available in /docs/:
- Architecture overview and design documents
- 31 Architecture Decision Records (ADRs)
- API contracts and specifications
- Deployment and migration guides
- Development standards and setup
Related Documentation
- ADR-031: IndieAuth Endpoint Discovery
- ADR-030: IndieAuth Provider Removal Strategy
- ADR-023: Micropub V1 Implementation Strategy
- ADR-022: Migration Race Condition Fix
- See
/docs/reports/for detailed implementation reports
[1.0.0-rc.5] - 2025-11-24
Fixed
Migration Race Condition (CRITICAL)
- CRITICAL: Migration race condition causing container startup failures with multiple gunicorn workers
- Implemented database-level locking using SQLite's
BEGIN IMMEDIATEtransaction mode - Added exponential backoff retry logic (10 attempts, up to 120s total) for lock acquisition
- Workers now coordinate properly: one applies migrations while others wait and verify
- Graduated logging (DEBUG → INFO → WARNING) based on retry attempts
- New connection created for each retry attempt to prevent state issues
- See ADR-022 and migration-race-condition-fix-implementation.md for technical details
- Implemented database-level locking using SQLite's
IndieAuth Endpoint Discovery (CRITICAL)
- CRITICAL: Fixed hardcoded IndieAuth endpoint configuration (violated IndieAuth specification)
- Endpoints now discovered dynamically from user's profile URL (ADMIN_ME)
- Implements W3C IndieAuth specification Section 4.2 (Discovery by Clients)
- Supports both HTTP Link headers and HTML link elements for discovery
- Endpoint discovery cached (1 hour TTL) for performance
- Token verifications cached (5 minutes TTL)
- Graceful fallback to expired cache on network failures
- See ADR-031 and docs/architecture/indieauth-endpoint-discovery.md for details
Changed
IndieAuth Endpoint Discovery
-
BREAKING: Removed
TOKEN_ENDPOINTconfiguration variable- Endpoints are now discovered automatically from
ADMIN_MEprofile - Deprecation warning shown if
TOKEN_ENDPOINTstill in environment - See docs/migration/fix-hardcoded-endpoints.md for migration guide
- Endpoints are now discovered automatically from
-
Token Verification (
starpunk/auth_external.py)- Complete rewrite with endpoint discovery implementation
- Always discovers endpoints from
ADMIN_ME(single-user V1 assumption) - Validates discovered endpoints (HTTPS required in production, localhost allowed in debug)
- Implements retry logic with exponential backoff for network errors
- Token hashing (SHA-256) for secure caching
- URL normalization for comparison (lowercase, no trailing slash)
-
Caching Strategy
- Simple single-user cache (V1 implementation)
- Endpoint cache: 1 hour TTL with grace period on failures
- Token verification cache: 5 minutes TTL
- Cache cleared automatically on application restart
Added
IndieAuth Endpoint Discovery
- New dependency:
beautifulsoup4>=4.12.0for HTML parsing - HTTP Link header parsing (RFC 8288 basic support)
- HTML link element extraction with BeautifulSoup4
- Relative URL resolution against profile base URL
- HTTPS enforcement in production (HTTP allowed in debug mode)
- Comprehensive error handling with clear messages
- 35 new tests covering all discovery scenarios
Technical Details
Migration Race Condition Fix
- Modified
starpunk/migrations.pyto wrap migration execution inBEGIN IMMEDIATEtransaction - Each worker attempts to acquire RESERVED lock; only one succeeds
- Other workers retry with exponential backoff (100ms base, doubling each attempt, plus jitter)
- Workers that arrive late detect completed migrations and exit gracefully
- Timeout protection: 30s per connection attempt, 120s absolute maximum
- Comprehensive error messages guide operators to resolution steps
Endpoint Discovery Implementation
- Discovery priority: HTTP Link headers (highest), then HTML link elements
- Profile URL fetch timeout: 5 seconds (cached results)
- Token verification timeout: 3 seconds (per request)
- Maximum 3 retries for server errors (500-504) and network failures
- No retries for client errors (400, 401, 403, 404)
- Single-user cache structure (no profile URL mapping needed in V1)
- Grace period: Uses expired endpoint cache if fresh discovery fails
- V2-ready: Cache structure can be upgraded to dict-based for multi-user
Breaking Changes
TOKEN_ENDPOINTenvironment variable no longer used (will show deprecation warning)- Micropub now requires discoverable IndieAuth endpoints in
ADMIN_MEprofile - ADMIN_ME profile must include
<link rel="token_endpoint">or HTTP Link header
Migration Guide
See docs/migration/fix-hardcoded-endpoints.md for detailed migration steps:
- Ensure your ADMIN_ME profile has IndieAuth link elements
- Remove TOKEN_ENDPOINT from your .env file
- Restart StarPunk - endpoints will be discovered automatically
Configuration
Updated requirements:
ADMIN_ME: Required, must be a valid profile URL with IndieAuth endpointsTOKEN_ENDPOINT: Deprecated, will be ignored (remove from configuration)
Tests
- 536 tests passing (excluding timing-sensitive migration race tests)
- 35 new endpoint discovery tests:
- Link header parsing (absolute and relative URLs)
- HTML parsing (including malformed HTML)
- Discovery priority (Link headers over HTML)
- HTTPS validation (production vs debug mode)
- Caching behavior (TTL, expiry, grace period)
- Token verification (success, errors, retries)
- URL normalization and scope checking
[1.0.0-rc.4] - 2025-11-24
Complete IndieAuth Server Removal (Phases 1-4)
StarPunk no longer acts as an IndieAuth authorization server. All IndieAuth operations are now delegated to external providers (e.g., IndieLogin.com). This simplifies the codebase and aligns with IndieWeb best practices.
Removed
-
Phase 1: Authorization Endpoint
- Deleted
/auth/authorizationendpoint andauthorization_endpoint()function - Removed authorization consent UI template (
templates/auth/authorize.html) - Removed authorization-related imports:
create_authorization_codeandvalidate_scope - Deleted tests:
tests/test_routes_authorization.py,tests/test_auth_pkce.py
- Deleted
-
Phase 2: Token Issuance
- Deleted
/auth/tokenendpoint andtoken_endpoint()function - Removed all token issuance functionality
- Deleted tests:
tests/test_routes_token.py
- Deleted
-
Phase 3: Token Storage
- Deleted
starpunk/tokens.pymodule entirely - Dropped
tokensandauthorization_codesdatabase tables (migration 004) - Removed token CRUD and verification functions
- Deleted tests:
tests/test_tokens.py
- Deleted
Added
- Phase 4: External Token Verification
- New module
starpunk/auth_external.pyfor external IndieAuth token verification verify_external_token()function to verify tokens with external providerscheck_scope()function moved from tokens module- Configuration:
TOKEN_ENDPOINTfor external token endpoint URL - HTTP client (httpx) for token verification requests
- Proper error handling for unreachable auth servers
- Timeout protection (5s) for external verification requests
- New module
Changed
-
Micropub endpoint now verifies tokens with external IndieAuth providers
- Updated
routes/micropub.pyto useverify_external_token() - Updated
micropub.pyto importcheck_scopefromauth_external - All Micropub tests updated to mock external verification
- Updated
-
Migrations:
- Migration 003: Remove
code_verifiercolumn fromauth_statetable - Migration 004: Drop
tokensandauthorization_codestables - Both migrations applied automatically on startup
- Migration 003: Remove
-
Tests: All 501 tests passing
- Fixed migration tests to work with current schema (no
code_verifier) - Updated Micropub tests to mock external token verification
- Fixed test fixtures and app context usage
- Removed 38 obsolete token-related tests
- Fixed migration tests to work with current schema (no
Configuration
New required configuration for production:
TOKEN_ENDPOINT: External IndieAuth token endpoint (e.g., https://tokens.indieauth.com/token)ADMIN_ME: Site owner's identity URL (already required)
Technical Details
- External token verification follows IndieAuth specification
- Tokens verified via GET request with Authorization header
- Token response validated for required fields (me, client_id, scope)
- Only tokens matching
ADMIN_MEare accepted - Graceful degradation if external server unavailable
Breaking Changes
- Micropub clients must obtain tokens from external IndieAuth providers
- Existing internal tokens are invalid (tables dropped in migration 004)
TOKEN_ENDPOINTconfiguration required for Micropub to function
Migration Guide
- Choose external IndieAuth provider (recommended: IndieLogin.com)
- Set
TOKEN_ENDPOINTenvironment variable - Existing sessions unaffected - admin login still works
- Micropub clients need new tokens from external provider
Standards Compliance
- Fully compliant with W3C IndieAuth specification
- Follows IndieWeb principle: delegate to external services
- OAuth 2.0 Bearer token authentication maintained
Related Documentation
- ADR-030: IndieAuth Provider Removal Strategy
- ADR-050: Remove Custom IndieAuth Server
- Implementation report:
docs/reports/2025-11-24-indieauth-removal-complete.md
Notes
- This completes the transition from self-hosted IndieAuth to external delegation
- Simpler codebase: -500 lines of code, -5 database tables
- More secure: External providers handle token security
- More maintainable: Less code to secure and update
[1.0.0-rc.3] - 2025-11-24
Fixed
- CRITICAL: Migration detection failure for partially migrated databases: Fixed migration 002 detection logic
- Production database had migration 001 applied but not migration 002
- Migration 002's tables (tokens, authorization_codes) already existed from SCHEMA_SQL in v1.0.0-rc.1
- Previous logic only used smart detection for fresh databases (migration_count == 0)
- For partially migrated databases (migration_count > 0), it tried to run migration 002 normally
- This caused "table already exists" error because CREATE TABLE statements would fail
- Fixed by checking migration 002's state regardless of migration_count
- Migration 002 now checks if its tables exist before running, skips table creation if they do
- Missing indexes are created even when tables exist, ensuring complete database state
- Fixes deployment failure on production database with existing tables but missing migration record
Technical Details
- Affected databases: Any database with migration 001 applied but not migration 002, where tables were created by SCHEMA_SQL
- Root cause: Smart detection (is_migration_needed) was only called when migration_count == 0
- Solution: Always check migration 002's state, regardless of migration_count
- Backwards compatibility: Works for fresh databases, partially migrated databases, and fully migrated databases
- Migration 002 will create only missing indexes if tables already exist
[1.0.0-rc.2] - 2025-11-24
Fixed
- CRITICAL: Database migration failure on existing databases: Removed duplicate index definitions from SCHEMA_SQL
- Migration 002 creates indexes
idx_tokens_hash,idx_tokens_me, andidx_tokens_expires - These same indexes were also in SCHEMA_SQL (database.py lines 58-60)
- When applying migration 002 to existing databases, indexes already existed from SCHEMA_SQL, causing failure
- Removed the three index creation statements from SCHEMA_SQL to prevent conflicts
- Migration 002 is now the sole source of truth for token table indexes
- Fixes "index already exists" error when running migrations on databases created before v1.0.0-rc.1
- Migration 002 creates indexes
Technical Details
- Affected databases: Any database created with v1.0.0-rc.1 or earlier that had run init_db()
- Root cause: SCHEMA_SQL ran on every init_db() call, creating indexes before migration could run
- Solution: Remove index creation from SCHEMA_SQL, delegate to migration 002 exclusively
- Backwards compatibility: Fresh databases will get indexes from migration 002 automatically
[1.0.0-rc.1] - 2025-11-24
Release Candidate for V1.0.0
First release candidate with complete IndieWeb support. This milestone implements the full V1 specification with IndieAuth authentication and Micropub posting capabilities.
Added
-
Phase 1: Secure Token Management
- Bearer token storage with Argon2id hashing
- Automatic token expiration (90 days default)
- Token revocation endpoint (
POST /micropub?action=revoke) - Admin interface for token management with creation, viewing, and revocation
- Comprehensive test coverage for token operations (14 tests)
-
Phase 2: IndieAuth Token Endpoint
- Token endpoint (
POST /indieauth/token) for access token issuance - Authorization endpoint (
POST /indieauth/authorize) for consent flow - PKCE verification for authorization code exchange
- Token verification endpoint (
GET /indieauth/token) for clients - Proper OAuth 2.0/IndieAuth spec compliance
- Client credential validation and scope enforcement
- Test suite for token and authorization endpoints (13 tests)
- Token endpoint (
-
Phase 3: Micropub Endpoint
- Micropub endpoint (
POST /micropub) for creating posts - Support for both JSON and form-encoded requests
- Bearer token authentication with scope validation
- Content validation and sanitization
- Post creation with automatic timestamps
- Location header with post URL in responses
- Comprehensive error handling with proper HTTP status codes
- Integration tests for complete authentication flow (11 tests)
- Micropub endpoint (
Changed
- Admin interface now includes token management section
- Database schema extended with
tokenstable for secure token storage - Authentication system now supports both admin sessions and bearer tokens
- Authorization flow integrated with existing IndieAuth authentication
Security
- Bearer tokens hashed with Argon2id (same as passwords)
- Tokens support automatic expiration
- Scope validation enforces
createpermission for posting - PKCE prevents authorization code interception
- Token verification validates both hash and expiration
Standards Compliance
- IndieAuth specification (W3C) for authentication and authorization
- Micropub specification (W3C) for posting interface
- OAuth 2.0 bearer token authentication
- Proper HTTP status codes and error responses
- Location header for created resources
Testing
- 77 total tests (all passing)
- Complete coverage of token management, IndieAuth endpoints, and Micropub
- Integration tests verify end-to-end flows
- Error case coverage for validation and authentication failures
Documentation
- Implementation reports for all three phases
- Architecture reviews documenting design decisions
- API contracts specified in docs/design/api-contracts.md
- Test coverage documented in implementation reports
Related Standards
- ADR-023: Micropub V1 Implementation Strategy
- W3C IndieAuth Specification
- W3C Micropub Specification
Notes
This is a release candidate for testing. Stable 1.0.0 will be released after testing period and any necessary fixes.
[0.9.5] - 2025-11-23
Fixed
- SECRET_KEY empty string handling: Fixed config.py to properly handle empty
FLASK_SECRET_KEYenvironment variableos.getenv()returns empty string (not None) when env var is set to""- Empty string now correctly falls back to SESSION_SECRET
- Prevents Flask session/flash failures when FLASK_SECRET_KEY="" in .env file
[0.9.4] - 2025-11-22
Fixed
- IndieAuth authentication endpoint correction: Changed code redemption from token endpoint to authorization endpoint
- Per IndieAuth spec: authentication-only flows use
/authorize, not/token - StarPunk only needs identity verification, not access tokens
- Removed unnecessary
grant_typeparameter (only needed for token endpoint) - Updated debug logging to reflect "code verification" terminology
- Fixes authentication with IndieLogin.com and spec-compliant providers
- Per IndieAuth spec: authentication-only flows use
Changed
- Code redemption now POSTs to
/authorizeendpoint instead of/token - Log messages updated from "token exchange" to "code verification"
[0.9.3] - 2025-11-22
Fixed
- IndieAuth token exchange missing grant_type: Added required
grant_type=authorization_codeparameter to token exchange request- OAuth 2.0 spec requires this parameter for authorization code flow
- Some IndieAuth providers reject token exchange without this parameter
- Fixes authentication failures with spec-compliant IndieAuth providers
[0.9.2] - 2025-11-22
Fixed
- IndieAuth callback 404 error: Fixed auth blueprint URL prefix mismatch
- Auth blueprint was using
/adminprefix but redirect_uri used/auth/callback - Changed blueprint prefix from
/adminto/authas documented in ADR-022 - Auth routes now correctly at
/auth/login,/auth/callback,/auth/logout - Admin dashboard routes remain at
/admin/*(unchanged)
- Auth blueprint was using
Changed
- Updated test expectations to use new
/auth/*URL patterns
[0.9.1] - 2025-11-19
Fixed
- IndieAuth client_id trailing slash: Added automatic trailing slash normalization to SITE_URL
- IndieLogin.com spec requires client_id URLs to have trailing slash for root domains
- Fixes "client_id is not registered" authentication errors
- Normalizes https://example.com to https://example.com/
- Enhanced debug logging: Added detailed httpx request/response logging for token exchange
- Shows exact HTTP method, URL, headers, and body being sent to IndieLogin.com
- Helps troubleshoot authentication issues with full visibility
- All sensitive data (tokens, verifiers) automatically redacted
Changed
- SITE_URL configuration now automatically adds trailing slash if missing
[0.9.0] - 2025-11-19
Added
- Automatic Database Migration System: Zero-touch database schema updates on application startup
- Migration runner module (
starpunk/migrations.py) with automatic execution - Fresh database detection to prevent unnecessary migration execution
- Legacy database detection to apply pending migrations automatically
- Migration tracking table (
schema_migrations) to record applied migrations - Helper functions for database introspection (table_exists, column_exists, index_exists)
- Comprehensive migration test suite (26 tests covering all scenarios)
Changed
init_db()now automatically runs migrations after creating schema- Database initialization is fully automatic in containerized deployments
- Migration files in
migrations/directory are executed in alphanumeric order
Features
- Fresh Database Behavior: New installations detect current schema and mark migrations as applied without execution
- Legacy Database Behavior: Existing databases automatically apply pending migrations on startup
- Migration Tracking: All applied migrations recorded with timestamps in schema_migrations table
- Idempotent: Safe to run multiple times, only applies pending migrations
- Fail-Safe: Application fails to start if migrations fail, preventing inconsistent state
Infrastructure
- Container deployments now self-initialize with correct schema automatically
- No manual SQL execution required for schema updates
- Clear migration history in database for audit purposes
- Migration failures logged with detailed error messages
Standards Compliance
- Sequential migration numbering (001, 002, 003...)
- One migration per schema change for clear audit trail
- Migration files include date and ADR reference headers
- Follows standard migration patterns from Django/Rails
Testing
- 100% test coverage for migration system (26/26 tests passing)
- Tests cover fresh DB, legacy DB, partial migrations, failures
- Integration tests with actual migration file (001_add_code_verifier_to_auth_state.sql)
- Verified both automatic detection scenarios in production
Related Documentation
- ADR-020: Automatic Database Migration System
- Implementation guidance document with step-by-step instructions
- Quick reference card for migration system usage
[0.8.0] - 2025-11-19
Fixed
- CRITICAL: Fixed IndieAuth authentication to work with IndieLogin.com API
- Implemented required PKCE (Proof Key for Code Exchange) for security
- Corrected IndieLogin.com API endpoints (/authorize and /token instead of /auth)
- Added issuer validation for authentication callbacks
Added
- PKCE code_verifier generation and storage
- PKCE code_challenge generation (SHA256, base64-url encoded)
- Database column: auth_state.code_verifier for PKCE support
- Database migration script: migrations/001_add_code_verifier_to_auth_state.sql
- Comprehensive PKCE unit tests (6 tests, all passing)
Removed
- OAuth Client ID Metadata Document endpoint (/.well-known/oauth-authorization-server)
- Added in v0.7.0 but unnecessary for IndieLogin.com
- IndieLogin.com does not use OAuth client discovery
- h-app microformats markup from templates
- Modified in v0.7.1 but unnecessary for IndieLogin.com
- IndieLogin.com does not parse h-app for client identification
- indieauth-metadata link from HTML head
Changed
- Authentication flow now follows IndieLogin.com API specification exactly
- Database schema: auth_state table includes code_verifier column
- State token validation now returns code_verifier for token exchange
- Token exchange uses /token endpoint (not /auth)
- Authorization requests use /authorize endpoint (not /auth)
Security
- PKCE prevents authorization code interception attacks
- Issuer validation prevents token substitution attacks
- Code verifier securely stored and single-use
- Code verifier redacted in logs for security
Breaking Changes
- Users mid-authentication when upgrading will need to restart login (state tokens expire in 5 minutes)
- Existing state tokens without code_verifier will be invalid (intentional security improvement)
Notes
- v0.7.0: OAuth metadata endpoint added based on misunderstanding of requirements. This endpoint was never functional for our use case and is removed in v0.8.0.
- v0.7.1: h-app visibility changes attempted to fix authentication but addressed wrong issue. h-app discovery not used by IndieLogin.com. Removed in v0.8.0.
- v0.8.0: Correct implementation based on official IndieLogin.com API documentation.
Related Documentation
- ADR-025: IndieAuth Correct Implementation Based on IndieLogin.com API
- Design Document: docs/designs/indieauth-pkce-authentication.md
- ADR-016: Superseded (h-app client discovery not required)
- ADR-017: Superseded (OAuth metadata not required)
Migration Notes
- Database migration required: Add code_verifier column to auth_state table
- See migrations/001_add_code_verifier_to_auth_state.sql for SQL
- See docs/designs/indieauth-pkce-authentication.md for full implementation guide
[0.7.1] - 2025-11-19
Known Issues
- IndieAuth authentication still broken: This release attempted to fix authentication by making h-app visible, but IndieLogin.com does not parse h-app. Missing PKCE implementation is the actual issue. Fixed in v0.8.0.
Fixed
- IndieAuth h-app Visibility: Removed
hiddenandaria-hidden="true"attributes from h-app microformat markup- h-app was invisible to IndieAuth parsers, preventing proper client discovery
- Now visible in DOM for microformat parsers while remaining non-intrusive in footer
- Provides backward compatibility for IndieAuth services that rely on h-app parsing
[0.7.0] - 2025-11-19
Known Issues
- IndieAuth authentication still broken: This release attempted to fix authentication by adding OAuth metadata endpoint, but this is not required by IndieLogin.com. Missing PKCE implementation is the actual issue. Fixed in v0.8.0.
Added
- IndieAuth Detailed Logging: Comprehensive logging for authentication flows
- Logging helper functions with automatic token redaction (_redact_token, _log_http_request, _log_http_response)
- DEBUG-level HTTP request/response logging for IndieLogin.com interactions
- Configurable logging via LOG_LEVEL environment variable (DEBUG, INFO, WARNING, ERROR)
- Security-aware logging with automatic redaction of sensitive data (tokens, codes, secrets)
- Production warning when DEBUG logging is enabled in non-development environments
- Comprehensive test suite for logging functions (14 new tests)
Changed
- Enhanced authentication flow visibility with structured logging
- initiate_login(), handle_callback(), create_session(), and verify_session() now include detailed logging
- Flask logger configuration now based on LOG_LEVEL environment variable
- Log format varies by level: detailed for DEBUG, concise for INFO/WARNING/ERROR
Security
- All sensitive tokens automatically redacted in logs (show only first 6-8 and last 4 characters)
- Authorization codes, state tokens, and access tokens never logged in full
- Sensitive HTTP headers (Authorization, Cookie, Set-Cookie) excluded from logs
- Production warning prevents accidental DEBUG logging in production
Features
- Token redaction shows pattern like "abc123...********...xyz9" for debugging while protecting secrets
- HTTP request logging includes method, URL, and redacted parameters
- HTTP response logging includes status code, safe headers, and redacted body
- Session verification and creation logging for audit trails
- Admin authorization logging for security monitoring
Testing
- 51 authentication tests passing (100% pass rate)
- Tests verify token redaction at all levels
- Tests confirm no sensitive data appears in logs
- Tests verify logging behavior at different log levels (DEBUG vs INFO)
Standards Compliance
- OWASP Logging Cheat Sheet: Sensitive data redaction
- Python logging best practices
- IndieAuth specification compatibility (logging doesn't interfere with auth flow)
Related Documentation
- ADR-018: IndieAuth Detailed Logging Strategy
- Implementation includes complete specification from ADR-018
[0.6.2] - 2025-11-19
Fixed
- CRITICAL: Implemented OAuth Client ID Metadata Document to fix IndieAuth authentication
- Added
/.well-known/oauth-authorization-serverendpoint returning JSON metadata - IndieLogin.com now correctly verifies StarPunk as a registered OAuth client
- Resolves "client_id is not registered" error preventing production authentication
- Fixes authentication flow with modern IndieAuth servers (2022+ specification)
Added
- OAuth Client ID Metadata Document endpoint at
/.well-known/oauth-authorization-server - JSON metadata response with client_id, client_name, redirect_uris, and OAuth capabilities
<link rel="indieauth-metadata">discovery hint in HTML head- 24-hour caching for metadata endpoint (Cache-Control headers)
- Comprehensive test suite for OAuth metadata endpoint (12 new tests)
- Tests for indieauth-metadata link discovery (3 tests)
Changed
- IndieAuth client discovery now uses modern JSON metadata (primary method)
- h-app microformats retained for backward compatibility (legacy fallback)
- Three-layer discovery: well-known URL, link rel hint, h-app markup
Standards Compliance
- IndieAuth specification section 4.2 (Client Information Discovery)
- OAuth Client ID Metadata Document format
- IANA well-known URI registry standard
- OAuth 2.0 Dynamic Client Registration (RFC 7591)
Technical Details
- Metadata endpoint uses configuration values (SITE_URL, SITE_NAME)
- client_id exactly matches document URL (spec requirement)
- redirect_uris properly formatted as array
- Supports PKCE (S256 code challenge method)
- Public client configuration (no client secret)
Related Documentation
- ADR-017: OAuth Client ID Metadata Document Implementation
- IndieAuth Fix Summary report
- IndieAuth Client Discovery Root Cause Analysis
[0.6.1] - 2025-11-19
Fixed
- CRITICAL: Fixed IndieAuth client discovery to enable production authentication
- Added h-app microformats markup to base.html for IndieAuth client verification
- IndieLogin.com can now verify StarPunk as a legitimate OAuth client
- Resolves "client_id is not registered" error that blocked all production authentication
Changed
- Added hidden h-app metadata div to footer with SITE_URL and SITE_NAME
- h-app markup uses aria-hidden="true" and hidden attribute for screen reader and visual hiding
- Implements IndieAuth legacy client discovery standard for backward compatibility
Standards Compliance
- IndieAuth client discovery (legacy h-app microformats)
- Microformats2 h-app specification
- HTML5 hidden attribute standard
- ARIA accessibility standard
Related Documentation
- ADR-016: IndieAuth Client Discovery Mechanism
- IndieAuth client discovery analysis report
[0.6.0] - 2025-11-19
Added
- RSS Feed Generation: Standards-compliant RSS 2.0 feed for published notes
- RSS feed module (
starpunk/feed.py) with feed generation functions - GET
/feed.xmlroute for RSS feed access - Server-side feed caching (5-minute default, configurable)
- ETag support for efficient feed updates
- Cache-Control headers for client-side caching
- RSS feed auto-discovery link in HTML templates
- RSS link in site navigation
- Comprehensive RSS feed test suite (44 tests)
Production Container
- Containerfile: Multi-stage build for optimized image size (174MB)
- Container Orchestration: Podman and Docker Compose compatible
- Health Check Endpoint: GET
/healthfor container monitoring - Gunicorn WSGI Server: Production-ready with 4 workers
- Security: Non-root user execution (starpunk:1000)
- Volume Mounts: Data persistence for notes and database
- Reverse Proxy Configs: Caddy and Nginx examples with auto-HTTPS
- Container Documentation: Comprehensive deployment guide
Configuration
FEED_MAX_ITEMS: Maximum items in RSS feed (default: 50)FEED_CACHE_SECONDS: Server-side cache duration in seconds (default: 300)VERSION: Application version for health checks (default: 0.6.0)ENVIRONMENT: Deployment environment (development/production)WORKERS: Number of Gunicorn workers (default: 4)WORKER_TIMEOUT: Gunicorn worker timeout in seconds (default: 30)MAX_REQUESTS: Max requests per worker before restart (default: 1000)
Features
- RSS 2.0 compliant XML generation using feedgen library
- RFC-822 date formatting for RSS pubDate elements
- Intelligent note title extraction (first line or timestamp fallback)
- HTML content in CDATA sections for feed readers
- Atom self-link for feed discovery
- Only published notes included in feed
- Absolute URLs for all feed item links
Testing
- 88% overall test coverage (up from 87%)
- 96% coverage for feed module
- 449/450 tests passing (99.78% pass rate)
- Test isolation with automatic cache clearing
- Unicode and special character handling verified
Standards Compliance
- RSS 2.0 specification compliant
- RFC-822 date format for timestamps
- IndieWeb feed discovery support
- W3C Feed Validator compatible
Container Features
- Multi-stage build optimizes image size (Python 3.11-slim base)
- uv package manager for fast dependency installation
- Health checks verify database connectivity and filesystem access
- Resource limits prevent container resource exhaustion
- Log rotation (10MB max, 3 files) prevents disk space issues
- Automatic restart policy for reliability
- SELinux compatibility with volume mount flags
Deployment
- Podman-compatible with
--userns=keep-idfor proper permissions - Docker-compatible with standard volume mounts
- Reverse proxy examples for Caddy (auto-HTTPS) and Nginx
- HTTPS required for IndieAuth in production
- Complete backup and restore procedures documented
- Performance tuning guide for worker configuration
Related Documentation
- ADR-014: RSS Feed Implementation Strategy
- ADR-015: Phase 5 Implementation Approach
- Phase 5 design documentation
- Phase 5 quick reference guide
- Container deployment guide
[0.5.2] - 2025-11-18
Fixed
- Admin Routes: Fixed delete route to return HTTP 404 when attempting to delete nonexistent notes, per ADR-012 (HTTP Error Handling Policy)
- Added existence check to delete route before attempting deletion, consistent with edit route pattern
- Fixed test for delete nonexistent note to match ADR-012 compliance (expect 404 status, not 200 with follow_redirects)
Changed
- Delete route now checks note existence before deletion and returns 404 with "Note not found" flash message for nonexistent notes
- Test suite: 405/406 tests passing (99.75%)
[0.5.1] - 2025-11-18
Fixed
- CRITICAL: Fixed authentication redirect loop caused by cookie name collision between Flask's session and StarPunk's auth token
- Renamed authentication cookie from
sessiontostarpunk_sessionto avoid conflict with Flask's server-side session mechanism used by flash messages - All authentication flows (dev login, IndieAuth, logout) now work correctly without redirect loops
- Flash messages now display properly without interfering with authentication state
Changed
- BREAKING CHANGE: Authentication cookie renamed from
sessiontostarpunk_session- Existing authenticated users will be logged out and need to re-authenticate after upgrade
- This is an unavoidable breaking change required to fix the critical bug
Documentation
- Established cookie naming convention standard (starpunk_* prefix for all application cookies)
- Created implementation report documenting the root cause and fix
[0.5.0] - 2025-11-19
Added
- Development authentication module (
starpunk/dev_auth.py) for local testing is_dev_mode()function to check development mode statuscreate_dev_session()function for authentication bypass in development- Web interface templates with Microformats2 markup
- Admin dashboard, note editor, and login pages
- Public note display and RSS feed support
Fixed
- Phase 4 test suite now passing (400/406 tests, 98.5% pass rate)
- Template encoding issues (removed corrupted Unicode characters)
- Test database initialization using tmp_path fixtures
- Route URL patterns (trailing slash consistency)
- Template variable naming (g.user_me → g.me)
- Function name mismatches in tests (get_all_notes → list_notes)
- URL builder endpoint name (auth.login → auth.login_form)
- Session verification return type handling in tests
- Flake8 code quality issues (unused imports, f-strings)
Security
- Development authentication includes prominent warning logging
- DEV_MODE validation ensures DEV_ADMIN_ME is set
- Production mode validation ensures ADMIN_ME is set
Testing
- 87% overall test coverage
- All Phase 4 route and template tests functional
- Proper test isolation with temporary databases
- Fixed test context usage (test_request_context)
Code Quality
- All code formatted with Black
- Passes Flake8 validation
- Removed unused imports and fixed f-string warnings
0.4.0 - 2025-11-18
Added
- Authentication module (
starpunk/auth.py) with IndieLogin support - Core authentication functions:
initiate_login,handle_callback,create_session,verify_session,destroy_session require_authdecorator for protecting admin routes- Custom authentication exceptions (AuthError, InvalidStateError, UnauthorizedError, IndieLoginError)
- CSRF protection via state tokens
- Secure session management with SHA-256 token hashing
- Session metadata tracking (user agent, IP address)
- Automatic cleanup of expired sessions and state tokens
- URL validation utility function (
is_valid_url) - Comprehensive authentication test suite (37 tests, 96% coverage)
Changed
- Updated sessions table schema to use
session_token_hashinstead of plaintext tokens - Added
user_agentandip_addressfields to sessions table - Added
redirect_urifield to auth_state table - Added indexes for authentication performance (session_token_hash, me)
Security
- Token hashing with SHA-256 for secure storage
- CSRF protection with single-use state tokens
- Cryptographically secure token generation (secrets module)
- SQL injection prevention with prepared statements
- Comprehensive security logging
0.3.0 - 2025-11-18
Added
- Notes management module (
starpunk/notes.py) with CRUD operations - Custom exceptions for note operations (NoteError, NoteNotFoundError, InvalidNoteDataError, NoteSyncError)
- File and database synchronization with transaction safety
- Support for soft and hard note deletion
- Comprehensive test suite for notes module (85 tests, 86% coverage)
- Database schema support for soft deletes (deleted_at column)
- Slug uniqueness enforcement with random suffix generation
- Content hash calculation for integrity verification
Changed
- Updated database schema to include
deleted_atcolumn in notes table - Added index on
deleted_atfor query performance
0.1.0 - 2024-11-18
Added
- Initial project structure
- Core architecture design
- Technology stack selection (Flask, SQLite, file-based storage)
- Architecture Decision Records (ADR-001 through ADR-007)
- Development documentation and standards
- Phase 1.1 design: Core utilities specification
- Python coding standards
- Documentation organization structure
Documentation
- Complete architecture overview
- Technology stack documentation
- ADR-001: Python web framework (Flask)
- ADR-002: Flask extensions (minimal approach)
- ADR-003: Frontend technology (server-side rendering)
- ADR-004: File-based note storage
- ADR-005: IndieLogin authentication
- ADR-006: Python virtual environment (uv)
- ADR-007: Slug generation algorithm
- ADR-008: Versioning strategy