docs: Extract and organize CLAUDE.MD content, restructure documentation
This commit performs comprehensive documentation reorganization: 1. Extracted testing checklist from CLAUDE.MD to docs/standards/testing-checklist.md - Consolidated manual testing checklist - Added validation tools and resources - Created pre-release validation workflow 2. Streamlined CLAUDE.md to lightweight operational instructions - Python environment setup (uv) - Agent-developer protocol - Key documentation references - Removed redundant content (already in other docs) 3. Removed CLAUDE.MD (uppercase) - content was redundant - All content already exists in architecture/overview.md and projectplan docs - Only unique content (testing checklist) was extracted 4. Moved root documentation files to appropriate locations: - CONTAINER_IMPLEMENTATION_SUMMARY.md -> docs/reports/2025-11-19-container-implementation-summary.md - QUICKFIX-AUTH-LOOP.md -> docs/reports/2025-11-18-quickfix-auth-loop.md - TECHNOLOGY-STACK-SUMMARY.md -> docs/architecture/technology-stack-legacy.md - TODO_TEST_UPDATES.md -> docs/reports/2025-11-19-todo-test-updates.md 5. Consolidated design folders: - Moved all docs/designs/ content into docs/design/ - Renamed PHASE-5-EXECUTIVE-SUMMARY.md to phase-5-executive-summary.md (consistent naming) - Removed empty docs/designs/ directory 6. Added ADR-021: IndieAuth Provider Strategy - Documents decision to build own IndieAuth provider - Explains rationale and trade-offs Repository root now contains only: README.md, CLAUDE.md, CHANGELOG.md 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
412
CLAUDE.MD
412
CLAUDE.MD
@@ -1,412 +0,0 @@
|
|||||||
# StarPunk - Minimal IndieWeb CMS
|
|
||||||
|
|
||||||
## Project Overview
|
|
||||||
|
|
||||||
StarPunk is a minimalist, single-user CMS for publishing IndieWeb-compatible notes with RSS syndication. It emphasizes simplicity, elegance, and standards compliance.
|
|
||||||
|
|
||||||
**Core Philosophy**: Every line of code must justify its existence. When in doubt, leave it out.
|
|
||||||
|
|
||||||
## V1 Scope
|
|
||||||
|
|
||||||
### Must Have
|
|
||||||
- Publish notes (https://indieweb.org/note)
|
|
||||||
- IndieAuth authentication (https://indieauth.spec.indieweb.org)
|
|
||||||
- Micropub server endpoint (https://micropub.spec.indieweb.org)
|
|
||||||
- RSS feed generation
|
|
||||||
- API-first architecture
|
|
||||||
- Markdown support
|
|
||||||
- Self-hostable deployment
|
|
||||||
|
|
||||||
### Won't Have (V1)
|
|
||||||
- Webmentions
|
|
||||||
- POSSE (beyond RSS)
|
|
||||||
- Multiple users
|
|
||||||
- Comments
|
|
||||||
- Analytics
|
|
||||||
- Themes/customization
|
|
||||||
- Media uploads
|
|
||||||
- Other post types (articles, photos, replies)
|
|
||||||
|
|
||||||
## System Architecture
|
|
||||||
|
|
||||||
### Core Components
|
|
||||||
|
|
||||||
1. **Data Layer**
|
|
||||||
- Notes storage (content, HTML rendering, timestamps, slugs)
|
|
||||||
- Authentication tokens for IndieAuth sessions
|
|
||||||
- Simple schema with minimal relationships
|
|
||||||
- Persistence with backup capability
|
|
||||||
|
|
||||||
2. **API Layer**
|
|
||||||
- RESTful endpoints for note management
|
|
||||||
- Micropub endpoint for external clients
|
|
||||||
- IndieAuth implementation
|
|
||||||
- RSS feed generation
|
|
||||||
- JSON responses for all APIs
|
|
||||||
|
|
||||||
3. **Web Interface**
|
|
||||||
- Minimal public interface displaying notes
|
|
||||||
- Admin interface for creating/managing notes
|
|
||||||
- Single elegant theme
|
|
||||||
- Proper microformats markup (h-entry, h-card)
|
|
||||||
- No client-side complexity
|
|
||||||
|
|
||||||
### Data Model
|
|
||||||
|
|
||||||
```
|
|
||||||
Notes:
|
|
||||||
- id: unique identifier
|
|
||||||
- content: raw markdown text
|
|
||||||
- content_html: rendered HTML
|
|
||||||
- slug: URL-friendly identifier
|
|
||||||
- published: boolean flag
|
|
||||||
- created_at: timestamp
|
|
||||||
- updated_at: timestamp
|
|
||||||
|
|
||||||
Tokens:
|
|
||||||
- token: unique token string
|
|
||||||
- me: user identity URL
|
|
||||||
- client_id: micropub client identifier
|
|
||||||
- scope: permission scope
|
|
||||||
- created_at: timestamp
|
|
||||||
- expires_at: optional expiration
|
|
||||||
```
|
|
||||||
|
|
||||||
### URL Structure
|
|
||||||
|
|
||||||
```
|
|
||||||
/ # Homepage with recent notes
|
|
||||||
/note/{slug} # Individual note permalink
|
|
||||||
/admin # Admin dashboard
|
|
||||||
/admin/new # Create new note
|
|
||||||
/api/micropub # Micropub endpoint
|
|
||||||
/api/notes # Notes CRUD API
|
|
||||||
/api/auth # IndieAuth endpoints
|
|
||||||
/feed.xml # RSS feed
|
|
||||||
/.well-known/oauth-authorization-server # IndieAuth metadata
|
|
||||||
```
|
|
||||||
|
|
||||||
## Implementation Requirements
|
|
||||||
|
|
||||||
### Phase 1: Foundation
|
|
||||||
|
|
||||||
**Data Storage**
|
|
||||||
- Implement note storage with CRUD operations
|
|
||||||
- Support markdown content with HTML rendering
|
|
||||||
- Generate unique slugs for URLs
|
|
||||||
- Track creation and update timestamps
|
|
||||||
|
|
||||||
**Configuration**
|
|
||||||
- Site URL (required for absolute URLs)
|
|
||||||
- Site title and author information
|
|
||||||
- IndieAuth endpoint configuration
|
|
||||||
- Environment-based configuration
|
|
||||||
|
|
||||||
### Phase 2: Core APIs
|
|
||||||
|
|
||||||
**Notes API**
|
|
||||||
- GET /api/notes - List published notes
|
|
||||||
- POST /api/notes - Create new note (authenticated)
|
|
||||||
- GET /api/notes/{id} - Get single note
|
|
||||||
- PUT /api/notes/{id} - Update note (authenticated)
|
|
||||||
- DELETE /api/notes/{id} - Delete note (authenticated)
|
|
||||||
|
|
||||||
**RSS Feed**
|
|
||||||
- Generate valid RSS 2.0 feed
|
|
||||||
- Include all published notes
|
|
||||||
- Proper date formatting (RFC-822)
|
|
||||||
- CDATA wrapping for HTML content
|
|
||||||
- Cache appropriately (5 minute minimum)
|
|
||||||
|
|
||||||
### Phase 3: IndieAuth Implementation
|
|
||||||
|
|
||||||
**Authorization Endpoint**
|
|
||||||
- Validate client_id parameter
|
|
||||||
- Verify redirect_uri matches registered client
|
|
||||||
- Generate authorization codes
|
|
||||||
- Support PKCE flow
|
|
||||||
|
|
||||||
**Token Endpoint**
|
|
||||||
- Exchange authorization codes for access tokens
|
|
||||||
- Validate code verifier for PKCE
|
|
||||||
- Return token with appropriate scope
|
|
||||||
- Store token with expiration
|
|
||||||
|
|
||||||
**Token Verification**
|
|
||||||
- Validate bearer tokens in Authorization header
|
|
||||||
- Check token expiration
|
|
||||||
- Verify scope for requested operation
|
|
||||||
|
|
||||||
### Phase 4: Micropub Implementation
|
|
||||||
|
|
||||||
**POST Endpoint**
|
|
||||||
- Support JSON format (Content-Type: application/json)
|
|
||||||
- Support form-encoded format (Content-Type: application/x-www-form-urlencoded)
|
|
||||||
- Handle h-entry creation for notes
|
|
||||||
- Return 201 Created with Location header
|
|
||||||
- Validate authentication token
|
|
||||||
|
|
||||||
**GET Endpoint**
|
|
||||||
- Support q=config query (return supported features)
|
|
||||||
- Support q=source query (return note source)
|
|
||||||
- Return appropriate JSON responses
|
|
||||||
|
|
||||||
**Micropub Request Structure (JSON)**
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"type": ["h-entry"],
|
|
||||||
"properties": {
|
|
||||||
"content": ["Note content here"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Micropub Response**
|
|
||||||
```
|
|
||||||
HTTP/1.1 201 Created
|
|
||||||
Location: https://example.com/note/abc123
|
|
||||||
```
|
|
||||||
|
|
||||||
### Phase 5: Web Interface
|
|
||||||
|
|
||||||
**Homepage Requirements**
|
|
||||||
- Display notes in reverse chronological order
|
|
||||||
- Include proper h-entry microformats
|
|
||||||
- Show note content (e-content class)
|
|
||||||
- Include permalink (u-url class)
|
|
||||||
- Display publish date (dt-published class)
|
|
||||||
- Clean, readable typography
|
|
||||||
- Mobile-responsive design
|
|
||||||
|
|
||||||
**Note Permalink Page**
|
|
||||||
- Full note display with microformats
|
|
||||||
- Author information (h-card)
|
|
||||||
- Timestamp and permalink
|
|
||||||
- Link back to homepage
|
|
||||||
|
|
||||||
**Admin Interface**
|
|
||||||
- Simple markdown editor
|
|
||||||
- Preview capability
|
|
||||||
- Publish/Draft toggle
|
|
||||||
- List of existing notes
|
|
||||||
- Edit existing notes
|
|
||||||
- Protected by authentication
|
|
||||||
|
|
||||||
**Microformats Example**
|
|
||||||
```html
|
|
||||||
<article class="h-entry">
|
|
||||||
<div class="e-content">
|
|
||||||
<p>Note content goes here</p>
|
|
||||||
</div>
|
|
||||||
<footer>
|
|
||||||
<a class="u-url" href="/note/abc123">
|
|
||||||
<time class="dt-published" datetime="2024-01-01T12:00:00Z">
|
|
||||||
January 1, 2024
|
|
||||||
</time>
|
|
||||||
</a>
|
|
||||||
</footer>
|
|
||||||
</article>
|
|
||||||
```
|
|
||||||
|
|
||||||
### Phase 6: Deployment
|
|
||||||
|
|
||||||
**Requirements**
|
|
||||||
- Self-hostable package
|
|
||||||
- Single deployment unit
|
|
||||||
- Persistent data storage
|
|
||||||
- Environment-based configuration
|
|
||||||
- Backup-friendly data format
|
|
||||||
|
|
||||||
**Configuration Variables**
|
|
||||||
- SITE_URL - Full URL of the site
|
|
||||||
- SITE_TITLE - Site name for RSS feed
|
|
||||||
- SITE_AUTHOR - Default author name
|
|
||||||
- INDIEAUTH_ENDPOINT - IndieAuth provider URL
|
|
||||||
- DATA_PATH - Location for persistent storage
|
|
||||||
|
|
||||||
### Phase 7: Testing
|
|
||||||
|
|
||||||
**Unit Tests Required**
|
|
||||||
- Data layer operations
|
|
||||||
- Micropub request parsing
|
|
||||||
- IndieAuth token validation
|
|
||||||
- Markdown rendering
|
|
||||||
- Slug generation
|
|
||||||
|
|
||||||
**Integration Tests**
|
|
||||||
- Complete Micropub flow
|
|
||||||
- IndieAuth authentication flow
|
|
||||||
- RSS feed generation
|
|
||||||
- API endpoint responses
|
|
||||||
|
|
||||||
**Test Coverage Areas**
|
|
||||||
- Note creation via web interface
|
|
||||||
- Note creation via Micropub
|
|
||||||
- Authentication flows
|
|
||||||
- Feed validation
|
|
||||||
- Error handling
|
|
||||||
|
|
||||||
## Standards Compliance
|
|
||||||
|
|
||||||
### IndieWeb Standards
|
|
||||||
|
|
||||||
**Microformats2**
|
|
||||||
- h-entry for notes
|
|
||||||
- h-card for author information
|
|
||||||
- e-content for note content
|
|
||||||
- dt-published for timestamps
|
|
||||||
- u-url for permalinks
|
|
||||||
|
|
||||||
**IndieAuth**
|
|
||||||
- OAuth 2.0 compatible flow
|
|
||||||
- Support for authorization code grant
|
|
||||||
- PKCE support recommended
|
|
||||||
- Token introspection endpoint
|
|
||||||
|
|
||||||
**Micropub**
|
|
||||||
- JSON and form-encoded content types
|
|
||||||
- Location header on creation
|
|
||||||
- Configuration endpoint
|
|
||||||
- Source endpoint for queries
|
|
||||||
|
|
||||||
### Web Standards
|
|
||||||
|
|
||||||
**HTTP**
|
|
||||||
- Proper status codes (200, 201, 400, 401, 404)
|
|
||||||
- Content-Type headers
|
|
||||||
- Cache-Control headers where appropriate
|
|
||||||
- CORS headers for API endpoints
|
|
||||||
|
|
||||||
**RSS 2.0**
|
|
||||||
- Valid XML structure
|
|
||||||
- Required channel elements
|
|
||||||
- Proper date formatting
|
|
||||||
- GUID for each item
|
|
||||||
- CDATA for HTML content
|
|
||||||
|
|
||||||
**HTML**
|
|
||||||
- Semantic HTML5 elements
|
|
||||||
- Valid markup
|
|
||||||
- Accessible forms
|
|
||||||
- Mobile-responsive design
|
|
||||||
|
|
||||||
## Security Considerations
|
|
||||||
|
|
||||||
### Authentication
|
|
||||||
- Validate all tokens before operations
|
|
||||||
- Implement token expiration
|
|
||||||
- Use secure token generation
|
|
||||||
- Protect admin routes
|
|
||||||
|
|
||||||
### Input Validation
|
|
||||||
- Sanitize markdown input
|
|
||||||
- Validate Micropub payloads
|
|
||||||
- Prevent SQL injection
|
|
||||||
- Escape HTML appropriately
|
|
||||||
|
|
||||||
### HTTP Security
|
|
||||||
- Use HTTPS in production
|
|
||||||
- Set secure headers
|
|
||||||
- Implement CSRF protection
|
|
||||||
- Rate limit API endpoints
|
|
||||||
|
|
||||||
## Performance Guidelines
|
|
||||||
|
|
||||||
### Response Times
|
|
||||||
- API responses < 100ms
|
|
||||||
- Page loads < 200ms
|
|
||||||
- RSS feed generation < 300ms
|
|
||||||
|
|
||||||
### Caching Strategy
|
|
||||||
- Cache RSS feed (5 minutes)
|
|
||||||
- Cache static assets
|
|
||||||
- Database query optimization
|
|
||||||
- Minimize external dependencies
|
|
||||||
|
|
||||||
### Resource Usage
|
|
||||||
- Efficient database queries
|
|
||||||
- Minimal memory footprint
|
|
||||||
- Optimize HTML/CSS delivery
|
|
||||||
- Compress responses
|
|
||||||
|
|
||||||
## Testing Checklist
|
|
||||||
|
|
||||||
- [ ] Create notes via web interface
|
|
||||||
- [ ] Create notes via Micropub JSON
|
|
||||||
- [ ] Create notes via Micropub form-encoded
|
|
||||||
- [ ] RSS feed validates (W3C validator)
|
|
||||||
- [ ] IndieAuth login flow works
|
|
||||||
- [ ] Micropub client authentication
|
|
||||||
- [ ] Notes display with proper microformats
|
|
||||||
- [ ] API returns correct status codes
|
|
||||||
- [ ] Markdown renders correctly
|
|
||||||
- [ ] Slugs generate uniquely
|
|
||||||
- [ ] Timestamps record accurately
|
|
||||||
- [ ] Token expiration works
|
|
||||||
- [ ] Rate limiting functions
|
|
||||||
- [ ] All unit tests pass
|
|
||||||
|
|
||||||
## Validation Tools
|
|
||||||
|
|
||||||
**IndieWeb**
|
|
||||||
- https://indiewebify.me/ - Verify microformats
|
|
||||||
- https://indieauth.com/validate - Test IndieAuth
|
|
||||||
- https://micropub.rocks/ - Micropub test suite
|
|
||||||
|
|
||||||
**Web Standards**
|
|
||||||
- https://validator.w3.org/feed/ - RSS validator
|
|
||||||
- https://validator.w3.org/ - HTML validator
|
|
||||||
- https://jsonlint.com/ - JSON validator
|
|
||||||
|
|
||||||
## Resources
|
|
||||||
|
|
||||||
### Specifications
|
|
||||||
- IndieWeb Notes: https://indieweb.org/note
|
|
||||||
- Micropub Spec: https://micropub.spec.indieweb.org
|
|
||||||
- IndieAuth Spec: https://indieauth.spec.indieweb.org
|
|
||||||
- Microformats2: http://microformats.org/wiki/h-entry
|
|
||||||
- RSS 2.0 Spec: https://www.rssboard.org/rss-specification
|
|
||||||
|
|
||||||
### Testing & Validation
|
|
||||||
- Micropub Test Suite: https://micropub.rocks/
|
|
||||||
- IndieAuth Testing: https://indieauth.com/
|
|
||||||
- Microformats Parser: https://pin13.net/mf2/
|
|
||||||
|
|
||||||
### Example Implementations
|
|
||||||
- IndieWeb Examples: https://indieweb.org/examples
|
|
||||||
- Micropub Clients: https://indieweb.org/Micropub/Clients
|
|
||||||
|
|
||||||
## Development Principles
|
|
||||||
|
|
||||||
1. **Minimal Code**: Every feature must justify its complexity
|
|
||||||
2. **Standards First**: Follow specifications exactly
|
|
||||||
3. **User Control**: User owns their data completely
|
|
||||||
4. **No Lock-in**: Data must be portable and exportable
|
|
||||||
5. **Progressive Enhancement**: Core functionality works without JavaScript
|
|
||||||
6. **Documentation**: Code should be self-documenting
|
|
||||||
7. **Test Coverage**: Critical paths must have tests
|
|
||||||
|
|
||||||
## Future Considerations (Post-V1)
|
|
||||||
|
|
||||||
Potential V2 features:
|
|
||||||
- Webmentions support
|
|
||||||
- Media uploads (photos)
|
|
||||||
- Additional post types (articles, replies)
|
|
||||||
- POSSE to Mastodon/ActivityPub
|
|
||||||
- Full-text search
|
|
||||||
- Draft/scheduled posts
|
|
||||||
- Multiple IndieAuth providers
|
|
||||||
- Backup/restore functionality
|
|
||||||
- Import from other platforms
|
|
||||||
- Export in multiple formats
|
|
||||||
|
|
||||||
## Success Criteria
|
|
||||||
|
|
||||||
The project is successful when:
|
|
||||||
- A user can publish notes from any Micropub client
|
|
||||||
- Notes appear in RSS readers immediately
|
|
||||||
- The system runs on minimal resources
|
|
||||||
- Code is readable and maintainable
|
|
||||||
- All IndieWeb validators pass
|
|
||||||
- Setup takes less than 5 minutes
|
|
||||||
- System runs for months without intervention
|
|
||||||
48
CLAUDE.md
48
CLAUDE.md
@@ -1,4 +1,44 @@
|
|||||||
- we use uv for python venv management in this project so commands involving python probably need to be run with uv
|
# Claude Agent Instructions
|
||||||
- whenever you invoke agent-developer you will remind it to document what it does in docs/reports, update the changelog, and increment the version number where appropriate inline with docs/standards/versioning-strategy.md
|
|
||||||
- when invoking agent-developer remind in that we are using uv and that any pyrhon commands need to be run with uv
|
This file contains operational instructions for Claude agents working on this project.
|
||||||
- when invoking agent-developer make sure it follows proper git protocol as defined in docs/standards/git-branching-strategy.md
|
|
||||||
|
## Python Environment
|
||||||
|
|
||||||
|
- We use **uv** for Python virtual environment management
|
||||||
|
- All Python commands must be run with `uv run` prefix
|
||||||
|
- Example: `uv run pytest`, `uv run flask run`
|
||||||
|
|
||||||
|
## Agent-Developer Protocol
|
||||||
|
|
||||||
|
When invoking the agent-developer, always remind it to:
|
||||||
|
|
||||||
|
1. **Document work in reports**
|
||||||
|
- Create implementation reports in `docs/reports/`
|
||||||
|
- Include date in filename: `YYYY-MM-DD-description.md`
|
||||||
|
|
||||||
|
2. **Update the changelog**
|
||||||
|
- Add entries to `CHANGELOG.md` for user-facing changes
|
||||||
|
- Follow existing format
|
||||||
|
|
||||||
|
3. **Version number management**
|
||||||
|
- Increment version numbers according to `docs/standards/versioning-strategy.md`
|
||||||
|
- Update version in `starpunk/__init__.py`
|
||||||
|
|
||||||
|
4. **Follow git protocol**
|
||||||
|
- Adhere to git branching strategy in `docs/standards/git-branching-strategy.md`
|
||||||
|
- Create feature branches for non-trivial changes
|
||||||
|
- Write clear commit messages
|
||||||
|
|
||||||
|
## Key Documentation References
|
||||||
|
|
||||||
|
- **Architecture**: See `docs/architecture/overview.md`
|
||||||
|
- **Implementation Plan**: See `docs/projectplan/v1/implementation-plan.md`
|
||||||
|
- **Feature Scope**: See `docs/projectplan/v1/feature-scope.md`
|
||||||
|
- **Coding Standards**: See `docs/standards/python-coding-standards.md`
|
||||||
|
- **Testing**: See `docs/standards/testing-checklist.md`
|
||||||
|
|
||||||
|
## Project Philosophy
|
||||||
|
|
||||||
|
"Every line of code must justify its existence. When in doubt, leave it out."
|
||||||
|
|
||||||
|
Keep implementations minimal, standards-compliant, and maintainable.
|
||||||
|
|||||||
541
docs/decisions/ADR-021-indieauth-provider-strategy.md
Normal file
541
docs/decisions/ADR-021-indieauth-provider-strategy.md
Normal file
@@ -0,0 +1,541 @@
|
|||||||
|
# ADR-021: IndieAuth Provider Strategy
|
||||||
|
|
||||||
|
## Status
|
||||||
|
Accepted
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
StarPunk currently uses IndieLogin.com for authentication (ADR-005), but there is a critical misunderstanding about how IndieAuth works that needs to be addressed.
|
||||||
|
|
||||||
|
### The Problem
|
||||||
|
|
||||||
|
The user reported that IndieLogin.com requires manual client_id registration, making it unsuitable for self-hosted software where each installation has a different domain. This concern is based on a fundamental misunderstanding of how IndieAuth differs from traditional OAuth2.
|
||||||
|
|
||||||
|
### How IndieAuth Actually Works
|
||||||
|
|
||||||
|
Unlike traditional OAuth2 providers (GitHub, Google, etc.), **IndieAuth does not require pre-registration**:
|
||||||
|
|
||||||
|
1. **DNS-Based Client Identification**: IndieAuth uses DNS as a replacement for client registration. A client application identifies itself using its own URL (e.g., `https://starpunk.example.com`), which serves as a unique identifier.
|
||||||
|
|
||||||
|
2. **No Secrets Required**: All clients are public clients. There are no client secrets to manage or register.
|
||||||
|
|
||||||
|
3. **Dynamic Redirect URI Verification**: Instead of pre-registered redirect URIs, applications publish their valid redirect URLs at their client_id URL, which authorization servers can discover.
|
||||||
|
|
||||||
|
4. **Client Metadata Discovery**: Authorization servers can optionally fetch the client_id URL to display application information (name, logo) to users during authorization.
|
||||||
|
|
||||||
|
### StarPunk's Authentication Architecture
|
||||||
|
|
||||||
|
It is critical to understand that StarPunk has **two distinct authentication flows**:
|
||||||
|
|
||||||
|
#### Flow 1: Admin Authentication (Current Misunderstanding)
|
||||||
|
**Purpose**: Authenticate the StarPunk admin user to access the admin interface
|
||||||
|
**Current Implementation**: Uses IndieLogin.com as described in ADR-005
|
||||||
|
**How it works**:
|
||||||
|
1. Admin visits `/admin/login`
|
||||||
|
2. StarPunk redirects to IndieLogin.com with its own URL as `client_id`
|
||||||
|
3. IndieLogin.com verifies the admin's identity
|
||||||
|
4. Admin receives session cookie to access StarPunk admin
|
||||||
|
|
||||||
|
**Registration Required?** NO - IndieAuth never requires registration
|
||||||
|
|
||||||
|
#### Flow 2: Micropub Client Authorization (The Real Architecture)
|
||||||
|
**Purpose**: Allow external Micropub clients to publish to StarPunk
|
||||||
|
**How it works**:
|
||||||
|
1. User configures their personal website (e.g., `https://alice.com`) with links to StarPunk's Micropub endpoint
|
||||||
|
2. User opens Micropub client (Quill, Indigenous, etc.)
|
||||||
|
3. Client discovers authorization/token endpoints from `https://alice.com` (NOT from StarPunk)
|
||||||
|
4. Client gets access token from the discovered authorization server
|
||||||
|
5. Client uses token to POST to StarPunk's Micropub endpoint
|
||||||
|
6. StarPunk verifies the token
|
||||||
|
|
||||||
|
**Who Provides Authorization?** The USER's chosen authorization server, not StarPunk
|
||||||
|
|
||||||
|
### The Real Question
|
||||||
|
|
||||||
|
StarPunk faces two architectural decisions:
|
||||||
|
|
||||||
|
1. **Admin Authentication**: How should StarPunk administrators authenticate to the admin interface?
|
||||||
|
2. **User Authorization**: Should StarPunk provide authorization/token endpoints for its users, or should users bring their own?
|
||||||
|
|
||||||
|
## Research Findings
|
||||||
|
|
||||||
|
### Alternative IndieAuth Services
|
||||||
|
|
||||||
|
**IndieLogin.com** (Current)
|
||||||
|
- Actively maintained by Aaron Parecki (IndieAuth spec editor)
|
||||||
|
- Supports multiple auth methods: RelMeAuth, email, PGP, BlueSky OAuth (added 2025)
|
||||||
|
- **No registration required** - this was the key misunderstanding
|
||||||
|
- Free, community service
|
||||||
|
- High availability
|
||||||
|
|
||||||
|
**tokens.indieauth.com**
|
||||||
|
- Provides token endpoint functionality
|
||||||
|
- Separate from authorization endpoint
|
||||||
|
- Also maintained by IndieWeb community
|
||||||
|
- Also requires no registration
|
||||||
|
|
||||||
|
**Other Services**
|
||||||
|
- No other widely-used public IndieAuth providers found
|
||||||
|
- Most implementations are self-hosted (see below)
|
||||||
|
|
||||||
|
### Self-Hosted IndieAuth Implementations
|
||||||
|
|
||||||
|
**Taproot/IndieAuth** (PHP)
|
||||||
|
- Complexity: Moderate (7/10)
|
||||||
|
- Full-featured: Authorization + token endpoints
|
||||||
|
- PSR-7 compatible, well-tested (100% coverage)
|
||||||
|
- Lightweight dependencies (Guzzle, mf2)
|
||||||
|
- Production-ready since v0.1.0
|
||||||
|
|
||||||
|
**Selfauth** (PHP)
|
||||||
|
- Complexity: Low (3/10)
|
||||||
|
- **Limitation**: Authorization endpoint ONLY (no token endpoint)
|
||||||
|
- Cannot be used for Micropub (requires token endpoint)
|
||||||
|
- Suitable only for simple authentication use cases
|
||||||
|
|
||||||
|
**hacdias/indieauth** (Go)
|
||||||
|
- Complexity: Moderate (6/10)
|
||||||
|
- Provides both server and client libraries
|
||||||
|
- Modern Go implementation
|
||||||
|
- Used in production by author
|
||||||
|
|
||||||
|
**Custom Implementation** (Python)
|
||||||
|
- Complexity: High (8/10)
|
||||||
|
- Must implement IndieAuth spec 1.1
|
||||||
|
- Required endpoints:
|
||||||
|
- Authorization endpoint (authentication + code generation)
|
||||||
|
- Token endpoint (token issuance + verification)
|
||||||
|
- Metadata endpoint (server discovery)
|
||||||
|
- Introspection endpoint (token verification)
|
||||||
|
- Must support:
|
||||||
|
- PKCE (required by spec)
|
||||||
|
- Client metadata discovery
|
||||||
|
- Profile URL validation
|
||||||
|
- Scope-based permissions
|
||||||
|
- Token revocation
|
||||||
|
- Estimated effort: 40-60 hours for full implementation
|
||||||
|
- Ongoing maintenance burden for security updates
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
|
||||||
|
**Recommendation: Continue Using IndieLogin.com with Clarified Architecture**
|
||||||
|
|
||||||
|
StarPunk should:
|
||||||
|
|
||||||
|
1. **For Admin Authentication**: Continue using IndieLogin.com (no changes needed)
|
||||||
|
- No registration required
|
||||||
|
- Works out of the box for self-hosted installations
|
||||||
|
- Each StarPunk instance uses its own domain as client_id
|
||||||
|
- Zero maintenance burden
|
||||||
|
|
||||||
|
2. **For Micropub Authorization**: Document that users must provide their own authorization server
|
||||||
|
- User configures their personal domain with IndieAuth endpoints
|
||||||
|
- User can choose:
|
||||||
|
- IndieLogin.com (easiest)
|
||||||
|
- Self-hosted IndieAuth server (advanced)
|
||||||
|
- Any other IndieAuth-compliant service
|
||||||
|
- StarPunk only verifies tokens, doesn't issue them
|
||||||
|
|
||||||
|
3. **For V2 Consideration**: Optionally provide built-in authorization server
|
||||||
|
- Would allow StarPunk to be a complete standalone solution
|
||||||
|
- Users could use StarPunk's domain as their identity
|
||||||
|
- Requires implementing full IndieAuth server (40-60 hours)
|
||||||
|
- Only pursue if there is strong user demand
|
||||||
|
|
||||||
|
## Rationale
|
||||||
|
|
||||||
|
### Why Continue with IndieLogin.com
|
||||||
|
|
||||||
|
**Simplicity Score: 10/10**
|
||||||
|
- Zero configuration required
|
||||||
|
- No registration process
|
||||||
|
- Works immediately for any domain
|
||||||
|
- Battle-tested by IndieWeb community
|
||||||
|
- The original concern (manual registration) does not exist
|
||||||
|
|
||||||
|
**Fitness Score: 10/10**
|
||||||
|
- Perfect for single-user CMS
|
||||||
|
- Aligns with IndieWeb principles
|
||||||
|
- User controls their identity
|
||||||
|
- No lock-in (user can switch authorization servers)
|
||||||
|
|
||||||
|
**Maintenance Score: 10/10**
|
||||||
|
- Externally maintained
|
||||||
|
- Security updates handled by community
|
||||||
|
- No code to maintain in StarPunk
|
||||||
|
- Proven reliability and uptime
|
||||||
|
|
||||||
|
**Standards Compliance: Pass**
|
||||||
|
- Full IndieAuth spec compliance
|
||||||
|
- OAuth 2.0 compatible
|
||||||
|
- Supports modern extensions (PKCE, client metadata)
|
||||||
|
|
||||||
|
### Why Not Self-Host (for V1)
|
||||||
|
|
||||||
|
**Complexity vs Benefit**
|
||||||
|
- Self-hosting adds 40-60 hours of development
|
||||||
|
- Ongoing security maintenance burden
|
||||||
|
- Solves a problem that doesn't exist (no registration required)
|
||||||
|
- Violates "every line of code must justify its existence"
|
||||||
|
|
||||||
|
**User Perspective**
|
||||||
|
- Users already need a domain for IndieWeb
|
||||||
|
- Most users will use IndieLogin.com or similar service
|
||||||
|
- Advanced users can self-host their own IndieAuth server
|
||||||
|
- StarPunk doesn't need to solve this problem
|
||||||
|
|
||||||
|
**Alternative Philosophy**
|
||||||
|
- StarPunk is a Micropub SERVER, not an authorization server
|
||||||
|
- Separation of concerns: publishing vs identity
|
||||||
|
- Users should control their own identity infrastructure
|
||||||
|
- StarPunk focuses on doing one thing well: publishing notes
|
||||||
|
|
||||||
|
## Architectural Clarification
|
||||||
|
|
||||||
|
### Current Architecture (Correct Understanding)
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────────────────────────────┐
|
||||||
|
│ Flow 1: Admin Authentication │
|
||||||
|
│ │
|
||||||
|
│ StarPunk Admin │
|
||||||
|
│ ↓ │
|
||||||
|
│ StarPunk (/admin/login) │
|
||||||
|
│ ↓ (redirect with client_id=https://starpunk.example) │
|
||||||
|
│ IndieLogin.com (verifies admin identity) │
|
||||||
|
│ ↓ (returns verified "me" URL) │
|
||||||
|
│ StarPunk (creates session) │
|
||||||
|
└─────────────────────────────────────────────────────────────┘
|
||||||
|
|
||||||
|
┌─────────────────────────────────────────────────────────────┐
|
||||||
|
│ Flow 2: Micropub Publishing │
|
||||||
|
│ │
|
||||||
|
│ User's Website (https://alice.com) │
|
||||||
|
│ Links to: │
|
||||||
|
│ - authorization_endpoint (IndieLogin or self-hosted) │
|
||||||
|
│ - token_endpoint (tokens.indieauth.com or self-hosted) │
|
||||||
|
│ - micropub endpoint (StarPunk) │
|
||||||
|
│ ↓ │
|
||||||
|
│ Micropub Client (Quill, Indigenous) │
|
||||||
|
│ ↓ (discovers endpoints from alice.com) │
|
||||||
|
│ Authorization Server (user's choice, NOT StarPunk) │
|
||||||
|
│ ↓ (issues access token) │
|
||||||
|
│ Micropub Client │
|
||||||
|
│ ↓ (POST with Bearer token) │
|
||||||
|
│ StarPunk Micropub Endpoint │
|
||||||
|
│ ↓ (verifies token with authorization server) │
|
||||||
|
│ StarPunk (creates note) │
|
||||||
|
└─────────────────────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
### What StarPunk Implements
|
||||||
|
|
||||||
|
**Currently Implemented** (ADR-005):
|
||||||
|
- Session-based admin authentication via IndieLogin.com
|
||||||
|
- CSRF protection (state tokens)
|
||||||
|
- Session management
|
||||||
|
- Admin route protection
|
||||||
|
|
||||||
|
**Must Be Implemented** (for Micropub):
|
||||||
|
- Token verification endpoint (query user's token endpoint)
|
||||||
|
- Bearer token extraction from Authorization header
|
||||||
|
- Scope verification (check token has "create" permission)
|
||||||
|
- Token storage/caching (optional, for performance)
|
||||||
|
|
||||||
|
**Does NOT Implement** (users provide these):
|
||||||
|
- Authorization endpoint (users use IndieLogin.com or self-hosted)
|
||||||
|
- Token endpoint (users use tokens.indieauth.com or self-hosted)
|
||||||
|
- User identity management (users own their domains)
|
||||||
|
|
||||||
|
## Implementation Outline
|
||||||
|
|
||||||
|
### No Changes Needed for Admin Auth
|
||||||
|
The current IndieLogin.com integration (ADR-005) is correct and requires no changes. Each self-hosted StarPunk installation uses its own domain as `client_id` without any registration.
|
||||||
|
|
||||||
|
### Required for Micropub Support
|
||||||
|
|
||||||
|
#### 1. Token Verification
|
||||||
|
```python
|
||||||
|
def verify_micropub_token(bearer_token, expected_me):
|
||||||
|
"""
|
||||||
|
Verify access token by querying the token endpoint
|
||||||
|
|
||||||
|
Args:
|
||||||
|
bearer_token: Token from Authorization header
|
||||||
|
expected_me: Expected user identity (from StarPunk config)
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict: Token info (me, client_id, scope) if valid
|
||||||
|
None: If token is invalid
|
||||||
|
"""
|
||||||
|
# Discover token endpoint from expected_me domain
|
||||||
|
token_endpoint = discover_token_endpoint(expected_me)
|
||||||
|
|
||||||
|
# Verify token
|
||||||
|
response = httpx.get(
|
||||||
|
token_endpoint,
|
||||||
|
headers={'Authorization': f'Bearer {bearer_token}'},
|
||||||
|
params={'token': bearer_token}
|
||||||
|
)
|
||||||
|
|
||||||
|
if response.status_code != 200:
|
||||||
|
return None
|
||||||
|
|
||||||
|
data = response.json()
|
||||||
|
|
||||||
|
# Verify token is for expected user
|
||||||
|
if data.get('me') != expected_me:
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Verify token has required scope
|
||||||
|
scope = data.get('scope', '')
|
||||||
|
if 'create' not in scope:
|
||||||
|
return None
|
||||||
|
|
||||||
|
return data
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2. Endpoint Discovery
|
||||||
|
```python
|
||||||
|
def discover_token_endpoint(me_url):
|
||||||
|
"""
|
||||||
|
Discover token endpoint from user's profile URL
|
||||||
|
|
||||||
|
Checks for:
|
||||||
|
1. indieauth-metadata endpoint
|
||||||
|
2. Fallback to direct token_endpoint link
|
||||||
|
"""
|
||||||
|
response = httpx.get(me_url)
|
||||||
|
|
||||||
|
# Check HTTP Link header
|
||||||
|
link_header = response.headers.get('Link', '')
|
||||||
|
# Parse link header for indieauth-metadata
|
||||||
|
|
||||||
|
# Check HTML <link> tags
|
||||||
|
# Parse HTML for <link rel="indieauth-metadata">
|
||||||
|
|
||||||
|
# Fetch metadata endpoint
|
||||||
|
# Return token_endpoint URL
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 3. Micropub Endpoint Protection
|
||||||
|
```python
|
||||||
|
@app.route('/api/micropub', methods=['POST'])
|
||||||
|
def micropub_endpoint():
|
||||||
|
# Extract bearer token
|
||||||
|
auth_header = request.headers.get('Authorization', '')
|
||||||
|
if not auth_header.startswith('Bearer '):
|
||||||
|
return {'error': 'unauthorized'}, 401
|
||||||
|
|
||||||
|
bearer_token = auth_header[7:] # Remove "Bearer "
|
||||||
|
|
||||||
|
# Verify token
|
||||||
|
token_info = verify_micropub_token(bearer_token, ADMIN_ME)
|
||||||
|
if not token_info:
|
||||||
|
return {'error': 'forbidden'}, 403
|
||||||
|
|
||||||
|
# Process Micropub request
|
||||||
|
# Create note
|
||||||
|
# Return 201 with Location header
|
||||||
|
```
|
||||||
|
|
||||||
|
### Documentation Updates
|
||||||
|
|
||||||
|
#### For Users (Setup Guide)
|
||||||
|
```markdown
|
||||||
|
# Setting Up Your IndieWeb Identity
|
||||||
|
|
||||||
|
To publish to StarPunk via Micropub clients:
|
||||||
|
|
||||||
|
1. **Add Links to Your Website**
|
||||||
|
Add these to your personal website's <head>:
|
||||||
|
```html
|
||||||
|
<link rel="authorization_endpoint" href="https://indielogin.com/auth">
|
||||||
|
<link rel="token_endpoint" href="https://tokens.indieauth.com/token">
|
||||||
|
<link rel="micropub" href="https://your-starpunk.example.com/api/micropub">
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Configure StarPunk**
|
||||||
|
Set your website URL in StarPunk configuration:
|
||||||
|
```
|
||||||
|
ADMIN_ME=https://your-website.com
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Use a Micropub Client**
|
||||||
|
- Quill: https://quill.p3k.io
|
||||||
|
- Indigenous (mobile app)
|
||||||
|
- Or any Micropub-compatible client
|
||||||
|
|
||||||
|
4. **Advanced: Self-Host Authorization**
|
||||||
|
Instead of IndieLogin.com, you can run your own IndieAuth server.
|
||||||
|
See: https://indieweb.org/IndieAuth#Software
|
||||||
|
```
|
||||||
|
|
||||||
|
#### For Developers (Architecture Docs)
|
||||||
|
Update `/home/phil/Projects/starpunk/docs/architecture/overview.md` to clarify the two authentication flows and explain that StarPunk is a Micropub server, not an authorization server.
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
### Positive
|
||||||
|
- **No development needed**: Current architecture is correct
|
||||||
|
- **No registration required**: Works for self-hosted installations out of the box
|
||||||
|
- **User control**: Users choose their own authorization provider
|
||||||
|
- **Standards compliant**: Proper separation of Micropub server and authorization server
|
||||||
|
- **Simple**: StarPunk focuses on publishing, not identity management
|
||||||
|
- **Flexible**: Users can switch authorization providers without affecting StarPunk
|
||||||
|
|
||||||
|
### Negative
|
||||||
|
- **User education required**: Must explain that they need to configure their domain
|
||||||
|
- **Not standalone**: StarPunk cannot function completely independently (requires external auth)
|
||||||
|
- **Dependency**: Relies on external services (mitigated: user chooses service)
|
||||||
|
|
||||||
|
### Neutral
|
||||||
|
- **Architectural purity**: Follows IndieWeb principle of separation of concerns
|
||||||
|
- **Complexity distribution**: Moves authorization complexity to where it belongs (identity provider)
|
||||||
|
|
||||||
|
## V2 Considerations
|
||||||
|
|
||||||
|
If there is user demand for a more integrated solution, V2 could add:
|
||||||
|
|
||||||
|
### Option A: Embedded IndieAuth Server
|
||||||
|
**Pros**:
|
||||||
|
- StarPunk becomes completely standalone
|
||||||
|
- Users can use StarPunk domain as their identity
|
||||||
|
- One-step setup for non-technical users
|
||||||
|
|
||||||
|
**Cons**:
|
||||||
|
- 40-60 hours development effort
|
||||||
|
- Ongoing security maintenance
|
||||||
|
- Adds complexity to codebase
|
||||||
|
- May violate simplicity principle
|
||||||
|
|
||||||
|
**Decision**: Only implement if users request it
|
||||||
|
|
||||||
|
### Option B: Hybrid Mode
|
||||||
|
**Pros**:
|
||||||
|
- Advanced users can use external auth (current behavior)
|
||||||
|
- Simple users can use built-in auth
|
||||||
|
- Best of both worlds
|
||||||
|
|
||||||
|
**Cons**:
|
||||||
|
- Even more complexity
|
||||||
|
- Two codepaths to maintain
|
||||||
|
- Configuration complexity
|
||||||
|
|
||||||
|
**Decision**: Defer until V2 user feedback
|
||||||
|
|
||||||
|
### Option C: StarPunk-Hosted Service
|
||||||
|
**Pros**:
|
||||||
|
- One StarPunk authorization server for all installations
|
||||||
|
- Users register their StarPunk instance once
|
||||||
|
- Simple for end users
|
||||||
|
|
||||||
|
**Cons**:
|
||||||
|
- Centralized service (not indie)
|
||||||
|
- Single point of failure
|
||||||
|
- Hosting/maintenance burden
|
||||||
|
- Violates IndieWeb principles
|
||||||
|
|
||||||
|
**Decision**: Rejected - not aligned with IndieWeb values
|
||||||
|
|
||||||
|
## Alternatives Considered
|
||||||
|
|
||||||
|
### Alternative 1: Self-Host IndieAuth (Taproot/PHP)
|
||||||
|
**Evaluation**:
|
||||||
|
- Complexity: Would require running PHP alongside Python
|
||||||
|
- Deployment: Two separate applications to manage
|
||||||
|
- Maintenance: Security updates for both Python and PHP
|
||||||
|
- Verdict: **Rejected** - adds unnecessary complexity
|
||||||
|
|
||||||
|
### Alternative 2: Port Taproot to Python
|
||||||
|
**Evaluation**:
|
||||||
|
- Effort: 40-60 hours development
|
||||||
|
- Maintenance: Full responsibility for security
|
||||||
|
- Value: Solves a non-existent problem (no registration needed)
|
||||||
|
- Verdict: **Rejected** - violates simplicity principle
|
||||||
|
|
||||||
|
### Alternative 3: Use OAuth2 Service (GitHub, Google)
|
||||||
|
**Evaluation**:
|
||||||
|
- Simplicity: Very simple to implement
|
||||||
|
- IndieWeb Compliance: **FAIL** - not IndieWeb compatible
|
||||||
|
- User Ownership: **FAIL** - users don't own their identity
|
||||||
|
- Verdict: **Rejected** - violates core requirements
|
||||||
|
|
||||||
|
### Alternative 4: Password Authentication
|
||||||
|
**Evaluation**:
|
||||||
|
- Simplicity: Moderate (password hashing, reset flows)
|
||||||
|
- IndieWeb Compliance: **FAIL** - not IndieWeb authentication
|
||||||
|
- Security: Must implement password best practices
|
||||||
|
- Verdict: **Rejected** - not aligned with IndieWeb principles
|
||||||
|
|
||||||
|
### Alternative 5: Use IndieAuth as Library (Client Side)
|
||||||
|
**Evaluation**:
|
||||||
|
- Would make StarPunk act as IndieAuth client to discover user's auth server
|
||||||
|
- Current architecture already does this for Micropub
|
||||||
|
- Admin interface uses simpler session-based auth
|
||||||
|
- Verdict: **Already implemented** for Micropub flow
|
||||||
|
|
||||||
|
## Migration Plan
|
||||||
|
|
||||||
|
### From Current Broken Understanding → Correct Understanding
|
||||||
|
|
||||||
|
**No Code Changes Required**
|
||||||
|
|
||||||
|
1. **Update Documentation**
|
||||||
|
- Clarify that no registration is needed
|
||||||
|
- Explain the two authentication flows
|
||||||
|
- Document Micropub setup for users
|
||||||
|
|
||||||
|
2. **Complete Micropub Implementation**
|
||||||
|
- Implement token verification
|
||||||
|
- Implement endpoint discovery
|
||||||
|
- Add Bearer token authentication
|
||||||
|
|
||||||
|
3. **User Education**
|
||||||
|
- Create setup guide explaining domain configuration
|
||||||
|
- Provide example HTML snippets
|
||||||
|
- Link to IndieWeb resources
|
||||||
|
|
||||||
|
### Timeline
|
||||||
|
- Documentation updates: 2 hours
|
||||||
|
- Micropub token verification: 8 hours
|
||||||
|
- Testing with real Micropub clients: 4 hours
|
||||||
|
- Total: ~14 hours
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
### IndieAuth Specifications
|
||||||
|
- [IndieAuth Spec](https://indieauth.spec.indieweb.org/) - Official W3C specification
|
||||||
|
- [OAuth 2.0](https://oauth.net/2/) - Underlying OAuth 2.0 foundation
|
||||||
|
- [Client Identifier](https://www.oauth.com/oauth2-servers/indieauth/) - How client_id works in IndieAuth
|
||||||
|
|
||||||
|
### Services
|
||||||
|
- [IndieLogin.com](https://indielogin.com/) - Public IndieAuth service (no registration)
|
||||||
|
- [IndieLogin API Docs](https://indielogin.com/api) - Integration documentation
|
||||||
|
- [tokens.indieauth.com](https://tokens.indieauth.com/token) - Public token endpoint service
|
||||||
|
|
||||||
|
### Self-Hosted Implementations
|
||||||
|
- [Taproot/IndieAuth](https://github.com/Taproot/indieauth) - PHP implementation
|
||||||
|
- [hacdias/indieauth](https://github.com/hacdias/indieauth) - Go implementation
|
||||||
|
- [Selfauth](https://github.com/Inklings-io/selfauth) - Simple auth-only PHP
|
||||||
|
|
||||||
|
### IndieWeb Resources
|
||||||
|
- [IndieWeb Wiki: IndieAuth](https://indieweb.org/IndieAuth) - Community documentation
|
||||||
|
- [IndieWeb Wiki: Micropub](https://indieweb.org/Micropub) - Micropub overview
|
||||||
|
- [IndieWeb Wiki: authorization-endpoint](https://indieweb.org/authorization-endpoint) - Endpoint details
|
||||||
|
|
||||||
|
### Related ADRs
|
||||||
|
- [ADR-005: IndieLogin Authentication](/home/phil/Projects/starpunk/docs/decisions/ADR-005-indielogin-authentication.md) - Original auth decision
|
||||||
|
- [ADR-010: Authentication Module Design](/home/phil/Projects/starpunk/docs/decisions/ADR-010-authentication-module-design.md) - Auth module structure
|
||||||
|
|
||||||
|
### Community Examples
|
||||||
|
- [Aaron Parecki's IndieAuth Notes](https://aaronparecki.com/2025/10/08/4/cimd) - Client ID metadata adoption
|
||||||
|
- [Jamie Tanna's IndieAuth Server](https://www.jvt.me/posts/2020/12/09/personal-indieauth-server/) - Self-hosted implementation
|
||||||
|
- [Micropub Servers](https://indieweb.org/Micropub/Servers) - Examples of Micropub implementations
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Document Version**: 1.0
|
||||||
|
**Created**: 2025-11-19
|
||||||
|
**Author**: StarPunk Architecture Team (agent-architect)
|
||||||
|
**Status**: Accepted
|
||||||
127
docs/standards/testing-checklist.md
Normal file
127
docs/standards/testing-checklist.md
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
# Testing Checklist
|
||||||
|
|
||||||
|
This document provides a comprehensive checklist for testing StarPunk functionality before release.
|
||||||
|
|
||||||
|
## Manual Testing Checklist
|
||||||
|
|
||||||
|
### Core Functionality
|
||||||
|
- [ ] Create notes via web interface
|
||||||
|
- [ ] Create notes via Micropub JSON
|
||||||
|
- [ ] Create notes via Micropub form-encoded
|
||||||
|
- [ ] Notes display with proper microformats
|
||||||
|
- [ ] Markdown renders correctly
|
||||||
|
- [ ] Slugs generate uniquely
|
||||||
|
- [ ] Timestamps record accurately
|
||||||
|
|
||||||
|
### Authentication & Security
|
||||||
|
- [ ] IndieAuth login flow works
|
||||||
|
- [ ] Micropub client authentication
|
||||||
|
- [ ] Token expiration works
|
||||||
|
- [ ] Rate limiting functions
|
||||||
|
|
||||||
|
### Syndication & Standards
|
||||||
|
- [ ] RSS feed validates (W3C validator)
|
||||||
|
- [ ] API returns correct status codes
|
||||||
|
|
||||||
|
### Automated Testing
|
||||||
|
- [ ] All unit tests pass
|
||||||
|
- [ ] All integration tests pass
|
||||||
|
- [ ] Test coverage >80%
|
||||||
|
|
||||||
|
## Validation Tools
|
||||||
|
|
||||||
|
### IndieWeb Standards
|
||||||
|
- **IndieWebify.me**: https://indiewebify.me/
|
||||||
|
- Verify microformats (h-entry, h-card, h-feed)
|
||||||
|
- Check IndieAuth implementation
|
||||||
|
|
||||||
|
- **IndieAuth Validator**: https://indieauth.com/validate
|
||||||
|
- Test IndieAuth flow
|
||||||
|
- Validate token handling
|
||||||
|
|
||||||
|
- **Micropub Test Suite**: https://micropub.rocks/
|
||||||
|
- Comprehensive Micropub endpoint testing
|
||||||
|
- Verify spec compliance
|
||||||
|
|
||||||
|
### Web Standards
|
||||||
|
- **W3C Feed Validator**: https://validator.w3.org/feed/
|
||||||
|
- Validate RSS 2.0 feed structure
|
||||||
|
- Check date formatting
|
||||||
|
- Verify CDATA wrapping
|
||||||
|
|
||||||
|
- **W3C HTML Validator**: https://validator.w3.org/
|
||||||
|
- Validate HTML5 markup
|
||||||
|
- Check semantic structure
|
||||||
|
- Verify accessibility
|
||||||
|
|
||||||
|
- **JSON Validator**: https://jsonlint.com/
|
||||||
|
- Validate API responses
|
||||||
|
- Check Micropub payloads
|
||||||
|
|
||||||
|
## Testing Resources
|
||||||
|
|
||||||
|
### Specifications
|
||||||
|
- IndieWeb Notes: https://indieweb.org/note
|
||||||
|
- Micropub Spec: https://micropub.spec.indieweb.org
|
||||||
|
- IndieAuth Spec: https://indieauth.spec.indieweb.org
|
||||||
|
- Microformats2: http://microformats.org/wiki/h-entry
|
||||||
|
- RSS 2.0 Spec: https://www.rssboard.org/rss-specification
|
||||||
|
|
||||||
|
### Testing & Validation
|
||||||
|
- Micropub Test Suite: https://micropub.rocks/
|
||||||
|
- IndieAuth Testing: https://indieauth.com/
|
||||||
|
- Microformats Parser: https://pin13.net/mf2/
|
||||||
|
|
||||||
|
### Example Implementations
|
||||||
|
- IndieWeb Examples: https://indieweb.org/examples
|
||||||
|
- Micropub Clients: https://indieweb.org/Micropub/Clients
|
||||||
|
|
||||||
|
## Pre-Release Validation Workflow
|
||||||
|
|
||||||
|
1. **Run Automated Tests**
|
||||||
|
```bash
|
||||||
|
uv run pytest
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Validate HTML**
|
||||||
|
- Test homepage output
|
||||||
|
- Test note permalink output
|
||||||
|
- Run through W3C HTML Validator
|
||||||
|
|
||||||
|
3. **Validate RSS Feed**
|
||||||
|
- Access /feed.xml
|
||||||
|
- Run through W3C Feed Validator
|
||||||
|
- Verify in actual RSS reader
|
||||||
|
|
||||||
|
4. **Validate Microformats**
|
||||||
|
- Test homepage with IndieWebify.me
|
||||||
|
- Test note permalinks
|
||||||
|
- Use microformats parser
|
||||||
|
|
||||||
|
5. **Validate Micropub**
|
||||||
|
- Run micropub.rocks test suite
|
||||||
|
- Test with real Micropub client (Quill)
|
||||||
|
|
||||||
|
6. **Manual Browser Testing**
|
||||||
|
- Chrome/Chromium
|
||||||
|
- Firefox
|
||||||
|
- Safari (if available)
|
||||||
|
- Mobile browsers
|
||||||
|
|
||||||
|
7. **Security Verification**
|
||||||
|
- CSRF protection working
|
||||||
|
- XSS prevention verified
|
||||||
|
- SQL injection tests pass
|
||||||
|
- Path traversal prevention works
|
||||||
|
|
||||||
|
## Success Criteria
|
||||||
|
|
||||||
|
All checklist items must pass before V1 release. If any validation tool reports errors, they must be fixed before proceeding.
|
||||||
|
|
||||||
|
## Related Documentation
|
||||||
|
|
||||||
|
- [Testing Strategy](/home/phil/Projects/starpunk/docs/architecture/overview.md#testing-strategy)
|
||||||
|
- [Implementation Plan](/home/phil/Projects/starpunk/docs/projectplan/v1/implementation-plan.md)
|
||||||
|
- [Feature Scope](/home/phil/Projects/starpunk/docs/projectplan/v1/feature-scope.md)
|
||||||
|
|
||||||
|
**Last Updated**: 2025-11-24
|
||||||
Reference in New Issue
Block a user