fix(modpack-checker): Code review fixes — license, safety, and polish
Fixes 10 issues from full code review: - License corrected from MIT to Commercial - Deprecated datetime.utcnow() replaced with timezone-aware alternative - PHP array bounds checks added for all platform API responses - Modrinth file detection now derives project slug instead of using MC version - validate_api_key() no longer swallows network errors - HTTP timeouts added to all external API calls in PHP - Empty API key rejection added to CLI - Corrupted config now warns on stderr instead of failing silently - Error response format made consistent across controller - Docs updated with correct repo URL and clearer CurseForge ID instructions Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
c6d40dcf39
commit
3457b87aef
@@ -80,8 +80,12 @@ def config_group() -> None:
|
||||
@click.argument("api_key")
|
||||
def config_set_key(api_key: str) -> None:
|
||||
"""Save your CurseForge API key and validate it."""
|
||||
api_key = api_key.strip()
|
||||
if not api_key:
|
||||
console.print("[red]Error:[/red] API key cannot be empty.")
|
||||
sys.exit(1)
|
||||
cfg = Config.load()
|
||||
cfg.curseforge_api_key = api_key.strip()
|
||||
cfg.curseforge_api_key = api_key
|
||||
cfg.save()
|
||||
|
||||
client = CurseForgeClient(api_key)
|
||||
|
||||
@@ -31,7 +31,11 @@ class Config(BaseModel):
|
||||
data = json.load(f)
|
||||
return cls(**data)
|
||||
except (json.JSONDecodeError, ValueError):
|
||||
# Corrupted config — fall back to defaults silently
|
||||
import sys
|
||||
print(
|
||||
f"Warning: config file corrupted ({CONFIG_FILE}), using defaults.",
|
||||
file=sys.stderr,
|
||||
)
|
||||
return cls()
|
||||
return cls()
|
||||
|
||||
|
||||
@@ -130,7 +130,7 @@ class CurseForgeClient:
|
||||
try:
|
||||
self._get(f"/v1/games/{self._MINECRAFT_GAME_ID}")
|
||||
return True
|
||||
except (CurseForgeAuthError, CurseForgeError):
|
||||
except CurseForgeAuthError:
|
||||
return False
|
||||
|
||||
def get_mod(self, mod_id: int) -> Dict[str, Any]:
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
from datetime import datetime
|
||||
from datetime import datetime, timezone
|
||||
from pathlib import Path
|
||||
from typing import List, Optional
|
||||
|
||||
@@ -164,11 +164,11 @@ class Database:
|
||||
if row is None:
|
||||
raise ValueError(f"Modpack {curseforge_id} not found in database.")
|
||||
row.current_version = version
|
||||
row.last_checked = datetime.utcnow()
|
||||
row.last_checked = datetime.now(timezone.utc)
|
||||
session.add(
|
||||
_CheckHistoryRow(
|
||||
modpack_id=row.id,
|
||||
checked_at=datetime.utcnow(),
|
||||
checked_at=datetime.now(timezone.utc),
|
||||
version_found=version,
|
||||
notification_sent=notification_sent,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user