added quick connect auth from jellyfin, still needs to have some more cleaning before push to prod #2
+38
-7
@@ -152,16 +152,47 @@ async def login_submit(request: Request):
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# GET /auth/status — check which services are linked
|
||||
# GET /auth/status — get all linked services for a Discord user
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
@router.get("/status")
|
||||
@router.get("/Discord/status")
|
||||
async def auth_status(discord_id: int):
|
||||
"""Return which services this Discord user has linked."""
|
||||
services: dict[str, bool] = {}
|
||||
for svc_name in list_auth_services():
|
||||
services[svc_name] = auth_store.is_authenticated(discord_id, svc_name)
|
||||
return {"discord_id": discord_id, "services": services}
|
||||
"""
|
||||
Return all services linked to this Discord user with full details.
|
||||
|
||||
Response:
|
||||
{
|
||||
"discord_id": 123456789,
|
||||
"linked_services": {
|
||||
"jellyfin": {
|
||||
"external_user_id": "abc123",
|
||||
"external_name": "Tim",
|
||||
"linked_at": "2026-05-25T10:00:00",
|
||||
"credentials": {
|
||||
"token": "jwt...",
|
||||
"url": "http://jellyfin:8096",
|
||||
"user_id": "abc123"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
auths = auth_store.get_all_auths(discord_id)
|
||||
|
||||
linked_services: dict[str, dict] = {}
|
||||
for auth in auths:
|
||||
svc_name = auth["service"]
|
||||
linked_services[svc_name] = {
|
||||
"external_user_id": auth["external_user_id"],
|
||||
"external_name": auth["external_name"],
|
||||
"linked_at": auth["linked_at"],
|
||||
"credentials": auth["credentials"],
|
||||
}
|
||||
|
||||
return {
|
||||
"discord_id": discord_id,
|
||||
"linked_services": linked_services,
|
||||
}
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
@@ -298,6 +298,48 @@ def revoke(discord_user_id: int, service: str) -> None:
|
||||
logger.info("Revoked auth for user %s on %s", discord_user_id, service)
|
||||
|
||||
|
||||
def get_all_auths(discord_user_id: int) -> list[dict]:
|
||||
"""
|
||||
Return all active auth records for a Discord user.
|
||||
Each record includes service name, external user id, external name,
|
||||
linked_at timestamp, and the raw credentials (e.g. Jellyfin token + URL).
|
||||
|
||||
Used by the /api/v1/auth/status endpoint so other services can discover
|
||||
linked accounts for a given Discord ID.
|
||||
"""
|
||||
_ensure_schema()
|
||||
import json
|
||||
|
||||
with _db_lock:
|
||||
conn = _get_conn()
|
||||
rows = conn.execute(
|
||||
"""SELECT service, external_user_id, external_name, credentials, linked_at
|
||||
FROM user_auth
|
||||
WHERE discord_user_id = ? AND is_active = 1
|
||||
ORDER BY linked_at DESC""",
|
||||
(discord_user_id,),
|
||||
).fetchall()
|
||||
conn.close()
|
||||
|
||||
results: list[dict] = []
|
||||
for row in rows:
|
||||
creds = {}
|
||||
if row["credentials"]:
|
||||
try:
|
||||
creds = json.loads(row["credentials"])
|
||||
except (json.JSONDecodeError, TypeError):
|
||||
creds = {}
|
||||
results.append({
|
||||
"service": row["service"],
|
||||
"external_user_id": row["external_user_id"] or "",
|
||||
"external_name": row["external_name"] or "",
|
||||
"linked_at": row["linked_at"] or "",
|
||||
"credentials": creds,
|
||||
})
|
||||
|
||||
return results
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Dev / testing — reset the entire store
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user