fixed post token invalidation via mail/telegramm
This commit is contained in:
@@ -1613,6 +1613,12 @@ class DatabaseClient:
|
|||||||
lambda: self.client.table("email_action_tokens").update({"used": True}).eq("token", token).execute()
|
lambda: self.client.table("email_action_tokens").update({"used": True}).eq("token", token).execute()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
async def mark_all_post_tokens_used(self, post_id: UUID) -> None:
|
||||||
|
"""Mark all email action tokens for a post as used (invalidate approve + reject together)."""
|
||||||
|
await asyncio.to_thread(
|
||||||
|
lambda: self.client.table("email_action_tokens").update({"used": True}).eq("post_id", str(post_id)).execute()
|
||||||
|
)
|
||||||
|
|
||||||
async def cleanup_expired_email_tokens(self) -> None:
|
async def cleanup_expired_email_tokens(self) -> None:
|
||||||
"""Delete expired email tokens from the database."""
|
"""Delete expired email tokens from the database."""
|
||||||
now = datetime.now(timezone.utc).isoformat()
|
now = datetime.now(timezone.utc).isoformat()
|
||||||
|
|||||||
@@ -336,6 +336,13 @@ class TelegramService:
|
|||||||
|
|
||||||
async def _handle_callback_query(self, chat_id: str, cb_id: str, data: str, message_id: int, db) -> None:
|
async def _handle_callback_query(self, chat_id: str, cb_id: str, data: str, message_id: int, db) -> None:
|
||||||
"""Handle inline keyboard button presses."""
|
"""Handle inline keyboard button presses."""
|
||||||
|
# approve/reject callbacks are token-authenticated — no account lookup needed
|
||||||
|
if data.startswith("approve:") or data.startswith("reject:"):
|
||||||
|
action, token = data.split(":", 1)
|
||||||
|
await self._handle_approval_callback(chat_id, message_id, action, token, db)
|
||||||
|
return
|
||||||
|
|
||||||
|
# All other callbacks require a linked account
|
||||||
tg_account = await db.get_telegram_account_by_chat_id(chat_id)
|
tg_account = await db.get_telegram_account_by_chat_id(chat_id)
|
||||||
if not tg_account:
|
if not tg_account:
|
||||||
return
|
return
|
||||||
@@ -356,6 +363,49 @@ class TelegramService:
|
|||||||
await self._clear_conv(chat_id)
|
await self._clear_conv(chat_id)
|
||||||
await self.send_message(chat_id, "🔄 Alles klar! Schreib mir dein neues Thema.")
|
await self.send_message(chat_id, "🔄 Alles klar! Schreib mir dein neues Thema.")
|
||||||
|
|
||||||
|
async def _handle_approval_callback(
|
||||||
|
self, chat_id: str, message_id: int, action: str, token: str, db
|
||||||
|
) -> None:
|
||||||
|
"""Handle approve/reject callback from inline keyboard buttons."""
|
||||||
|
from src.services.email_service import validate_token
|
||||||
|
from uuid import UUID
|
||||||
|
|
||||||
|
token_data = await validate_token(token)
|
||||||
|
if not token_data:
|
||||||
|
await self.edit_message(
|
||||||
|
chat_id, message_id,
|
||||||
|
"❌ Dieser Link ist ungültig oder wurde bereits verwendet."
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
post_id = UUID(token_data["post_id"])
|
||||||
|
post = await db.get_generated_post(post_id)
|
||||||
|
if not post:
|
||||||
|
await self.edit_message(chat_id, message_id, "❌ Post nicht gefunden.")
|
||||||
|
return
|
||||||
|
|
||||||
|
if action == "approve":
|
||||||
|
new_status = "ready"
|
||||||
|
result_text = (
|
||||||
|
f"✅ <b>Post freigegeben!</b>\n\n"
|
||||||
|
f"<i>{post.topic_title or 'Post'}</i>\n\n"
|
||||||
|
f"Der Post kann jetzt eingeplant werden."
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
new_status = "draft"
|
||||||
|
result_text = (
|
||||||
|
f"❌ <b>Post abgelehnt.</b>\n\n"
|
||||||
|
f"<i>{post.topic_title or 'Post'}</i>\n\n"
|
||||||
|
f"Der Post wurde zurück in die Entwürfe verschoben."
|
||||||
|
)
|
||||||
|
|
||||||
|
await db.update_generated_post(post_id, {"status": new_status})
|
||||||
|
# Invalidate both approve + reject tokens for this post
|
||||||
|
await db.mark_all_post_tokens_used(post_id)
|
||||||
|
|
||||||
|
# Edit the original message to show the result (removes buttons)
|
||||||
|
await self.edit_message(chat_id, message_id, result_text)
|
||||||
|
|
||||||
async def _handle_post_type_selected(
|
async def _handle_post_type_selected(
|
||||||
self, chat_id: str, user_id: str, post_type_id_str: str, conv: dict, message_id: int, db
|
self, chat_id: str, user_id: str, post_type_id_str: str, conv: dict, message_id: int, db
|
||||||
) -> None:
|
) -> None:
|
||||||
|
|||||||
@@ -2328,13 +2328,12 @@ async def update_post_status(
|
|||||||
chat_id=telegram_account.telegram_chat_id,
|
chat_id=telegram_account.telegram_chat_id,
|
||||||
text=(
|
text=(
|
||||||
f"📋 <b>{company_name}</b> hat deinen Post bearbeitet und bittet um deine Freigabe:\n\n"
|
f"📋 <b>{company_name}</b> hat deinen Post bearbeitet und bittet um deine Freigabe:\n\n"
|
||||||
f"<i>{post.topic_title or 'Untitled Post'}</i>\n\n"
|
f"<i>{post.topic_title or 'Untitled Post'}</i>"
|
||||||
f"Bitte gib den Post frei oder lehne ihn ab:"
|
|
||||||
),
|
),
|
||||||
reply_markup={
|
reply_markup={
|
||||||
"inline_keyboard": [[
|
"inline_keyboard": [[
|
||||||
{"text": "✅ Freigeben", "url": approve_url},
|
{"text": "✅ Freigeben", "callback_data": f"approve:{approve_token}"},
|
||||||
{"text": "❌ Ablehnen", "url": reject_url}
|
{"text": "❌ Ablehnen", "callback_data": f"reject:{reject_token}"}
|
||||||
]]
|
]]
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -2453,8 +2452,8 @@ async def handle_email_action(request: Request, token: str):
|
|||||||
# Update post status
|
# Update post status
|
||||||
await db.update_generated_post(post_id, {"status": new_status})
|
await db.update_generated_post(post_id, {"status": new_status})
|
||||||
|
|
||||||
# Mark token as used
|
# Invalidate ALL tokens for this post (both approve + reject)
|
||||||
await mark_token_used(token)
|
await db.mark_all_post_tokens_used(post_id)
|
||||||
|
|
||||||
# Send notification to creator
|
# Send notification to creator
|
||||||
if profile and profile.creator_email:
|
if profile and profile.creator_email:
|
||||||
|
|||||||
Reference in New Issue
Block a user