Create subdomain passport endpoint
cgen-f10d72a058e248369ca94d2828e36932
This commit is contained in:
parent
5018f6eb75
commit
e25f2c1b22
1 changed files with 127 additions and 0 deletions
127
api/passport/subdomain/[username].ts
Normal file
127
api/passport/subdomain/[username].ts
Normal file
|
|
@ -0,0 +1,127 @@
|
||||||
|
import type { VercelRequest, VercelResponse } from "@vercel/node";
|
||||||
|
import { getAdminClient } from "../../_supabase";
|
||||||
|
|
||||||
|
export default async function handler(req: VercelRequest, res: VercelResponse) {
|
||||||
|
if (req.method !== "GET") {
|
||||||
|
return res.status(405).json({ error: "Method not allowed" });
|
||||||
|
}
|
||||||
|
|
||||||
|
const { username } = req.query;
|
||||||
|
|
||||||
|
if (!username || typeof username !== "string") {
|
||||||
|
return res.status(400).json({ error: "Username is required" });
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const admin = getAdminClient();
|
||||||
|
|
||||||
|
// Look up user by username
|
||||||
|
const { data: user, error: userError } = await admin
|
||||||
|
.from("user_profiles")
|
||||||
|
.select(
|
||||||
|
`
|
||||||
|
id,
|
||||||
|
username,
|
||||||
|
full_name,
|
||||||
|
email,
|
||||||
|
bio,
|
||||||
|
avatar_url,
|
||||||
|
banner_url,
|
||||||
|
location,
|
||||||
|
website_url,
|
||||||
|
github_url,
|
||||||
|
linkedin_url,
|
||||||
|
twitter_url,
|
||||||
|
role,
|
||||||
|
level,
|
||||||
|
total_xp,
|
||||||
|
user_type,
|
||||||
|
experience_level,
|
||||||
|
current_streak,
|
||||||
|
longest_streak,
|
||||||
|
created_at,
|
||||||
|
updated_at
|
||||||
|
`,
|
||||||
|
)
|
||||||
|
.eq("username", username)
|
||||||
|
.single();
|
||||||
|
|
||||||
|
if (userError) {
|
||||||
|
if (userError.code === "PGRST116") {
|
||||||
|
// No rows found
|
||||||
|
return res.status(404).json({ error: "User not found" });
|
||||||
|
}
|
||||||
|
throw userError;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!user) {
|
||||||
|
return res.status(404).json({ error: "User not found" });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get user's achievements
|
||||||
|
const { data: achievements = [] } = await admin
|
||||||
|
.from("user_achievements")
|
||||||
|
.select(
|
||||||
|
`
|
||||||
|
achievement_id,
|
||||||
|
achievements(
|
||||||
|
id,
|
||||||
|
name,
|
||||||
|
description,
|
||||||
|
icon,
|
||||||
|
category
|
||||||
|
)
|
||||||
|
`,
|
||||||
|
)
|
||||||
|
.eq("user_id", user.id);
|
||||||
|
|
||||||
|
// Get user's interests
|
||||||
|
const { data: userInterests = [] } = await admin
|
||||||
|
.from("user_interests")
|
||||||
|
.select(
|
||||||
|
`
|
||||||
|
interest_id,
|
||||||
|
interests(
|
||||||
|
id,
|
||||||
|
name,
|
||||||
|
category
|
||||||
|
)
|
||||||
|
`,
|
||||||
|
)
|
||||||
|
.eq("user_id", user.id);
|
||||||
|
|
||||||
|
// Get linked auth providers
|
||||||
|
const { data: linkedProviders = [] } = await admin
|
||||||
|
.from("user_auth_identities")
|
||||||
|
.select("provider, linked_at, last_sign_in_at")
|
||||||
|
.eq("user_id", user.id)
|
||||||
|
.not("deleted_at", "is", null);
|
||||||
|
|
||||||
|
return res.status(200).json({
|
||||||
|
type: "creator",
|
||||||
|
user: {
|
||||||
|
...user,
|
||||||
|
achievements: achievements
|
||||||
|
.map((a: any) => a.achievements)
|
||||||
|
.filter(Boolean),
|
||||||
|
interests: userInterests
|
||||||
|
.map((i: any) => i.interests)
|
||||||
|
.filter(Boolean),
|
||||||
|
linkedProviders,
|
||||||
|
},
|
||||||
|
domain: req.headers.host || "",
|
||||||
|
});
|
||||||
|
} catch (error: any) {
|
||||||
|
console.error("[Passport Subdomain Error]", error);
|
||||||
|
|
||||||
|
if (/SUPABASE_/.test(String(error?.message || ""))) {
|
||||||
|
return res.status(500).json({
|
||||||
|
error: `Server misconfigured: ${error.message}`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return res.status(500).json({
|
||||||
|
error: error?.message || "Failed to load passport",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue