feat: Implement IndieAuth token and authorization endpoints (Phase 2)
Following design in /docs/design/micropub-architecture.md and /docs/decisions/ADR-029-micropub-v1-implementation-phases.md Token Endpoint (/auth/token): - Exchange authorization codes for access tokens - Form-encoded POST requests per IndieAuth spec - PKCE support (code_verifier validation) - OAuth 2.0 error responses - Validates client_id, redirect_uri, me parameters - Returns Bearer tokens with scope Authorization Endpoint (/auth/authorization): - GET: Display consent form (requires admin login) - POST: Process approval/denial - PKCE support (code_challenge storage) - Scope validation and filtering - Integration with session management - Proper error handling and redirects All 33 Phase 2 tests pass (17 token + 16 authorization) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
81
templates/auth/authorize.html
Normal file
81
templates/auth/authorize.html
Normal file
@@ -0,0 +1,81 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Authorize Application - StarPunk{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="authorization-container">
|
||||
<h2>Authorization Request</h2>
|
||||
|
||||
<div class="authorization-info">
|
||||
<p class="auth-intro">
|
||||
An application is requesting access to your StarPunk site.
|
||||
</p>
|
||||
|
||||
<div class="client-info">
|
||||
<h3>Application Details</h3>
|
||||
<dl>
|
||||
<dt>Client:</dt>
|
||||
<dd><code>{{ client_id }}</code></dd>
|
||||
|
||||
<dt>Your Identity:</dt>
|
||||
<dd><code>{{ me }}</code></dd>
|
||||
|
||||
{% if scope %}
|
||||
<dt>Requested Permissions:</dt>
|
||||
<dd>
|
||||
<ul class="scope-list">
|
||||
{% for s in scope.split() %}
|
||||
<li><strong>{{ s }}</strong> - {% if s == 'create' %}Create new posts{% endif %}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</dd>
|
||||
{% else %}
|
||||
<dt>Requested Permissions:</dt>
|
||||
<dd><em>No permissions requested (read-only access)</em></dd>
|
||||
{% endif %}
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
<div class="authorization-warning">
|
||||
<p><strong>Warning:</strong> Only authorize applications you trust.</p>
|
||||
<p>This application will be able to perform the above actions on your behalf.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form action="{{ url_for('auth.authorization_endpoint') }}" method="POST" class="authorization-form">
|
||||
<!-- Pass through all parameters as hidden fields -->
|
||||
<input type="hidden" name="client_id" value="{{ client_id }}">
|
||||
<input type="hidden" name="redirect_uri" value="{{ redirect_uri }}">
|
||||
<input type="hidden" name="state" value="{{ state }}">
|
||||
<input type="hidden" name="scope" value="{{ scope }}">
|
||||
<input type="hidden" name="me" value="{{ me }}">
|
||||
<input type="hidden" name="response_type" value="{{ response_type }}">
|
||||
{% if code_challenge %}
|
||||
<input type="hidden" name="code_challenge" value="{{ code_challenge }}">
|
||||
<input type="hidden" name="code_challenge_method" value="{{ code_challenge_method }}">
|
||||
{% endif %}
|
||||
|
||||
<div class="authorization-actions">
|
||||
<button type="submit" name="approve" value="yes" class="button button-primary">
|
||||
Authorize
|
||||
</button>
|
||||
<button type="submit" name="approve" value="no" class="button button-secondary">
|
||||
Deny
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="authorization-help">
|
||||
<h3>What does this mean?</h3>
|
||||
<p>
|
||||
By clicking "Authorize", you allow this application to access your StarPunk site
|
||||
with the permissions listed above. You can revoke access at any time from your
|
||||
admin dashboard.
|
||||
</p>
|
||||
<p>
|
||||
If you don't recognize this application or didn't intend to authorize it,
|
||||
click "Deny" to reject the request.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user