Create token exchange endpoint for Foundation OAuth
cgen-8034b9e955d547db9961099058064abf
This commit is contained in:
parent
4513e5cdee
commit
9227230658
1 changed files with 75 additions and 0 deletions
75
api/auth/exchange-token.ts
Normal file
75
api/auth/exchange-token.ts
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
/**
|
||||
* Token Exchange Endpoint
|
||||
*
|
||||
* Frontend calls this endpoint after receiving the authorization code from Foundation.
|
||||
* It stores the Foundation's access token and returns user information.
|
||||
*/
|
||||
|
||||
import { VercelRequest, VercelResponse } from "@vercel/node";
|
||||
|
||||
const FOUNDATION_URL = process.env.VITE_FOUNDATION_URL || "https://aethex.foundation";
|
||||
const API_BASE = process.env.VITE_API_BASE || "https://aethex.dev";
|
||||
|
||||
export default async function handler(
|
||||
req: VercelRequest,
|
||||
res: VercelResponse,
|
||||
) {
|
||||
if (req.method !== "POST") {
|
||||
return res.status(405).json({ error: "Method not allowed" });
|
||||
}
|
||||
|
||||
const { code } = req.body;
|
||||
|
||||
if (!code) {
|
||||
return res.status(400).json({ error: "Authorization code is required" });
|
||||
}
|
||||
|
||||
try {
|
||||
// Exchange code for token with Foundation
|
||||
const tokenResponse = await fetch(`${FOUNDATION_URL}/api/oauth/token`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
grant_type: "authorization_code",
|
||||
code,
|
||||
client_id: "aethex-corp",
|
||||
client_secret: process.env.FOUNDATION_OAUTH_CLIENT_SECRET,
|
||||
redirect_uri: `${API_BASE}/api/auth/foundation-callback`,
|
||||
}),
|
||||
});
|
||||
|
||||
if (!tokenResponse.ok) {
|
||||
const errorData = await tokenResponse.json().catch(() => ({}));
|
||||
console.error("[Exchange Token] Token exchange failed:", errorData);
|
||||
return res.status(400).json({
|
||||
error: "Failed to exchange code for token",
|
||||
details: errorData,
|
||||
});
|
||||
}
|
||||
|
||||
const tokenData = await tokenResponse.json();
|
||||
|
||||
if (!tokenData.access_token) {
|
||||
return res.status(400).json({ error: "No access token in response" });
|
||||
}
|
||||
|
||||
// Set cookie with access token
|
||||
res.setHeader("Set-Cookie", [
|
||||
`foundation_access_token=${tokenData.access_token}; Path=/; HttpOnly; Secure; SameSite=Strict`,
|
||||
`auth_user_id=${tokenData.user?.id || ""}; Path=/; Secure; SameSite=Strict`,
|
||||
]);
|
||||
|
||||
return res.status(200).json({
|
||||
accessToken: tokenData.access_token,
|
||||
user: tokenData.user,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("[Exchange Token] Error:", error);
|
||||
return res.status(500).json({
|
||||
error: "Failed to exchange token",
|
||||
details: String(error),
|
||||
});
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue