|
|
import { redirect } from "@sveltejs/kit"; |
|
|
const GET = async ({ url, cookies, fetch }) => { |
|
|
const code = url.searchParams.get("code"); |
|
|
const state = url.searchParams.get("state"); |
|
|
const error = url.searchParams.get("error"); |
|
|
const errorDescription = url.searchParams.get("error_description"); |
|
|
if (error) { |
|
|
console.error("OAuth error:", error, errorDescription); |
|
|
throw redirect(303, `/login?error=${encodeURIComponent(error)}`); |
|
|
} |
|
|
if (!code) { |
|
|
console.error("No authorization code received"); |
|
|
throw redirect(303, "/login?error=no_code"); |
|
|
} |
|
|
const savedState = cookies.get("oauth_state"); |
|
|
if (state !== savedState) { |
|
|
console.error("State mismatch - possible CSRF attack"); |
|
|
throw redirect(303, "/login?error=invalid_state"); |
|
|
} |
|
|
try { |
|
|
const tokenResponse = await fetch("https://huggingface.co/oauth/token", { |
|
|
method: "POST", |
|
|
headers: { |
|
|
"Content-Type": "application/json" |
|
|
}, |
|
|
body: JSON.stringify({ |
|
|
grant_type: "authorization_code", |
|
|
code, |
|
|
client_id: process.env.OAUTH_CLIENT_ID, |
|
|
client_secret: process.env.OAUTH_CLIENT_SECRET, |
|
|
redirect_uri: process.env.OAUTH_REDIRECT_URI || `${url.origin}/oauth/callback` |
|
|
}) |
|
|
}); |
|
|
if (!tokenResponse.ok) { |
|
|
const errorData = await tokenResponse.text(); |
|
|
console.error("Token exchange failed:", errorData); |
|
|
throw redirect(303, "/login?error=token_exchange_failed"); |
|
|
} |
|
|
const tokenData = await tokenResponse.json(); |
|
|
const accessToken = tokenData.access_token; |
|
|
const userResponse = await fetch("https://huggingface.co/api/whoami-v2", { |
|
|
headers: { |
|
|
Authorization: `Bearer ${accessToken}` |
|
|
} |
|
|
}); |
|
|
if (!userResponse.ok) { |
|
|
console.error("Failed to fetch user info"); |
|
|
throw redirect(303, "/login?error=user_fetch_failed"); |
|
|
} |
|
|
const userData = await userResponse.json(); |
|
|
cookies.set("access_token", accessToken, { |
|
|
path: "/", |
|
|
httpOnly: true, |
|
|
secure: process.env.NODE_ENV === "production", |
|
|
sameSite: "lax", |
|
|
maxAge: 60 * 60 * 24 * 30 |
|
|
|
|
|
}); |
|
|
cookies.set("user", JSON.stringify(userData), { |
|
|
path: "/", |
|
|
httpOnly: true, |
|
|
secure: process.env.NODE_ENV === "production", |
|
|
sameSite: "lax", |
|
|
maxAge: 60 * 60 * 24 * 30 |
|
|
|
|
|
}); |
|
|
cookies.delete("oauth_state", { path: "/" }); |
|
|
throw redirect(303, "/"); |
|
|
} catch (error2) { |
|
|
if (error2 instanceof Response) { |
|
|
throw error2; |
|
|
} |
|
|
console.error("Unexpected error during OAuth callback:", error2); |
|
|
throw redirect(303, "/login?error=unexpected_error"); |
|
|
} |
|
|
}; |
|
|
export { |
|
|
GET |
|
|
}; |
|
|
|