Digest polish: honest on-site wording, one-tap opt-in after sign-in, List-Unsubscribe
* On-site end-cap now says "You're caught up for now." — honest, since Highlights refreshes through the day (the email keeps the daily "see you tomorrow"). * Anonymous "Get tomorrow's brief by email" now honors the one-tap promise: sets a pending flag, opens sign-in, and auto-enables once auth resolves. * Email compliance (RFC 2369/8058): send_email takes optional headers; the digest sets List-Unsubscribe + List-Unsubscribe-Post=One-Click, and a POST /api/digest/unsubscribe handles native one-click (GET still serves the page). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
+14
-5
@@ -528,16 +528,25 @@ def create_app() -> FastAPI:
|
||||
conn.commit()
|
||||
return {"ok": True, "digest_enabled": body.enabled}
|
||||
|
||||
@app.get("/api/digest/unsubscribe", response_class=HTMLResponse)
|
||||
def digest_unsubscribe(u: int = Query(...), t: str = Query(...)) -> HTMLResponse:
|
||||
# One-click, no login: match the per-user token, then turn the digest off.
|
||||
ok = False
|
||||
def _do_unsubscribe(u: int, t: str) -> bool:
|
||||
with get_conn() as conn:
|
||||
row = conn.execute("SELECT digest_unsub_token FROM users WHERE id = ?", (u,)).fetchone()
|
||||
if row and row["digest_unsub_token"] and hmac.compare_digest(row["digest_unsub_token"], t):
|
||||
conn.execute("UPDATE users SET digest_enabled = 0 WHERE id = ?", (u,))
|
||||
conn.commit()
|
||||
ok = True
|
||||
return True
|
||||
return False
|
||||
|
||||
@app.post("/api/digest/unsubscribe")
|
||||
def digest_unsubscribe_oneclick(u: int = Query(...), t: str = Query(...)) -> dict:
|
||||
# RFC 8058 one-click: the mailbox provider POSTs here; just do it + 200.
|
||||
_do_unsubscribe(u, t)
|
||||
return {"ok": True}
|
||||
|
||||
@app.get("/api/digest/unsubscribe", response_class=HTMLResponse)
|
||||
def digest_unsubscribe(u: int = Query(...), t: str = Query(...)) -> HTMLResponse:
|
||||
# One-click, no login: match the per-user token, then turn the digest off.
|
||||
ok = _do_unsubscribe(u, t)
|
||||
msg = (
|
||||
"You’re unsubscribed from the daily digest. No hard feelings — "
|
||||
"Upbeat Bytes is always here when you want it."
|
||||
|
||||
Reference in New Issue
Block a user