Skip to content

Commit e1dfb74

Browse files
chore: add masked token in logs for debug purposes
1 parent 2531a8c commit e1dfb74

File tree

5 files changed

+33
-11
lines changed

5 files changed

+33
-11
lines changed

app/api/endpoints/catalogs.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from app.services.catalog_updater import refresh_catalogs_for_credentials
55
from app.services.recommendation_service import RecommendationService
66
from app.services.stremio_service import StremioService
7-
from app.utils import resolve_user_credentials
7+
from app.utils import redact_token, resolve_user_credentials
88

99
router = APIRouter()
1010

@@ -32,7 +32,7 @@ async def get_catalog(
3232
detail="Missing credentials token. Please open Watchly from a configured manifest URL.",
3333
)
3434

35-
logger.info(f"Fetching catalog for {type} with id {id}")
35+
logger.info(f"[{redact_token(token)}] Fetching catalog for {type} with id {id}")
3636

3737
credentials = await resolve_user_credentials(token)
3838

@@ -84,7 +84,7 @@ async def get_catalog(
8484
except HTTPException:
8585
raise
8686
except Exception as e:
87-
logger.error(f"Error fetching catalog for {type}/{id}: {e}", exc_info=True)
87+
logger.error(f"[{redact_token(token)}] Error fetching catalog for {type}/{id}: {e}", exc_info=True)
8888
raise HTTPException(status_code=500, detail=str(e))
8989

9090

@@ -96,7 +96,7 @@ async def update_catalogs(token: str):
9696
# Decode credentials from path
9797
credentials = await resolve_user_credentials(token)
9898

99-
logger.info("Updating catalogs in response to manual request")
99+
logger.info(f"[{redact_token(token)}] Updating catalogs in response to manual request")
100100
updated = await refresh_catalogs_for_credentials(credentials)
101101
logger.info(f"Manual catalog update completed: {updated}")
102102
return {"success": updated}

app/api/endpoints/tokens.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from app.services.catalog_updater import refresh_catalogs_for_credentials
99
from app.services.stremio_service import StremioService
1010
from app.services.token_store import token_store
11+
from app.utils import redact_token
1112

1213
router = APIRouter(prefix="/tokens", tags=["tokens"])
1314

@@ -106,6 +107,7 @@ async def create_token(payload: TokenRequest, request: Request) -> TokenResponse
106107

107108
try:
108109
token, created = await token_store.store_payload(payload_to_store)
110+
logger.info(f"[{redact_token(token)}] Token {'created' if created else 'updated'}")
109111
except RuntimeError as exc:
110112
logger.error("Token storage failed: {}", exc)
111113
raise HTTPException(
@@ -123,7 +125,7 @@ async def create_token(payload: TokenRequest, request: Request) -> TokenResponse
123125
try:
124126
await refresh_catalogs_for_credentials(payload_to_store, auth_key=verified_auth_key)
125127
except Exception as exc: # pragma: no cover - remote dependency
126-
logger.error("Initial catalog refresh failed: {}", exc, exc_info=True)
128+
logger.error(f"[{redact_token(token)}] Initial catalog refresh failed: {{}}", exc, exc_info=True)
127129
await token_store.delete_token(token)
128130
raise HTTPException(
129131
status_code=502,

app/core/config.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,13 @@ class Settings(BaseSettings):
1717
PORT: int = 8000
1818
ADDON_ID: str = "com.bimal.watchly"
1919
ADDON_NAME: str = "Watchly"
20-
APP_VERSION: str = "0.1.1"
21-
REDIS_URL: str = "redis://localhost:6379/0"
20+
APP_VERSION: str = "0.1.3"
21+
REDIS_URL: str = "redis://redis:6379/0"
2222
TOKEN_SALT: str = "change-me"
2323
TOKEN_TTL_SECONDS: int = 0 # 0 = never expire
2424
ANNOUNCEMENT_HTML: str = ""
2525
AUTO_UPDATE_CATALOGS: bool = True
26-
CATALOG_REFRESH_INTERVAL_SECONDS: int = 60 # 6 hours
26+
CATALOG_REFRESH_INTERVAL_SECONDS: int = 6 * 60 * 60 # 6 hours
2727
APP_ENV: Literal["development", "production"] = "development"
2828
HOST_NAME: str = "https://1ccea4301587-watchly.baby-beamup.club"
2929

app/services/catalog_updater.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from app.services.catalog import DynamicCatalogService
99
from app.services.stremio_service import StremioService
1010
from app.services.token_store import token_store
11+
from app.utils import redact_token
1112

1213
# Max number of concurrent updates to prevent overwhelming external APIs
1314
MAX_CONCURRENT_UPDATES = 5
@@ -26,9 +27,9 @@ async def refresh_catalogs_for_credentials(credentials: dict[str, Any], auth_key
2627

2728
catalogs = await dynamic_catalog_service.get_watched_loved_catalogs(library_items=library_items)
2829
catalogs += await dynamic_catalog_service.get_genre_based_catalogs(library_items=library_items)
29-
logger.info(
30-
f"Prepared {len(catalogs)} catalogs for {credentials.get('authKey') or credentials.get('username')}"
31-
)
30+
auth_key_or_username = credentials.get("authKey") or credentials.get("username")
31+
redacted = redact_token(auth_key_or_username) if auth_key_or_username else "unknown"
32+
logger.info(f"[{redacted}] Prepared {len(catalogs)} catalogs")
3233
auth_key = await stremio_service.get_auth_key()
3334
return await stremio_service.update_catalogs(catalogs, auth_key)
3435
finally:

app/utils.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,25 @@
55
from app.services.token_store import token_store
66

77

8+
def redact_token(token: str | None, visible_chars: int = 8) -> str:
9+
"""
10+
Redact a token for logging purposes.
11+
Shows first few characters followed by *** for debugging.
12+
13+
Args:
14+
token: The token to redact
15+
visible_chars: Number of characters to show before redaction (default: 8)
16+
17+
Returns:
18+
Redacted token string (e.g., "ksfjads***" or "None" if token is None)
19+
"""
20+
if not token:
21+
return "None"
22+
if len(token) <= visible_chars:
23+
return "***"
24+
return f"{token[:visible_chars]}***"
25+
26+
827
async def resolve_user_credentials(token: str) -> dict[str, Any]:
928
"""Resolve credentials from Redis token."""
1029
if not token:

0 commit comments

Comments
 (0)