Prettier format pending files

This commit is contained in:
Builder.io 2025-11-09 07:42:14 +00:00
parent 34f8661d1b
commit 7f4dc5c67b
8 changed files with 131 additions and 72 deletions

View file

@ -49,19 +49,22 @@ export default async function handler(req: any, res: any) {
const redirectUri = `${process.env.VITE_API_BASE || "https://aethex.dev"}/api/discord/oauth/callback`;
// Exchange code for access token
const tokenResponse = await fetch("https://discord.com/api/v10/oauth2/token", {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
const tokenResponse = await fetch(
"https://discord.com/api/v10/oauth2/token",
{
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
body: new URLSearchParams({
client_id: clientId,
client_secret: clientSecret,
grant_type: "authorization_code",
code,
redirect_uri: redirectUri,
}).toString(),
},
body: new URLSearchParams({
client_id: clientId,
client_secret: clientSecret,
grant_type: "authorization_code",
code,
redirect_uri: redirectUri,
}).toString(),
});
);
if (!tokenResponse.ok) {
const errorData = await tokenResponse.json();
@ -115,19 +118,23 @@ export default async function handler(req: any, res: any) {
} else {
// Create new user
// First create auth user
const { data: authData, error: authError } = await supabase.auth.admin.createUser({
email: discordUser.email,
email_confirm: true,
user_metadata: {
full_name: discordUser.username,
avatar_url: discordUser.avatar
? `https://cdn.discordapp.com/avatars/${discordUser.id}/${discordUser.avatar}.png`
: null,
},
});
const { data: authData, error: authError } =
await supabase.auth.admin.createUser({
email: discordUser.email,
email_confirm: true,
user_metadata: {
full_name: discordUser.username,
avatar_url: discordUser.avatar
? `https://cdn.discordapp.com/avatars/${discordUser.id}/${discordUser.avatar}.png`
: null,
},
});
if (authError || !authData.user) {
console.error("[Discord OAuth] Auth user creation failed:", authError);
console.error(
"[Discord OAuth] Auth user creation failed:",
authError,
);
return res.redirect("/login?error=auth_create");
}
@ -135,17 +142,22 @@ export default async function handler(req: any, res: any) {
isNewUser = true;
// Create user profile
const { error: profileError } = await supabase.from("user_profiles").insert({
id: userId,
email: discordUser.email,
full_name: discordUser.username,
avatar_url: discordUser.avatar
? `https://cdn.discordapp.com/avatars/${discordUser.id}/${discordUser.avatar}.png`
: null,
});
const { error: profileError } = await supabase
.from("user_profiles")
.insert({
id: userId,
email: discordUser.email,
full_name: discordUser.username,
avatar_url: discordUser.avatar
? `https://cdn.discordapp.com/avatars/${discordUser.id}/${discordUser.avatar}.png`
: null,
});
if (profileError) {
console.error("[Discord OAuth] Profile creation failed:", profileError);
console.error(
"[Discord OAuth] Profile creation failed:",
profileError,
);
return res.redirect("/login?error=profile_create");
}
}
@ -164,9 +176,10 @@ export default async function handler(req: any, res: any) {
}
// Generate session token
const { data: sessionData, error: sessionError } = await supabase.auth.admin.createSession({
user_id: userId,
});
const { data: sessionData, error: sessionError } =
await supabase.auth.admin.createSession({
user_id: userId,
});
if (sessionError || !sessionData.session) {
console.error("[Discord OAuth] Session creation failed:", sessionError);
@ -174,17 +187,25 @@ export default async function handler(req: any, res: any) {
}
// Redirect to next page with session
const nextPath = state && typeof state === "string" && state.startsWith("/") ? state : isNewUser ? "/onboarding" : "/dashboard";
const redirectUrl = new URL(nextPath, process.env.VITE_API_BASE || "https://aethex.dev");
const nextPath =
state && typeof state === "string" && state.startsWith("/")
? state
: isNewUser
? "/onboarding"
: "/dashboard";
const redirectUrl = new URL(
nextPath,
process.env.VITE_API_BASE || "https://aethex.dev",
);
// Set cookies for session (similar to how Supabase does it)
res.setHeader(
"Set-Cookie",
`sb-access-token=${sessionData.session.access_token}; Path=/; HttpOnly; Secure; SameSite=Lax`
`sb-access-token=${sessionData.session.access_token}; Path=/; HttpOnly; Secure; SameSite=Lax`,
);
res.setHeader(
"Set-Cookie",
`sb-refresh-token=${sessionData.session.refresh_token}; Path=/; HttpOnly; Secure; SameSite=Lax`
`sb-refresh-token=${sessionData.session.refresh_token}; Path=/; HttpOnly; Secure; SameSite=Lax`,
);
res.redirect(redirectUrl.toString());

View file

@ -13,10 +13,10 @@ export default function handler(req: any, res: any) {
}
const redirectUri = `${process.env.VITE_API_BASE || "https://aethex.dev"}/api/discord/oauth/callback`;
// Get the next URL from query params (where to redirect after login)
const next = req.query.state || "/dashboard";
const params = new URLSearchParams({
client_id: clientId,
redirect_uri: redirectUri,

View file

@ -12,7 +12,9 @@ export default async function handler(req: any, res: any) {
const { verification_code, user_id } = req.body;
if (!verification_code || !user_id) {
return res.status(400).json({ message: "Missing verification code or user ID" });
return res
.status(400)
.json({ message: "Missing verification code or user ID" });
}
const supabaseUrl = process.env.VITE_SUPABASE_URL;
@ -35,7 +37,8 @@ export default async function handler(req: any, res: any) {
if (verifyError || !verification) {
return res.status(400).json({
message: "Invalid or expired verification code. Please try /verify again.",
message:
"Invalid or expired verification code. Please try /verify again.",
});
}
@ -50,7 +53,8 @@ export default async function handler(req: any, res: any) {
if (existingLink && existingLink.user_id !== user_id) {
return res.status(400).json({
message: "This Discord account is already linked to another AeThex account.",
message:
"This Discord account is already linked to another AeThex account.",
});
}
@ -63,7 +67,9 @@ export default async function handler(req: any, res: any) {
if (linkError) {
console.error("[Discord Verify] Link creation failed:", linkError);
return res.status(500).json({ message: "Failed to link Discord account" });
return res
.status(500)
.json({ message: "Failed to link Discord account" });
}
// Delete used verification code

View file

@ -166,7 +166,6 @@ export default function ArmSwitcher() {
onClose={() => setIsModalOpen(false)}
/>
</div>
</>
);
}

View file

@ -94,7 +94,8 @@ const ARM_DESCRIPTIONS: Record<string, string> = {
gameforge:
"Game Development - Shipping games at the speed of thought with monthly cycles",
corp: "Enterprise Solutions - Consulting for large-scale transformations",
foundation: "Community & Education - Building open-source and talent pipelines",
foundation:
"Community & Education - Building open-source and talent pipelines",
devlink:
"Professional Networking - LinkedIn for Roblox developers and creators",
nexus: "Talent Marketplace - Cross-arm collaboration and opportunities",
@ -128,7 +129,9 @@ export default function ArmSwitcherModal({
onClose();
};
const selectedArmData = selectedArm ? ARMS.find((a) => a.id === selectedArm) : null;
const selectedArmData = selectedArm
? ARMS.find((a) => a.id === selectedArm)
: null;
if (!isOpen) return null;
@ -179,7 +182,9 @@ export default function ArmSwitcherModal({
{ARM_DESCRIPTIONS[arm.id]}
</p>
</div>
<div className={`w-2 h-2 rounded-full mt-1 ${arm.textColor}`} />
<div
className={`w-2 h-2 rounded-full mt-1 ${arm.textColor}`}
/>
</div>
</button>
))}
@ -213,13 +218,17 @@ export default function ArmSwitcherModal({
</div>
{/* Features */}
<div className={`p-4 rounded-lg ${selectedArmData.bgColor} border border-gray-700`}>
<div
className={`p-4 rounded-lg ${selectedArmData.bgColor} border border-gray-700`}
>
<h3 className="text-sm font-semibold text-gray-200 mb-3">
What you'll get:
</h3>
<ul className="space-y-2">
<li className="flex items-start gap-2">
<span className={`text-lg mt-0.5 ${selectedArmData.textColor}`}>
<span
className={`text-lg mt-0.5 ${selectedArmData.textColor}`}
>
</span>
<span className="text-sm text-gray-300">
@ -227,7 +236,9 @@ export default function ArmSwitcherModal({
</span>
</li>
<li className="flex items-start gap-2">
<span className={`text-lg mt-0.5 ${selectedArmData.textColor}`}>
<span
className={`text-lg mt-0.5 ${selectedArmData.textColor}`}
>
🚀
</span>
<span className="text-sm text-gray-300">
@ -235,7 +246,9 @@ export default function ArmSwitcherModal({
</span>
</li>
<li className="flex items-start gap-2">
<span className={`text-lg mt-0.5 ${selectedArmData.textColor}`}>
<span
className={`text-lg mt-0.5 ${selectedArmData.textColor}`}
>
🎯
</span>
<span className="text-sm text-gray-300">

View file

@ -1,5 +1,10 @@
import { useState, useEffect } from "react";
import { AlertCircle, CheckCircle, AlertTriangle, RefreshCw } from "lucide-react";
import {
AlertCircle,
CheckCircle,
AlertTriangle,
RefreshCw,
} from "lucide-react";
interface DiagnosticData {
timestamp: string;
@ -46,7 +51,7 @@ export default function AdminDiscordDiagnostic() {
setDiagnostic(data);
} catch (err) {
setError(
err instanceof Error ? err.message : "Failed to fetch diagnostic"
err instanceof Error ? err.message : "Failed to fetch diagnostic",
);
} finally {
setLoading(false);
@ -60,7 +65,9 @@ export default function AdminDiscordDiagnostic() {
return (
<div className="space-y-6">
<div className="flex items-center justify-between">
<h3 className="text-lg font-bold text-white">Discord Configuration Diagnostic</h3>
<h3 className="text-lg font-bold text-white">
Discord Configuration Diagnostic
</h3>
<button
onClick={fetchDiagnostic}
disabled={loading}

View file

@ -77,7 +77,9 @@ export default function DiscordVerify() {
}, 3000);
} catch (err) {
setError(
err instanceof Error ? err.message : "An error occurred. Please try again."
err instanceof Error
? err.message
: "An error occurred. Please try again.",
);
setIsLoading(false);
}
@ -129,7 +131,8 @@ export default function DiscordVerify() {
Discord User
</p>
<p className="text-sm text-muted-foreground">
{discordUser.username}#{discordUser.discriminator || "0000"}
{discordUser.username}#
{discordUser.discriminator || "0000"}
</p>
</div>
@ -153,8 +156,15 @@ export default function DiscordVerify() {
</p>
<ol className="text-sm text-muted-foreground space-y-1 list-decimal list-inside">
<li>Open Discord</li>
<li>Go to any server where the AeThex bot is installed</li>
<li>Type <code className="bg-background/50 px-2 py-1 rounded">/verify</code></li>
<li>
Go to any server where the AeThex bot is installed
</li>
<li>
Type{" "}
<code className="bg-background/50 px-2 py-1 rounded">
/verify
</code>
</li>
<li>Copy the 6-digit code from the bot's response</li>
</ol>
</div>
@ -213,8 +223,8 @@ export default function DiscordVerify() {
{/* Info Box */}
<div className="mt-6 p-4 rounded-lg bg-secondary/20 border border-border/50">
<p className="text-xs text-muted-foreground">
💡 <strong>Tip:</strong> You can also sign in directly with Discord
on the login page if you're creating a new account.
💡 <strong>Tip:</strong> You can also sign in directly with
Discord on the login page if you're creating a new account.
</p>
</div>
</div>

View file

@ -1500,21 +1500,21 @@ export function createServer() {
// Add recommendations based on validation
if (!botToken) {
diagnostics.recommendations.push(
"❌ DISCORD_BOT_TOKEN not set. Set it in environment variables."
"❌ DISCORD_BOT_TOKEN not set. Set it in environment variables.",
);
} else if ((botToken?.length || 0) < 20) {
diagnostics.recommendations.push(
`❌ DISCORD_BOT_TOKEN appears invalid (length: ${botToken?.length}). Should be 60+ characters.`
`❌ DISCORD_BOT_TOKEN appears invalid (length: ${botToken?.length}). Should be 60+ characters.`,
);
} else {
diagnostics.recommendations.push(
"✅ DISCORD_BOT_TOKEN format looks valid"
"✅ DISCORD_BOT_TOKEN format looks valid",
);
}
if (!clientId) {
diagnostics.recommendations.push(
"❌ DISCORD_CLIENT_ID not set. Set it to your application's ID."
"❌ DISCORD_CLIENT_ID not set. Set it to your application's ID.",
);
} else {
diagnostics.recommendations.push("✅ DISCORD_CLIENT_ID is set");
@ -1522,7 +1522,7 @@ export function createServer() {
if (!publicKey) {
diagnostics.recommendations.push(
"❌ DISCORD_PUBLIC_KEY not set. Needed for signature verification."
"❌ DISCORD_PUBLIC_KEY not set. Needed for signature verification.",
);
} else {
diagnostics.recommendations.push("✅ DISCORD_PUBLIC_KEY is set");
@ -1537,22 +1537,25 @@ export function createServer() {
headers: {
Authorization: `Bot ${botToken}`,
},
}
},
);
diagnostics.testRequest = {
...diagnostics.testRequest,
status: testResponse.status === 200 ? "✅ Success" : `❌ Failed (${testResponse.status})`,
status:
testResponse.status === 200
? "✅ Success"
: `❌ Failed (${testResponse.status})`,
responseCode: testResponse.status,
};
if (testResponse.status === 401) {
diagnostics.recommendations.push(
"❌ Token authentication failed (401). The token may be invalid or revoked."
"❌ Token authentication failed (401). The token may be invalid or revoked.",
);
} else if (testResponse.status === 200) {
diagnostics.recommendations.push(
"✅ Token authentication successful with Discord API!"
"✅ Token authentication successful with Discord API!",
);
}
} catch (error) {