From e100c4eff19e5fd57868bccbe5f8086bd93047b2 Mon Sep 17 00:00:00 2001 From: sirpiglr <49359077-sirpiglr@users.noreply.replit.com> Date: Sat, 13 Dec 2025 10:05:46 +0000 Subject: [PATCH] Update Discord verification flow to include expired code cleanup and bot notifications Add POST /api/discord/verify-callback webhook and implement expired verification code cleanup and bot notification logic within the /api/discord/verify-code endpoint. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 9203795e-937a-4306-b81d-b4d5c78c240e Replit-Commit-Checkpoint-Type: intermediate_checkpoint Replit-Commit-Event-Id: d6ce3cc9-6ce5-4141-b001-c604c9ee9c81 Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/7c94b7a0-29c7-4f2e-94ef-44b2153872b7/9203795e-937a-4306-b81d-b4d5c78c240e/v3HFq8K Replit-Helium-Checkpoint-Created: true --- client/pages/GetStarted.tsx | 2 +- server/index.ts | 78 +++++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+), 1 deletion(-) diff --git a/client/pages/GetStarted.tsx b/client/pages/GetStarted.tsx index ac3824b8..24477038 100644 --- a/client/pages/GetStarted.tsx +++ b/client/pages/GetStarted.tsx @@ -542,7 +542,7 @@ export default function GetStarted() { Explore the Ecosystem
Each realm is designed for different aspects of building and collaboration diff --git a/server/index.ts b/server/index.ts index 08fbcafd..8970dc06 100644 --- a/server/index.ts +++ b/server/index.ts @@ -1501,6 +1501,15 @@ export function createServer() { } try { + // Cleanup expired verification codes (opportunistic cleanup) + adminSupabase + .from("discord_verifications") + .delete() + .lt("expires_at", new Date().toISOString()) + .then(({ error }) => { + if (error) console.warn("[Discord Verify] Cleanup error:", error.message); + }); + // Find valid verification code const { data: verification, error: verifyError } = await adminSupabase .from("discord_verifications") @@ -1597,6 +1606,21 @@ export function createServer() { .delete() .eq("verification_code", verification_code.trim()); + // Notify bot about successful verification (fire and forget) + const botWebhookUrl = process.env.DISCORD_BOT_WEBHOOK_URL || "https://aethex-bot-master.replit.app/api/verify-success"; + fetch(botWebhookUrl, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + discord_id: discordId, + user_id: user_id, + success: true, + timestamp: new Date().toISOString(), + }), + }).catch((err) => { + console.warn("[Discord Verify] Failed to notify bot:", err.message); + }); + res.status(200).json({ success: true, message: "Discord account linked successfully!", @@ -1613,6 +1637,60 @@ export function createServer() { } }); + // Discord Verify Callback: Webhook for bot to receive verification confirmation + // Bot calls this after aethex.dev successfully links the Discord account + app.post("/api/discord/verify-callback", async (req, res) => { + const { discord_id, user_id, success, bot_secret } = req.body || {}; + + // Simple secret validation (bot sends shared secret) + const expectedSecret = process.env.DISCORD_BOT_WEBHOOK_SECRET || "aethex_bot_webhook_2025"; + if (bot_secret !== expectedSecret) { + console.warn("[Discord Callback] Invalid bot secret provided"); + return res.status(403).json({ error: "Invalid authorization" }); + } + + if (!discord_id) { + return res.status(400).json({ error: "Missing discord_id" }); + } + + console.log("[Discord Callback] Verification callback received:", { + discord_id, + user_id: user_id || "not provided", + success, + }); + + // This endpoint exists for the bot to know verification succeeded + // The bot can then assign the Verified role in Discord + res.status(200).json({ + received: true, + discord_id, + message: success ? "Verification confirmed" : "Verification status received", + }); + }); + + // Discord Cleanup: Remove expired verification codes (called periodically or on verify-code) + app.post("/api/discord/cleanup-expired-codes", async (req, res) => { + try { + const { deleted, error } = await adminSupabase + .from("discord_verifications") + .delete() + .lt("expires_at", new Date().toISOString()) + .select(); + + if (error) { + console.error("[Discord Cleanup] Error cleaning expired codes:", error); + return res.status(500).json({ error: error.message }); + } + + const count = deleted?.length || 0; + console.log(`[Discord Cleanup] Removed ${count} expired verification codes`); + res.status(200).json({ success: true, removed: count }); + } catch (error: any) { + console.error("[Discord Cleanup] Unexpected error:", error); + res.status(500).json({ error: error.message }); + } + }); + // Discord Role Mappings CRUD app.get("/api/discord/role-mappings", async (req, res) => { try {