Spaces:
Runtime error
Runtime error
hf sign in
Browse files- app/api/auth/route.ts +28 -0
- app/api/login/route.ts +2 -5
- app/login/callback/page.tsx +41 -1
- components/main/index.tsx +3 -9
- utils/useUser.ts +13 -0
app/api/auth/route.ts
ADDED
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
export async function POST(req: Request) {
|
2 |
+
const REDIRECT_URI = `https://${process.env.SPACE_HOST}`
|
3 |
+
const { code } = await req.json()
|
4 |
+
|
5 |
+
const request = await fetch('https://huggingface.co/oauth/token', {
|
6 |
+
method: 'POST',
|
7 |
+
headers: {
|
8 |
+
'Content-Type': 'application/x-www-form-urlencoded'
|
9 |
+
},
|
10 |
+
body: JSON.stringify({
|
11 |
+
client_id: process.env.OAUTH_CLIENT_ID,
|
12 |
+
code,
|
13 |
+
grand_type: 'authorization_code',
|
14 |
+
redirect_uri: REDIRECT_URI,
|
15 |
+
}),
|
16 |
+
})
|
17 |
+
|
18 |
+
const response = await request.clone().json().catch(() => ({}));
|
19 |
+
console.log(response)
|
20 |
+
|
21 |
+
return Response.json(
|
22 |
+
{
|
23 |
+
response,
|
24 |
+
status: 200,
|
25 |
+
ok: true
|
26 |
+
}
|
27 |
+
)
|
28 |
+
}
|
app/api/login/route.ts
CHANGED
@@ -1,11 +1,8 @@
|
|
1 |
-
export async function GET(
|
2 |
-
console.log(process.env)
|
3 |
-
|
4 |
const REDIRECT_URI = `https://${process.env.SPACE_HOST}/login/callback`
|
5 |
-
|
6 |
return Response.json(
|
7 |
{
|
8 |
-
redirect: `https://huggingface.co/oauth/authorize?redirect_uri=${REDIRECT_URI}&scope=openid%20profile&
|
9 |
status: 200,
|
10 |
ok: true
|
11 |
}
|
|
|
1 |
+
export async function GET() {
|
|
|
|
|
2 |
const REDIRECT_URI = `https://${process.env.SPACE_HOST}/login/callback`
|
|
|
3 |
return Response.json(
|
4 |
{
|
5 |
+
redirect: `https://huggingface.co/oauth/authorize?client_id=${process.env.OAUTH_CLIENT_ID}&redirect_uri=${REDIRECT_URI}&scope=openid%20profile&state=STATE&response_type=code`,
|
6 |
status: 200,
|
7 |
ok: true
|
8 |
}
|
app/login/callback/page.tsx
CHANGED
@@ -1,7 +1,47 @@
|
|
1 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
return (
|
3 |
<div className="pb-32">
|
4 |
<p className="font-bold text-4xl text-white">LOGIN CALLBACK</p>
|
|
|
5 |
</div>
|
6 |
);
|
7 |
}
|
|
|
1 |
+
async function getAuth(code: string) {
|
2 |
+
try {
|
3 |
+
const REDIRECT_URI = `https://${process.env.SPACE_HOST}/login/callback`;
|
4 |
+
const Authorization = `Basic ${Buffer.from(
|
5 |
+
`${process.env.OAUTH_CLIENT_ID}:${process.env.OAUTH_CLIENT_SECRET}`
|
6 |
+
).toString("base64")}`;
|
7 |
+
|
8 |
+
const request = await fetch("https://huggingface.co/oauth/token", {
|
9 |
+
method: "POST",
|
10 |
+
headers: {
|
11 |
+
"Content-Type": "application/x-www-form-urlencoded",
|
12 |
+
Authorization,
|
13 |
+
},
|
14 |
+
// send as Form data
|
15 |
+
body: new URLSearchParams({
|
16 |
+
grant_type: "authorization_code",
|
17 |
+
code,
|
18 |
+
redirect_uri: REDIRECT_URI,
|
19 |
+
}),
|
20 |
+
});
|
21 |
+
|
22 |
+
const response = await request
|
23 |
+
.clone()
|
24 |
+
.json()
|
25 |
+
.catch(() => ({}));
|
26 |
+
console.log(response);
|
27 |
+
return response;
|
28 |
+
} catch (error) {
|
29 |
+
console.log("error", error);
|
30 |
+
return null;
|
31 |
+
}
|
32 |
+
}
|
33 |
+
|
34 |
+
export default async function LoginCallback({
|
35 |
+
searchParams,
|
36 |
+
}: {
|
37 |
+
searchParams: { [key: string]: string | string[] | undefined };
|
38 |
+
}) {
|
39 |
+
const profile = await getAuth(searchParams?.code as string);
|
40 |
+
console.log(profile);
|
41 |
return (
|
42 |
<div className="pb-32">
|
43 |
<p className="font-bold text-4xl text-white">LOGIN CALLBACK</p>
|
44 |
+
{profile && JSON.stringify(profile, null, 2)}
|
45 |
</div>
|
46 |
);
|
47 |
}
|
components/main/index.tsx
CHANGED
@@ -9,6 +9,7 @@ import { Button } from "@/components/button";
|
|
9 |
import { useInputGeneration } from "./hooks/useInputGeneration";
|
10 |
import { Collections } from "./collections";
|
11 |
import { Settings } from "./settings";
|
|
|
12 |
|
13 |
const categories = [
|
14 |
{
|
@@ -26,18 +27,11 @@ const categories = [
|
|
26 |
|
27 |
export const Main = () => {
|
28 |
const user = false;
|
|
|
29 |
const { list_styles, style, setStyle, loading } = useInputGeneration();
|
30 |
const [category, setCategory] = useState<string>("community");
|
31 |
const [advancedSettings, setAdvancedSettings] = useState<boolean>(false);
|
32 |
|
33 |
-
const openLogin = async () => {
|
34 |
-
const response = await fetch(`/api/login`);
|
35 |
-
const { ok, redirect } = await response.json();
|
36 |
-
if (ok && redirect) {
|
37 |
-
window.open(redirect, "_blank");
|
38 |
-
}
|
39 |
-
};
|
40 |
-
|
41 |
return (
|
42 |
<main className="px-6 z-[2] relative max-w-[1722px] mx-auto">
|
43 |
<div className="py-2 pl-2 pr-2 lg:pr-4 bg-black bg-opacity-30 backdrop-blur-sm lg:sticky lg:top-4 z-10 rounded-full">
|
@@ -46,7 +40,7 @@ export const Main = () => {
|
|
46 |
<div className="items-center justify-center lg:justify-end gap-5 w-full mt-6 lg:mt-0 hidden lg:flex">
|
47 |
{categories.map(({ key, label, icon, isLogged }) =>
|
48 |
isLogged && !user ? (
|
49 |
-
<Button key={key} theme="white" onClick={
|
50 |
Sign in with Hugging Face
|
51 |
</Button>
|
52 |
) : (
|
|
|
9 |
import { useInputGeneration } from "./hooks/useInputGeneration";
|
10 |
import { Collections } from "./collections";
|
11 |
import { Settings } from "./settings";
|
12 |
+
import { useUser } from "@/utils/useUser";
|
13 |
|
14 |
const categories = [
|
15 |
{
|
|
|
27 |
|
28 |
export const Main = () => {
|
29 |
const user = false;
|
30 |
+
const { openWindowLogin } = useUser();
|
31 |
const { list_styles, style, setStyle, loading } = useInputGeneration();
|
32 |
const [category, setCategory] = useState<string>("community");
|
33 |
const [advancedSettings, setAdvancedSettings] = useState<boolean>(false);
|
34 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
35 |
return (
|
36 |
<main className="px-6 z-[2] relative max-w-[1722px] mx-auto">
|
37 |
<div className="py-2 pl-2 pr-2 lg:pr-4 bg-black bg-opacity-30 backdrop-blur-sm lg:sticky lg:top-4 z-10 rounded-full">
|
|
|
40 |
<div className="items-center justify-center lg:justify-end gap-5 w-full mt-6 lg:mt-0 hidden lg:flex">
|
41 |
{categories.map(({ key, label, icon, isLogged }) =>
|
42 |
isLogged && !user ? (
|
43 |
+
<Button key={key} theme="white" onClick={openWindowLogin}>
|
44 |
Sign in with Hugging Face
|
45 |
</Button>
|
46 |
) : (
|
utils/useUser.ts
ADDED
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
export const useUser = () => {
|
2 |
+
const openWindowLogin = async () => {
|
3 |
+
const response = await fetch(`/api/login`);
|
4 |
+
const { ok, redirect } = await response.json();
|
5 |
+
if (ok && redirect) {
|
6 |
+
window.open(redirect, "_blank");
|
7 |
+
}
|
8 |
+
};
|
9 |
+
|
10 |
+
return {
|
11 |
+
openWindowLogin,
|
12 |
+
}
|
13 |
+
}
|