diff --git a/.gitignore b/.gitignore index 5710f17..b73d7b9 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ __pycache__/ tokens.json config.json .active_tokens.json +*.before-* diff --git a/common.py b/common.py index 063bc66..5f5561f 100644 --- a/common.py +++ b/common.py @@ -193,7 +193,7 @@ async def oauth_token(request: Request): return JSONResponse({"error": "unsupported_grant_type"}, status_code=400) access_token = secrets.token_urlsafe(48) - expires_in = 86400 + expires_in = 2592000 # 30 days tokens = _load_access_tokens() # Cleanup expired now = time.time() diff --git a/mail/server.py b/mail/server.py index 4a7eee2..06c90d8 100644 --- a/mail/server.py +++ b/mail/server.py @@ -46,6 +46,21 @@ mcp = FastMCP("Mail", stateless_http=True, transport_security={"enable_dns_rebinding_protection": False}) +def _safe_decode(payload, charset): + """Decode bytes robust gegen unbekannte/kaputte Charsets (z.B. 'x-unknown').""" + if not isinstance(payload, bytes): + return str(payload) + for cs in (charset, "utf-8", "latin-1"): + if not cs: + continue + try: + return payload.decode(cs, errors="replace") + except (LookupError, TypeError): + continue + # Letzter Fallback: latin-1 akzeptiert jedes Byte + return payload.decode("latin-1", errors="replace") + + def _decode_hdr(raw): if not raw: return "" @@ -53,7 +68,7 @@ def _decode_hdr(raw): decoded = [] for data, charset in parts: if isinstance(data, bytes): - decoded.append(data.decode(charset or "utf-8", errors="replace")) + decoded.append(_safe_decode(data, charset)) else: decoded.append(str(data)) return " ".join(decoded) @@ -65,16 +80,16 @@ def _get_body(msg): if part.get_content_type() == "text/plain": payload = part.get_payload(decode=True) if payload: - return payload.decode(part.get_content_charset() or "utf-8", errors="replace") + return _safe_decode(payload, part.get_content_charset()) for part in msg.walk(): if part.get_content_type() == "text/html": payload = part.get_payload(decode=True) if payload: - return "[HTML] " + payload.decode(part.get_content_charset() or "utf-8", errors="replace") + return "[HTML] " + _safe_decode(payload, part.get_content_charset()) else: payload = msg.get_payload(decode=True) if payload: - return payload.decode(msg.get_content_charset() or "utf-8", errors="replace") + return _safe_decode(payload, msg.get_content_charset()) return ""