File size: 1,541 Bytes
f555806
 
 
 
 
 
 
 
 
 
 
 
8d67e1c
 
f555806
696b526
 
 
f555806
 
 
 
 
b65933f
f555806
 
 
8d67e1c
 
 
 
 
 
 
 
 
 
 
 
f555806
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import { randomUUID } from 'crypto';
import { NextRequest, NextResponse } from 'next/server';

const HF_AUTHORIZE_URL = 'https://huggingface.co/oauth/authorize';
const STATE_COOKIE = 'hf_oauth_state';

export async function GET(request: NextRequest) {
  const clientId = process.env.HF_OAUTH_CLIENT_ID || process.env.NEXT_PUBLIC_HF_OAUTH_CLIENT_ID;
  if (!clientId) {
    return NextResponse.json({ error: 'OAuth client ID not configured' }, { status: 500 });
  }

  const providedState = request.nextUrl.searchParams.get('state');
  const state = providedState || randomUUID();
  const origin = request.nextUrl.origin;
  const envRedirect =
    process.env.HF_OAUTH_REDIRECT_URI || process.env.NEXT_PUBLIC_HF_OAUTH_REDIRECT_URI || '';
  const redirectUri = envRedirect.trim() || `${origin}/auth/hf/callback`;

  const authorizeUrl = new URL(HF_AUTHORIZE_URL);
  authorizeUrl.searchParams.set('response_type', 'code');
  authorizeUrl.searchParams.set('client_id', clientId);
  authorizeUrl.searchParams.set('redirect_uri', redirectUri);
  authorizeUrl.searchParams.set('scope', 'openid profile read-repos write-repos manage-repos jobs');
  authorizeUrl.searchParams.set('state', state);

  const response = NextResponse.redirect(authorizeUrl.toString(), { status: 302 });

  if (!providedState) {
    response.cookies.set({
      name: STATE_COOKIE,
      value: state,
      httpOnly: true,
      sameSite: 'lax',
      secure: process.env.NODE_ENV === 'production',
      maxAge: 60 * 5,
      path: '/',
    });
  }

  return response;
}