"""Phase 5: Team invite acceptance route."""
from datetime import UTC
from flask import Blueprint, current_app, flash, g, redirect, render_template, request, session, url_for
from app.models import accept_invite, get_user
invite_bp = Blueprint("invites", __name__, url_prefix="/invite")
@invite_bp.route("/<token>", methods=["GET"])
def accept_invite_page(token):
"""Show invite acceptance page."""
# Look up the pending invite
from app.models import get_db, get_team, get_team_members
conn = None
try:
conn = get_db()
member = conn.execute(
"SELECT tm.*, t.name as team_name FROM team_members tm JOIN teams t ON t.id = tm.team_id WHERE tm.invite_token = ? AND tm.status = 'pending'",
(token,),
).fetchone()
finally:
if conn:
conn.close()
if not member:
flash("Invalid or expired invitation.", "error")
return redirect(url_for("auth.login"))
# Check token expiration before proceeding
expires_at = member.get("expires_at")
if expires_at:
from datetime import datetime, timezone
expiry = datetime.fromisoformat(expires_at)
if datetime.now(UTC) > expiry:
flash("This invitation has expired.", "error")
return redirect(url_for("auth.login"))
# If user is logged in, accept immediately
user_id = session.get("user_id")
if user_id:
# Check if the logged-in user matches the invite email
user = get_user(user_id)
if user and user["email"] == member["invited_email"]:
result = accept_invite(token, user_id)
if "error" in result:
flash(result["error"], "error")
return redirect(url_for("auth.dashboard"))
flash(f"Welcome to {member['team_name']}!", "success")
return redirect(url_for("teams.list_teams"))
else:
flash("This invite is for a different email address.", "error")
return redirect(url_for("auth.dashboard"))
# Show the invite page for non-logged-in users
return render_template(
"invites/accept.html", token=token, email=member["invited_email"], team_name=member["team_name"]
)
@invite_bp.route("/<token>/accept", methods=["POST"])
def accept_invite_action(token):
"""Accept an invite (for non-logged-in users who register first)."""
if session.get("user_id") is None:
flash("Please log in or create an account to accept this invitation.", "error")
return redirect(url_for("auth.register"))
result = accept_invite(token, session["user_id"])
if "error" in result:
flash(result["error"], "error")
return redirect(url_for("auth.dashboard"))
flash("You've joined the team!", "success")
return redirect(url_for("teams.list_teams"))