Create Discord Activity authentication proxy endpoint
cgen-fa375e4d704c498cbe54c17159ae566a
This commit is contained in:
parent
4fe52683e0
commit
d82db32505
1 changed files with 127 additions and 0 deletions
127
api/discord/activity-auth.ts
Normal file
127
api/discord/activity-auth.ts
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
import type { VercelRequest, VercelResponse } from "@vercel/node";
|
||||
import { createClient } from "@supabase/supabase-js";
|
||||
|
||||
const supabase = createClient(
|
||||
process.env.SUPABASE_URL || "",
|
||||
process.env.SUPABASE_SERVICE_ROLE || ""
|
||||
);
|
||||
|
||||
interface ActivityAuthRequest {
|
||||
access_token: string;
|
||||
}
|
||||
|
||||
interface UserData {
|
||||
id: string;
|
||||
discord_id: string;
|
||||
full_name: string | null;
|
||||
username: string | null;
|
||||
avatar_url: string | null;
|
||||
bio: string | null;
|
||||
user_type: string | null;
|
||||
primary_arm: string | null;
|
||||
}
|
||||
|
||||
export default async function handler(
|
||||
req: VercelRequest,
|
||||
res: VercelResponse
|
||||
) {
|
||||
if (req.method !== "POST") {
|
||||
res.setHeader("Allow", "POST");
|
||||
return res.status(405).json({ error: "Method not allowed" });
|
||||
}
|
||||
|
||||
try {
|
||||
const { access_token } = req.body as ActivityAuthRequest;
|
||||
|
||||
if (!access_token) {
|
||||
return res.status(400).json({ error: "access_token is required" });
|
||||
}
|
||||
|
||||
// Verify the access token with Discord API
|
||||
const discordResponse = await fetch("https://discord.com/api/v10/users/@me", {
|
||||
headers: {
|
||||
Authorization: `Bearer ${access_token}`,
|
||||
},
|
||||
});
|
||||
|
||||
if (!discordResponse.ok) {
|
||||
if (discordResponse.status === 401) {
|
||||
return res.status(401).json({ error: "Invalid or expired access token" });
|
||||
}
|
||||
throw new Error(`Discord API error: ${discordResponse.statusText}`);
|
||||
}
|
||||
|
||||
const discordUser = await discordResponse.json();
|
||||
const discord_id = discordUser.id;
|
||||
const discord_username = discordUser.username;
|
||||
|
||||
// Find or create user in Supabase
|
||||
const { data: existingUser, error: fetchError } = await supabase
|
||||
.from("user_profiles")
|
||||
.select("*")
|
||||
.eq("discord_id", discord_id)
|
||||
.maybeSingle();
|
||||
|
||||
if (fetchError && fetchError.code !== "PGRST116") {
|
||||
console.error("Supabase error:", fetchError);
|
||||
return res.status(500).json({ error: "Database error" });
|
||||
}
|
||||
|
||||
if (existingUser) {
|
||||
// User already exists, return their data
|
||||
return res.status(200).json({
|
||||
success: true,
|
||||
user: {
|
||||
id: existingUser.id,
|
||||
discord_id: existingUser.discord_id,
|
||||
full_name: existingUser.full_name,
|
||||
username: existingUser.username,
|
||||
avatar_url: existingUser.avatar_url,
|
||||
bio: existingUser.bio,
|
||||
user_type: existingUser.user_type,
|
||||
primary_arm: existingUser.primary_arm,
|
||||
} as UserData,
|
||||
});
|
||||
}
|
||||
|
||||
// Create new user if they don't exist
|
||||
const { data: newUser, error: createError } = await supabase
|
||||
.from("user_profiles")
|
||||
.insert({
|
||||
discord_id,
|
||||
username: discord_username,
|
||||
full_name: discordUser.global_name || discord_username,
|
||||
avatar_url: discordUser.avatar
|
||||
? `https://cdn.discordapp.com/avatars/${discord_id}/${discordUser.avatar}.png`
|
||||
: null,
|
||||
user_type: "community_member",
|
||||
primary_arm: "labs",
|
||||
})
|
||||
.select()
|
||||
.single();
|
||||
|
||||
if (createError) {
|
||||
console.error("Error creating user:", createError);
|
||||
return res.status(500).json({ error: "Failed to create user" });
|
||||
}
|
||||
|
||||
return res.status(200).json({
|
||||
success: true,
|
||||
user: {
|
||||
id: newUser.id,
|
||||
discord_id: newUser.discord_id,
|
||||
full_name: newUser.full_name,
|
||||
username: newUser.username,
|
||||
avatar_url: newUser.avatar_url,
|
||||
bio: newUser.bio,
|
||||
user_type: newUser.user_type,
|
||||
primary_arm: newUser.primary_arm,
|
||||
} as UserData,
|
||||
});
|
||||
} catch (error: any) {
|
||||
console.error("Activity auth error:", error);
|
||||
return res.status(500).json({
|
||||
error: error?.message || "Failed to authenticate activity",
|
||||
});
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue