68 lines
2 KiB
TypeScript
68 lines
2 KiB
TypeScript
|
|
import { createClient } from "@/lib/supabase/server";
|
||
|
|
import { NextResponse } from "next/server";
|
||
|
|
import { createClient as createAdminClient } from "@supabase/supabase-js";
|
||
|
|
|
||
|
|
export async function GET(request: Request) {
|
||
|
|
const { searchParams } = new URL(request.url);
|
||
|
|
const token = searchParams.get("token");
|
||
|
|
|
||
|
|
if (!token) {
|
||
|
|
return NextResponse.json({ error: "No token provided" }, { status: 400 });
|
||
|
|
}
|
||
|
|
|
||
|
|
const supabase = await createClient();
|
||
|
|
|
||
|
|
const supabaseAdmin = createAdminClient(
|
||
|
|
process.env.NEXT_PUBLIC_SUPABASE_URL!,
|
||
|
|
process.env.SUPABASE_SERVICE_ROLE_KEY!
|
||
|
|
);
|
||
|
|
|
||
|
|
// Validate the token
|
||
|
|
const { data: invite, error: inviteError } = await supabaseAdmin
|
||
|
|
.from("invitations")
|
||
|
|
.select("id, organization_id, status, expires_at, email")
|
||
|
|
.eq("token", token)
|
||
|
|
.single();
|
||
|
|
|
||
|
|
if (inviteError || !invite) {
|
||
|
|
return NextResponse.redirect(new URL("/?error=invalid_token", request.url));
|
||
|
|
}
|
||
|
|
|
||
|
|
if (invite.status !== "pending") {
|
||
|
|
return NextResponse.redirect(new URL("/?error=already_accepted", request.url));
|
||
|
|
}
|
||
|
|
|
||
|
|
if (new Date(invite.expires_at) < new Date()) {
|
||
|
|
return NextResponse.redirect(new URL("/?error=expired", request.url));
|
||
|
|
}
|
||
|
|
|
||
|
|
const { data: userData } = await supabase.auth.getUser();
|
||
|
|
|
||
|
|
if (!userData?.user) {
|
||
|
|
// Not logged in -> Store token in cookies and redirect to sign up
|
||
|
|
const response = NextResponse.redirect(new URL(`/auth/sign-up?email=${encodeURIComponent(invite.email)}`, request.url));
|
||
|
|
response.cookies.set("invite_token", token, {
|
||
|
|
maxAge: 60 * 60 * 24, // 1 day
|
||
|
|
path: "/",
|
||
|
|
httpOnly: true,
|
||
|
|
secure: process.env.NODE_ENV === "production",
|
||
|
|
sameSite: "lax",
|
||
|
|
});
|
||
|
|
return response;
|
||
|
|
}
|
||
|
|
|
||
|
|
const userId = userData.user.id;
|
||
|
|
|
||
|
|
await supabase
|
||
|
|
.from("profiles")
|
||
|
|
.update({ organization_id: invite.organization_id, role: "member" })
|
||
|
|
.eq("id", userId);
|
||
|
|
|
||
|
|
await supabaseAdmin
|
||
|
|
.from("invitations")
|
||
|
|
.update({ status: "accepted" })
|
||
|
|
.eq("id", invite.id);
|
||
|
|
|
||
|
|
return NextResponse.redirect(new URL("/dashboard", request.url));
|
||
|
|
}
|