|
import { redirect } from "@remix-run/node"; |
|
import type { LoaderFunctionArgs } from "@remix-run/node"; |
|
import { huggingFaceOAuth } from "~/lib/huggingface-oauth.server"; |
|
import { generateRandomString, createCodeChallenge } from "~/lib/oauth-utils.server"; |
|
import { getUserSession } from "~/lib/session.server"; |
|
|
|
export async function loader({ request }: LoaderFunctionArgs) { |
|
console.log('π₯ HuggingFace OAuth login route hit'); |
|
|
|
|
|
if (!huggingFaceOAuth.isConfigured()) { |
|
console.error('β HuggingFace OAuth not configured'); |
|
return redirect('/?error=hf_oauth_not_configured'); |
|
} |
|
|
|
const url = new URL(request.url); |
|
const returnTo = url.searchParams.get('returnTo') || '/'; |
|
|
|
|
|
const userSession = await getUserSession(request); |
|
if (userSession?.huggingface) { |
|
console.log('βΉοΈ User already has HuggingFace auth in session'); |
|
|
|
|
|
if (returnTo.includes('link=true')) { |
|
console.log('π Re-authenticating for account linking purposes'); |
|
} else { |
|
|
|
console.log('β
Already authenticated with HuggingFace, redirecting'); |
|
return redirect(returnTo); |
|
} |
|
} |
|
|
|
|
|
const state = generateRandomString(32); |
|
const codeVerifier = generateRandomString(128); |
|
const codeChallenge = await createCodeChallenge(codeVerifier); |
|
|
|
|
|
const authUrl = huggingFaceOAuth.getAuthorizationUrl(state, codeChallenge); |
|
|
|
console.log('π Redirecting to HuggingFace OAuth authorization URL'); |
|
|
|
|
|
const response = redirect(authUrl); |
|
|
|
|
|
const cookieOptions = 'Path=/; HttpOnly; SameSite=Lax; Max-Age=600'; |
|
|
|
response.headers.append('Set-Cookie', `hf_oauth_state=${state}; ${cookieOptions}`); |
|
response.headers.append('Set-Cookie', `hf_oauth_code_verifier=${codeVerifier}; ${cookieOptions}`); |
|
response.headers.append('Set-Cookie', `hf_oauth_return_to=${encodeURIComponent(returnTo)}; ${cookieOptions}`); |
|
|
|
console.log('β
HuggingFace OAuth cookies set'); |
|
|
|
return response; |
|
} |