From 0a9369aba54b57b4721691d9027b0e305e36f50d Mon Sep 17 00:00:00 2001 From: LittleSheep Date: Thu, 29 Feb 2024 22:14:22 +0800 Subject: [PATCH] :sparkles: OAuth & Auth Guard --- pkg/views/bun.lockb | Bin 165996 -> 166649 bytes pkg/views/src/main.tsx | 33 +++-- pkg/views/src/pages/auth/connect.tsx | 182 +++++++++++++++++++++++++++ pkg/views/src/pages/auth/layout.tsx | 12 ++ pkg/views/src/pages/auth/sign-in.tsx | 86 +++++++------ pkg/views/src/pages/auth/sign-up.tsx | 50 ++++---- pkg/views/src/pages/guard.tsx | 29 +++++ pkg/views/src/stores/userinfo.tsx | 14 ++- 8 files changed, 328 insertions(+), 78 deletions(-) create mode 100644 pkg/views/src/pages/auth/connect.tsx create mode 100644 pkg/views/src/pages/auth/layout.tsx create mode 100644 pkg/views/src/pages/guard.tsx diff --git a/pkg/views/bun.lockb b/pkg/views/bun.lockb index 20e87a6d5a753b7a3a7a5c84c5f4c9b6d3c0d28b..b20726d0f6073c9200167bf7a0af4e3102b00b7f 100755 GIT binary patch delta 32566 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 delta 31933 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 }, { - path: "/users", - element: , + path: "/", + element: , children: [ - { path: "/users", element: }, - { path: "/users/notifications", element: }, - { path: "/users/personalize", element: }, - { path: "/users/security", element: } + { + path: "/users", + element: , + children: [ + { path: "/users", element: }, + { path: "/users/notifications", element: }, + { path: "/users/personalize", element: }, + { path: "/users/security", element: } + ] + } ] } ] }, - { path: "/auth/sign-up", element: , errorElement: }, - { path: "/auth/sign-in", element: , errorElement: } + { + path: "/auth", + element: , + errorElement: , + children: [ + { path: "/auth/sign-up", element: , errorElement: }, + { path: "/auth/sign-in", element: , errorElement: }, + { path: "/auth/o/connect", element: , errorElement: } + ] + } ]); const element = ( diff --git a/pkg/views/src/pages/auth/connect.tsx b/pkg/views/src/pages/auth/connect.tsx new file mode 100644 index 0000000..567a3ed --- /dev/null +++ b/pkg/views/src/pages/auth/connect.tsx @@ -0,0 +1,182 @@ +import { useEffect, useState } from "react"; +import { + Alert, + Avatar, + Box, + Button, + Card, + CardContent, + Collapse, + Grid, + LinearProgress, + Typography +} from "@mui/material"; +import { request } from "@/scripts/request.ts"; +import { useUserinfo } from "@/stores/userinfo.tsx"; +import { useSearchParams } from "react-router-dom"; +import OutletIcon from "@mui/icons-material/Outlet"; +import WhatshotIcon from "@mui/icons-material/Whatshot"; + +export default function OauthConnectPage() { + const { getAtk } = useUserinfo(); + + const [panel, setPanel] = useState(0); + const [error, setError] = useState(null); + const [loading, setLoading] = useState(false); + + const [client, setClient] = useState(null); + + const [searchParams] = useSearchParams(); + + async function preconnect() { + const res = await request(`/api/auth/o/connect${location.search}`, { + headers: { "Authorization": `Bearer ${getAtk()}` } + }); + + if (res.status !== 200) { + setError(await res.text()); + } else { + const data = await res.json(); + + if (data["session"]) { + setPanel(1); + redirect(data["session"]); + } else { + setClient(data["client"]); + setLoading(false); + } + } + } + + useEffect(() => { + preconnect().then(() => console.log("Fetched metadata")); + }, []); + + function decline() { + if (window.history.length > 0) { + window.history.back(); + } else { + window.close(); + } + } + + async function approve() { + setLoading(true); + + const res = await request("/api/auth/o/connect?" + new URLSearchParams({ + client_id: searchParams.get("client_id") as string, + redirect_uri: encodeURIComponent(searchParams.get("redirect_uri") as string), + response_type: "code", + scope: searchParams.get("scope") as string + }), { + method: "POST", + headers: { "Authorization": `Bearer ${getAtk()}` } + }); + + if (res.status !== 200) { + setError(await res.text()); + setLoading(false); + } else { + const data = await res.json(); + setPanel(1); + setTimeout(() => redirect(data["session"]), 1850); + } + } + + function redirect(session: any) { + const url = `${searchParams.get("redirect_uri")}?code=${session["grant_token"]}&state=${searchParams.get("state")}`; + window.open(url, "_self"); + } + + const elements = [ + ( + <> + + + + + Sign in to {client?.name} + + + + + About this app + {client?.description} + + + Make you trust this app + + After you click Approve button, you will share your basic personal information to this application + developer. Some of them will leak your data. Think twice. + + + + + + + + + + + + ), + ( + <> + + + + + Authorized + + + + + Now Redirecting... + Hold on a second, we are going to redirect you to the target. + + + + + ) + ]; + + return ( + <> + {error && {error}} + + + + + + + + {elements[panel]} + + + + ); +} \ No newline at end of file diff --git a/pkg/views/src/pages/auth/layout.tsx b/pkg/views/src/pages/auth/layout.tsx new file mode 100644 index 0000000..f9dec4c --- /dev/null +++ b/pkg/views/src/pages/auth/layout.tsx @@ -0,0 +1,12 @@ +import { Box } from "@mui/material"; +import { Outlet } from "react-router-dom"; + +export default function AuthLayout() { + return ( + + + + + + ) +} \ No newline at end of file diff --git a/pkg/views/src/pages/auth/sign-in.tsx b/pkg/views/src/pages/auth/sign-in.tsx index 2173d10..22a62a7 100644 --- a/pkg/views/src/pages/auth/sign-in.tsx +++ b/pkg/views/src/pages/auth/sign-in.tsx @@ -277,51 +277,55 @@ export default function SignInPage() { } return ( - - - {error && {error}} + <> + {error && {error}} - - - - + + + You need sign in before take an action. After that, we will take you back to your work. + + - - {elements[panel]} - + + + + - - - - - Risk {challenge?.risk_level}  - Progress {challenge?.progress}/{challenge?.requirements} - - - - - - + + {elements[panel]} + - - - - Haven't an account? Sign up! - - + + + + + Risk {challenge?.risk_level}  + Progress {challenge?.progress}/{challenge?.requirements} + + + + + + + + + + + Haven't an account? Sign up! + - - + + ); } \ No newline at end of file diff --git a/pkg/views/src/pages/auth/sign-up.tsx b/pkg/views/src/pages/auth/sign-up.tsx index ba3dc8b..0af8031 100644 --- a/pkg/views/src/pages/auth/sign-up.tsx +++ b/pkg/views/src/pages/auth/sign-up.tsx @@ -166,35 +166,33 @@ export default function SignUpPage() { ]; return ( - - - {error && {error}} + <> + {error && {error}} - - - - + + + + - - {!done ? elements[0] : elements[1]} - - + + {!done ? elements[0] : elements[1]} + + - - - - Already have an account? Sign in! - - + + + + Already have an account? Sign in! + - - + + ); } \ No newline at end of file diff --git a/pkg/views/src/pages/guard.tsx b/pkg/views/src/pages/guard.tsx new file mode 100644 index 0000000..ce39a4c --- /dev/null +++ b/pkg/views/src/pages/guard.tsx @@ -0,0 +1,29 @@ +import { useEffect } from "react"; +import { Box, CircularProgress } from "@mui/material"; +import { Outlet, useLocation, useNavigate } from "react-router-dom"; +import { useUserinfo } from "@/stores/userinfo.tsx"; + +export default function AuthGuard() { + const { userinfo } = useUserinfo(); + + const navigate = useNavigate(); + const location = useLocation(); + + useEffect(() => { + console.log(userinfo) + if (userinfo?.isReady) { + if (!userinfo?.isLoggedIn) { + const callback = location.pathname + location.search; + navigate({ pathname: "/auth/sign-in", search: `redirect_uri=${callback}` }); + } + } + }, [userinfo]); + + return !userinfo?.isReady ? ( + + + + + + ) : ; +} \ No newline at end of file diff --git a/pkg/views/src/stores/userinfo.tsx b/pkg/views/src/stores/userinfo.tsx index e3400f7..4f70622 100644 --- a/pkg/views/src/stores/userinfo.tsx +++ b/pkg/views/src/stores/userinfo.tsx @@ -3,15 +3,17 @@ import { request } from "../scripts/request.ts"; import { createContext, useContext, useState } from "react"; export interface Userinfo { + isReady: boolean, isLoggedIn: boolean, displayName: string, data: any, } const defaultUserinfo: Userinfo = { + isReady: false, isLoggedIn: false, displayName: "Citizen", - data: null, + data: null }; const UserinfoContext = createContext({ userinfo: defaultUserinfo }); @@ -28,10 +30,15 @@ export function UserinfoProvider(props: any) { } async function readProfiles() { - if (!checkLoggedIn()) return; + if (!checkLoggedIn()) { + setUserinfo((data) => { + data.isReady = true; + return data; + }); + } const res = await request("/api/users/me", { - credentials: "include" + headers: { "Authorization": `Bearer ${getAtk()}` } }); if (res.status !== 200) { @@ -42,6 +49,7 @@ export function UserinfoProvider(props: any) { const data = await res.json(); setUserinfo({ + isReady: true, isLoggedIn: true, displayName: data["nick"], data: data