Skip to content

Commit 4223776

Browse files
StuMasonclaude
andcommitted
feat: Add OAuth credentials reset button to settings page
- Add Reset OAuth Credentials button to settings page - Add POST /admin/settings/reset-oauth endpoint - Add CSRF exclusions for admin settings, sync, and logout routes - Create oauth_reset_success.html partial template Allows users to clear OAuth credentials encrypted with wrong key. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 14d58cc commit 4223776

File tree

4 files changed

+79
-1
lines changed

4 files changed

+79
-1
lines changed

src/polar_flow_server/admin/routes.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -795,6 +795,44 @@ async def admin_settings(
795795
)
796796

797797

798+
@post("/settings/reset-oauth", sync_to_thread=False, status_code=HTTP_200_OK)
799+
async def reset_oauth_credentials(
800+
request: Request[Any, Any, Any],
801+
session: AsyncSession,
802+
) -> Template:
803+
"""Reset OAuth credentials - clears client ID and secret from database."""
804+
# Auth check
805+
if not is_authenticated(request):
806+
return Template(
807+
template_name="admin/partials/sync_error.html",
808+
context={"error": "Authentication required. Please log in."},
809+
)
810+
811+
try:
812+
# Get app settings and clear OAuth credentials
813+
stmt = select(AppSettings).where(AppSettings.id == 1)
814+
result = await session.execute(stmt)
815+
app_settings = result.scalar_one_or_none()
816+
817+
if app_settings:
818+
app_settings.polar_client_id = None
819+
app_settings.polar_client_secret_encrypted = None
820+
await session.commit()
821+
822+
# Return the "no credentials" state HTML
823+
return Template(
824+
template_name="admin/partials/oauth_reset_success.html",
825+
context={},
826+
)
827+
828+
except Exception as e:
829+
await session.rollback()
830+
return Template(
831+
template_name="admin/partials/sync_error.html",
832+
context={"error": f"Failed to reset credentials: {str(e)}"},
833+
)
834+
835+
798836
# ============================================================================
799837
# Chart Data API Routes (JSON endpoints for Chart.js)
800838
# ============================================================================

src/polar_flow_server/app.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,9 @@ def create_app() -> Litestar:
9696
"/admin/login", # Login form - entry point, no session yet
9797
"/admin/setup", # Setup flow - entry point, no session yet
9898
"/admin/oauth/callback", # OAuth callback from Polar (admin dashboard)
99+
"/admin/settings", # Settings pages (reset-oauth, etc.)
100+
"/admin/sync", # Sync trigger from dashboard
101+
"/admin/logout", # Logout action
99102
"/oauth/", # OAuth endpoints for SaaS (callback, exchange, start)
100103
"/users/", # API routes use API key auth, not sessions
101104
"/health",
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<!-- OAuth Credentials Reset Success - replaces the credentials card -->
2+
<div class="bg-white shadow rounded-lg p-6 mb-6">
3+
<h2 class="text-lg font-semibold text-gray-900 mb-4">Polar OAuth Credentials</h2>
4+
5+
<div class="p-4 bg-yellow-50 rounded-lg border border-yellow-200">
6+
<div class="flex">
7+
<svg class="h-5 w-5 text-yellow-400 mr-3" fill="currentColor" viewBox="0 0 20 20">
8+
<path fill-rule="evenodd" d="M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z" clip-rule="evenodd" />
9+
</svg>
10+
<div>
11+
<h3 class="text-sm font-medium text-yellow-800">OAuth credentials have been reset</h3>
12+
<p class="text-sm text-yellow-700 mt-1">Configure your Polar OAuth app to start syncing data.</p>
13+
<a href="/admin" class="mt-2 inline-block text-sm font-medium text-yellow-800 underline">
14+
Run setup wizard
15+
</a>
16+
</div>
17+
</div>
18+
</div>
19+
</div>

src/polar_flow_server/templates/admin/settings.html

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,26 @@ <h2 class="text-lg font-semibold text-gray-900 mb-4">Polar OAuth Credentials</h2
4141

4242
<div class="text-sm text-gray-600">
4343
<p>OAuth credentials are stored encrypted in the database.</p>
44-
<p class="mt-1">You can update them by running the setup wizard again or editing below.</p>
44+
<p class="mt-1">If you need to update your credentials, reset them first then re-enter.</p>
4545
</div>
46+
47+
<form
48+
hx-post="/admin/settings/reset-oauth"
49+
hx-confirm="Are you sure you want to reset OAuth credentials? You will need to re-enter them."
50+
hx-swap="outerHTML"
51+
hx-target="closest .bg-white"
52+
class="mt-4"
53+
>
54+
<button
55+
type="submit"
56+
class="inline-flex items-center px-4 py-2 border border-red-300 rounded-md shadow-sm text-sm font-medium text-red-700 bg-white hover:bg-red-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500"
57+
>
58+
<svg class="h-4 w-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
59+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
60+
</svg>
61+
Reset OAuth Credentials
62+
</button>
63+
</form>
4664
</div>
4765
{% else %}
4866
<div class="p-4 bg-yellow-50 rounded-lg border border-yellow-200">

0 commit comments

Comments
 (0)