UNPKG

nuxt-supabase-team-auth

Version:

Drop-in Nuxt 3 module for team-based authentication with Supabase

102 lines (101 loc) 3.44 kB
import { defineEventHandler, readBody, createError, getCookie, deleteCookie, getHeader } from "h3"; import { jwtVerify } from "jose"; import { createSessionFromMagicLink } from "../utils/magicLinkSession.js"; import { serverSupabaseServiceRole } from "#supabase/server"; const createServiceRoleClient = serverSupabaseServiceRole; export default defineEventHandler(async (event) => { try { const authHeader = getHeader(event, "authorization"); if (!authHeader) { throw createError({ statusCode: 401, message: "Missing authorization header" }); } const token = authHeader.replace("Bearer ", ""); if (!token) { throw createError({ statusCode: 401, message: "Invalid authorization header format" }); } const adminClient = createServiceRoleClient(event); const { data: { user }, error: userError } = await adminClient.auth.getUser(token); if (userError || !user) { throw createError({ statusCode: 401, message: "Invalid or expired token" }); } const { sessionId } = await readBody(event); if (!sessionId) { throw createError({ statusCode: 400, message: "Session ID is required" }); } const { data: sessionData, error: sessionError } = await adminClient.from("impersonation_sessions").select("*").eq("id", sessionId).eq("target_user_id", user.id).is("ended_at", null).single(); if (sessionError || !sessionData) { throw createError({ statusCode: 404, message: "Active impersonation session not found" }); } const impersonationCookie = getCookie(event, "admin-impersonation"); if (!impersonationCookie) { throw createError({ statusCode: 400, message: "Admin impersonation cookie not found" }); } const jwtSecret = process.env.SUPABASE_JWT_SECRET; if (!jwtSecret) { throw createError({ statusCode: 500, message: "SUPABASE_JWT_SECRET environment variable is required for impersonation functionality" }); } let adminEmail; try { const { payload } = await jwtVerify(impersonationCookie, new TextEncoder().encode(jwtSecret)); adminEmail = payload.admin_email; if (!adminEmail) { throw new Error("Admin email not found in JWT"); } } catch (error) { console.error("Failed to verify impersonation JWT:", error); throw createError({ statusCode: 400, message: "Invalid impersonation session token" }); } const { error: updateError } = await adminClient.from("impersonation_sessions").update({ ended_at: (/* @__PURE__ */ new Date()).toISOString() }).eq("id", sessionId); if (updateError) { console.error("Failed to update impersonation session:", updateError); } deleteCookie(event, "admin-impersonation", { path: "/" }); const { session: adminSession } = await createSessionFromMagicLink( adminClient, adminEmail ); return { success: true, message: "Impersonation ended successfully", session: adminSession }; } catch (error) { console.error("Stop impersonation error:", error); const errorObj = error; if (errorObj.statusCode) { throw error; } throw createError({ statusCode: 500, message: errorObj.message || "Failed to stop impersonation" }); } });