Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 11 additions & 10 deletions backend/app/services/auth/verification.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import uuid
from datetime import datetime, timedelta
from datetime import datetime, timedelta, timezone
from typing import Optional, Dict, Tuple
from app.database.supabase.client import get_supabase_client
from app.models.database.supabase import User
Expand All @@ -16,7 +16,7 @@ def _cleanup_expired_sessions():
"""
Remove expired verification sessions.
"""
current_time = datetime.now()
current_time = datetime.now(timezone.utc)
expired_sessions = [
session_id for session_id, (discord_id, expiry_time) in _verification_sessions.items()
if current_time > expiry_time
Expand All @@ -36,17 +36,18 @@ async def create_verification_session(discord_id: str) -> Optional[str]:
"""
supabase = get_supabase_client()

await cleanup_expired_tokens()
_cleanup_expired_sessions()

token = str(uuid.uuid4())
session_id = str(uuid.uuid4())
expiry_time = datetime.now() + timedelta(minutes=SESSION_EXPIRY_MINUTES)
expiry_time = datetime.now(timezone.utc) + timedelta(minutes=SESSION_EXPIRY_MINUTES)

try:
update_res = await supabase.table("users").update({
"verification_token": token,
"verification_token_expires_at": expiry_time.isoformat(),
"updated_at": datetime.now().isoformat()
"updated_at": datetime.now(timezone.utc).isoformat()
}).eq("discord_id", discord_id).execute()

if update_res.data:
Expand Down Expand Up @@ -79,7 +80,7 @@ async def find_user_by_session_and_verify(

discord_id, expiry_time = session_data

current_time = datetime.now().isoformat()
current_time = datetime.now(timezone.utc).isoformat()
user_res = await supabase.table("users").select("*").eq(
"discord_id", discord_id
).neq(
Expand All @@ -106,7 +107,7 @@ async def find_user_by_session_and_verify(
await supabase.table("users").update({
"verification_token": None,
"verification_token_expires_at": None,
"updated_at": datetime.now().isoformat()
"updated_at": datetime.now(timezone.utc).isoformat()
}).eq("id", user_to_verify['id']).execute()
raise Exception(f"GitHub account {github_username} is already linked to another Discord user")

Expand All @@ -115,7 +116,7 @@ async def find_user_by_session_and_verify(
"github_username": github_username,
"email": user_to_verify.get('email') or email,
"is_verified": True,
"verified_at": datetime.now().isoformat(),
"verified_at": datetime.now(timezone.utc).isoformat(),
"verification_token": None,
"verification_token_expires_at": None,
"updated_at": datetime.now().isoformat()
Expand All @@ -139,7 +140,7 @@ async def cleanup_expired_tokens():
Clean up expired verification tokens from database.
"""
supabase = get_supabase_client()
current_time = datetime.now().isoformat()
current_time = datetime.now(timezone.utc).isoformat()

try:
cleanup_res = await supabase.table("users").update({
Expand All @@ -165,12 +166,12 @@ async def get_verification_session_info(session_id: str) -> Optional[Dict[str, s

discord_id, expiry_time = session_data

if datetime.now() > expiry_time:
if datetime.now(timezone.utc) > expiry_time:
del _verification_sessions[session_id]
return None

return {
"discord_id": discord_id,
"expiry_time": expiry_time.isoformat(),
"time_remaining": str(expiry_time - datetime.now())
"time_remaining": str(expiry_time - datetime.now(timezone.utc))
}
43 changes: 31 additions & 12 deletions backend/integrations/discord/cogs.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import discord
from discord import app_commands
from discord.ext import commands, tasks
from datetime import datetime, timezone

from app.agents.devrel.onboarding.messages import (
build_encourage_verification_message,
Expand Down Expand Up @@ -129,18 +130,36 @@ async def verify_github(self, interaction: discord.Interaction):
return

if user_profile.verification_token:
embed = discord.Embed(
title="⏳ Verification Pending",
description="You already have a verification in progress.",
color=discord.Color.orange()
)
embed.add_field(
name="What to do",
value="Please complete the existing verification or wait for it to expire (5 minutes).",
inline=False
)
await interaction.followup.send(embed=embed, ephemeral=True)
return
expires_at = user_profile.verification_token_expires_at
is_expired = False

if expires_at:
if isinstance(expires_at, str):
expires_at_dt = datetime.fromisoformat(expires_at)
else:
expires_at_dt = expires_at

if expires_at_dt.tzinfo is None:
expires_at_dt = expires_at_dt.replace(tzinfo=timezone.utc)

now_utc = datetime.now(timezone.utc)

if expires_at_dt < now_utc:
is_expired = True

if not is_expired:
embed = discord.Embed(
title="⏳ Verification Pending",
description="You already have a verification in progress.",
color=discord.Color.orange()
)
embed.add_field(
name="What to do",
value="Please complete the existing verification or wait for it to expire (5 minutes).",
inline=False
)
await interaction.followup.send(embed=embed, ephemeral=True)
return

session_id = await create_verification_session(str(interaction.user.id))
if not session_id:
Expand Down