feat: OAuth user fixes + dashboard UI improvements (v3.2.0)

- Bug A: Fix OAuth consent redirect loop (return_url path-relative)
- Bug B: Accept OAuth JWT tokens on /u/{user_id}/{alias}/mcp
- Bug C: Add user OAuth client CRUD (list/create/delete) + new page
- D-1: Sidebar border via Tailwind class, version footer in sidebar
- D-2: Remove broken setInterval targeting #stats-container
- D-3: 404.html purple primary colors + system dark mode support
- D-4: Fix invisible buttons (bg-gray-200 + text-white in light mode)
- D-5: Pin Alpine.js to 3.14.8, remove duplicate CSRF meta tag
- D-6: Fix invisible lang toggle button in settings (dark mode)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
airano
2026-02-25 23:27:59 +03:30
parent ea51c10e03
commit fdb050454e
17 changed files with 538 additions and 102 deletions

View File

@@ -76,6 +76,7 @@ class ClientRegistry:
grant_types: list[str] | None = None,
allowed_scopes: list[str] | None = None,
metadata: dict | None = None,
owner_user_id: str | None = None,
) -> tuple[str, str]:
"""
Create new OAuth client.
@@ -99,6 +100,7 @@ class ClientRegistry:
grant_types=grant_types or ["authorization_code", "refresh_token"],
allowed_scopes=allowed_scopes or ["read", "write"],
metadata=metadata or {},
owner_user_id=owner_user_id,
)
# Save

View File

@@ -27,6 +27,9 @@ class OAuthClient(BaseModel):
)
created_at: datetime = Field(default_factory=lambda: datetime.now(UTC))
metadata: dict = Field(default_factory=dict)
owner_user_id: str | None = Field(
default=None, description="ID of the OAuth user who created this client (None = admin)"
)
@field_validator("redirect_uris")
def validate_redirect_uris(cls, v):