feat(tags): Add database schema and tags module (v1.3.0 Phase 1)
Implements tag/category system backend following microformats2 p-category specification. Database changes: - Migration 008: Add tags and note_tags tables - Normalized tag storage (case-insensitive lookup, display name preserved) - Indexes for performance New module: - starpunk/tags.py: Tag management functions - normalize_tag: Normalize tag strings - get_or_create_tag: Get or create tag records - add_tags_to_note: Associate tags with notes (replaces existing) - get_note_tags: Retrieve note tags (alphabetically ordered) - get_tag_by_name: Lookup tag by normalized name - get_notes_by_tag: Get all notes with specific tag - parse_tag_input: Parse comma-separated tag input Model updates: - Note.tags property (lazy-loaded, prefer pre-loading in routes) - Note.to_dict() add include_tags parameter CRUD updates: - create_note() accepts tags parameter - update_note() accepts tags parameter (None = no change, [] = remove all) Micropub integration: - Pass tags to create_note() (tags already extracted by extract_tags()) - Return tags in q=source response Per design doc: docs/design/v1.3.0/microformats-tags-design.md Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
159
docs/design/v1.0.0/micropub-401-diagnosis.md
Normal file
159
docs/design/v1.0.0/micropub-401-diagnosis.md
Normal file
@@ -0,0 +1,159 @@
|
||||
# Micropub 401 Unauthorized Error - Architectural Diagnosis
|
||||
|
||||
## Issue Summary
|
||||
|
||||
The Micropub endpoint is returning 401 Unauthorized when accessed from Quill, a Micropub client. The request `GET /micropub?q=config` fails with a 401 response.
|
||||
|
||||
## Root Cause Analysis
|
||||
|
||||
After reviewing the implementation, I've identified the **primary issue**:
|
||||
|
||||
### The IndieAuth/Micropub Authentication Flow is Not Complete
|
||||
|
||||
The user (Quill client) has not completed the IndieAuth authorization flow to obtain an access token. The 401 error is occurring because:
|
||||
|
||||
1. **No Bearer Token Provided**: Quill is attempting to query the Micropub config endpoint without providing an access token
|
||||
2. **No Token Exists**: The database shows 0 tokens and 0 authorization codes, indicating no IndieAuth flow has been completed
|
||||
|
||||
## Authentication Flow Requirements
|
||||
|
||||
For Quill to successfully access the Micropub endpoint, it needs to:
|
||||
|
||||
1. **Complete IndieAuth Authorization**:
|
||||
- Quill should redirect user to `/auth/authorization`
|
||||
- User logs in as admin (if not already logged in)
|
||||
- User approves Quill's authorization request
|
||||
- Authorization code is generated
|
||||
|
||||
2. **Exchange Code for Token**:
|
||||
- Quill exchanges authorization code at `/auth/token`
|
||||
- Access token is generated and stored (hashed)
|
||||
- Token is returned to Quill
|
||||
|
||||
3. **Use Token for Micropub Requests**:
|
||||
- Quill includes token in Authorization header: `Bearer {token}`
|
||||
- Or as query parameter: `?access_token={token}`
|
||||
|
||||
## Current Implementation Status
|
||||
|
||||
### ✅ Correctly Implemented
|
||||
|
||||
1. **Micropub Endpoint** (`/micropub`):
|
||||
- Properly extracts bearer token from header or parameter
|
||||
- Validates token by hash lookup
|
||||
- Returns appropriate 401 when token missing/invalid
|
||||
|
||||
2. **Token Security**:
|
||||
- Tokens stored as SHA256 hashes (secure)
|
||||
- Database schema correct with proper indexes
|
||||
- Token expiry and revocation support
|
||||
|
||||
3. **Authorization Endpoint** (`/auth/authorization`):
|
||||
- Accepts IndieAuth parameters
|
||||
- Requires admin login for authorization
|
||||
- Generates authorization codes with PKCE support
|
||||
|
||||
4. **Token Endpoint** (`/auth/token`):
|
||||
- Exchanges authorization codes for access tokens
|
||||
- Validates all required parameters including `me`
|
||||
- Implements PKCE verification when used
|
||||
|
||||
### ❌ Missing/Issues
|
||||
|
||||
1. **No Discovery Mechanism**:
|
||||
- The site needs to advertise its IndieAuth endpoints
|
||||
- Missing `<link>` tags in HTML or HTTP headers
|
||||
- Quill can't discover where to authorize
|
||||
|
||||
2. **No Existing Tokens**:
|
||||
- Database shows no tokens have been created
|
||||
- User has not gone through authorization flow
|
||||
|
||||
## Solution Steps
|
||||
|
||||
### Immediate Fix - Manual Authorization
|
||||
|
||||
1. **Direct Quill to Authorization Endpoint**:
|
||||
```
|
||||
https://your-site.com/auth/authorization?
|
||||
response_type=code&
|
||||
client_id=https://quill.p3k.io/&
|
||||
redirect_uri=https://quill.p3k.io/auth/callback&
|
||||
state={random}&
|
||||
scope=create&
|
||||
me=https://example.com
|
||||
```
|
||||
|
||||
2. **Complete the Flow**:
|
||||
- Log in as admin when prompted
|
||||
- Approve Quill's authorization request
|
||||
- Let Quill exchange code for token
|
||||
- Token will be stored and usable
|
||||
|
||||
### Permanent Fix - Add Discovery
|
||||
|
||||
The site needs to advertise its IndieAuth endpoints. Add to the home page HTML `<head>`:
|
||||
|
||||
```html
|
||||
<link rel="authorization_endpoint" href="/auth/authorization">
|
||||
<link rel="token_endpoint" href="/auth/token">
|
||||
<link rel="micropub" href="/micropub">
|
||||
```
|
||||
|
||||
Or return as HTTP Link headers:
|
||||
|
||||
```
|
||||
Link: </auth/authorization>; rel="authorization_endpoint"
|
||||
Link: </auth/token>; rel="token_endpoint"
|
||||
Link: </micropub>; rel="micropub"
|
||||
```
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. **Check if authorization works**:
|
||||
- Navigate to `/auth/authorization` with proper parameters
|
||||
- Should see authorization consent form after admin login
|
||||
|
||||
2. **Verify token creation**:
|
||||
```sql
|
||||
SELECT COUNT(*) FROM tokens;
|
||||
SELECT COUNT(*) FROM authorization_codes;
|
||||
```
|
||||
|
||||
3. **Test with curl after getting token**:
|
||||
```bash
|
||||
curl -H "Authorization: Bearer {token}" \
|
||||
"http://localhost:5000/micropub?q=config"
|
||||
```
|
||||
|
||||
## Configuration Notes
|
||||
|
||||
From `.env` file:
|
||||
- Site URL: `http://localhost:5000`
|
||||
- Admin ME: `https://example.com`
|
||||
- Database: `./data/starpunk.db`
|
||||
- Dev Mode: enabled
|
||||
|
||||
## Summary
|
||||
|
||||
The 401 error is **expected behavior** when no access token is provided. The issue is not a bug in the code, but rather that:
|
||||
|
||||
1. Quill hasn't completed the IndieAuth flow to obtain a token
|
||||
2. The site doesn't advertise its IndieAuth endpoints for discovery
|
||||
|
||||
The implementation is architecturally sound and follows IndieAuth/Micropub specifications correctly. The user needs to:
|
||||
1. Complete the authorization flow through Quill
|
||||
2. Add endpoint discovery to the site
|
||||
|
||||
## Architectural Recommendations
|
||||
|
||||
1. **Add endpoint discovery** to enable automatic client configuration
|
||||
2. **Consider adding a token management UI** for the admin to see/revoke tokens
|
||||
3. **Add logging** for authentication failures to aid debugging
|
||||
4. **Document the IndieAuth flow** for users setting up Micropub clients
|
||||
|
||||
---
|
||||
|
||||
**Date**: 2024-11-24
|
||||
**Architect**: StarPunk Architecture Team
|
||||
**Status**: Diagnosis Complete
|
||||
Reference in New Issue
Block a user