"""Simple auth service with in-memory fallback when PocketBase users unavailable.""" import hashlib import secrets from typing import Any from app.data import mock_data # In-memory store for demo mode _users: dict[str, dict] = {} _sessions: dict[str, str] = {} # token -> user_id _favorites: dict[str, list[str]] = {} # user_id -> [slugs] def _hash_password(password: str) -> str: return hashlib.sha256(password.encode()).hexdigest() def register_user(email: str, password: str, name: str) -> dict[str, Any] | None: if email in _users: return None uid = secrets.token_hex(8) _users[email] = { "id": uid, "email": email, "password_hash": _hash_password(password), "name": name, "avatar": "🧑‍💻", } _favorites[uid] = [] token = secrets.token_urlsafe(32) _sessions[token] = uid return {"token": token, "user": _user_profile(_users[email])} def login_user(email: str, password: str) -> dict[str, Any] | None: user = _users.get(email) if not user or user["password_hash"] != _hash_password(password): return None token = secrets.token_urlsafe(32) _sessions[token] = user["id"] return {"token": token, "user": _user_profile(user)} def get_user_by_token(token: str) -> dict | None: uid = _sessions.get(token) if not uid: return None for user in _users.values(): if user["id"] == uid: return _user_profile(user) return None def get_favorites(token: str) -> list[str]: uid = _sessions.get(token) if not uid: return [] return _favorites.get(uid, []) def toggle_favorite(token: str, slug: str) -> list[str]: uid = _sessions.get(token) if not uid: return [] favs = _favorites.setdefault(uid, []) if slug in favs: favs.remove(slug) else: favs.append(slug) return favs def _user_profile(user: dict) -> dict: return { "id": user["id"], "email": user["email"], "name": user["name"], "avatar": user.get("avatar", "🧑‍💻"), } # Demo account _demo = register_user("demo@nomadflow.io", "demo123", "演示用户") DEMO_TOKEN = _demo["token"] if _demo else ""