feat: refactor login

This commit is contained in:
Ou 2024-11-03 20:13:49 +08:00
parent 75ab32d250
commit 773ab138ca
12 changed files with 61 additions and 37 deletions

View File

@ -0,0 +1,8 @@
import process from "node:process"
export default defineEventHandler(async () => {
return {
enable: true,
url: `https://github.com/login/oauth/authorize?client_id=${process.env.G_CLIENT_ID}`,
}
})

View File

@ -53,10 +53,10 @@ function NewsCard({ id, handleListeners }: NewsCardProps) {
queryKey: [id, getRefreshId(id)],
queryFn: async ({ queryKey }) => {
const [_id, _refetchTime] = queryKey as [SourceID, number]
let url = `/api/s?id=${_id}`
let url = `/s?id=${_id}`
const headers: Record<string, any> = {}
if (Date.now() - _refetchTime < 1000) {
url = `/api/s?id=${_id}&latest`
url = `/s?id=${_id}&latest`
const jwt = safeParseString(localStorage.getItem("jwt"))
if (jwt) headers.Authorization = `Bearer ${jwt}`
} else if (cache.has(_id)) {

View File

@ -25,10 +25,11 @@ import { currentSourcesAtom } from "~/atoms"
export function Dnd() {
const [items, setItems] = useAtom(currentSourcesAtom)
useQuery({
queryKey: ["entries", items.sort()],
// sort in place
queryKey: ["entries", [...items].sort()],
queryFn: async ({ queryKey }) => {
const sources = queryKey[1]
const res: EntriesSourceResponse = await myFetch("/api/s/entries", {
const res: EntriesSourceResponse = await myFetch("/s/entries", {
method: "POST",
body: {
sources,

View File

@ -14,7 +14,7 @@ function ThemeToggle() {
}
export function Menu() {
const { loggedIn, login, logout, userInfo } = useLogin()
const { loggedIn, login, logout, userInfo, enableLogin } = useLogin()
const [shown, show] = useState(false)
const ref = useRef<HTMLElement>(null)
const isHover = useHoverDirty(ref)
@ -25,7 +25,7 @@ export function Menu() {
<span ref={ref} className="relative">
<span className="flex items-center scale-90">
{
loggedIn && userInfo.avatar
enableLogin && loggedIn && userInfo.avatar
? (
<button
type="button"
@ -57,7 +57,7 @@ export function Menu() {
}}
>
<ol className="bg-base bg-op-70! backdrop-blur-md p-2 rounded-lg color-base text-base">
{loggedIn
{enableLogin && (loggedIn
? (
<li onClick={logout}>
<span className="i-ph:sign-out-duotone inline-block" />
@ -69,7 +69,7 @@ export function Menu() {
<span className="i-ph:sign-in-duotone inline-block" />
<span>Github </span>
</li>
)}
))}
<ThemeToggle />
<li onClick={() => window.open(Homepage)}>
<span className="i-ph:github-logo-duotone inline-block" />

View File

@ -5,12 +5,32 @@ const userAtom = atomWithStorage<{
const jwtAtom = atomWithStorage("jwt", "")
const enableLoginAtom = atomWithStorage<{
enable: boolean
url?: string
}>("login", {
enable: true,
})
enableLoginAtom.onMount = (set) => {
myFetch("/enable-login").then((r) => {
set(r)
}).catch((e) => {
if (e.statusCode === 506) {
set({ enable: false })
console.log("clear")
}
})
}
export function useLogin() {
const userInfo = useAtomValue(userAtom)
const jwt = useAtomValue(jwtAtom)
const enableLogin = useAtomValue(enableLoginAtom)
const login = useCallback(() => {
window.location.href = __LOGIN_URL__
}, [])
window.location.href = enableLogin.url || "/api/login"
}, [enableLogin])
const logout = useCallback(() => {
window.localStorage.clear()
@ -20,6 +40,7 @@ export function useLogin() {
return {
loggedIn: !!jwt,
userInfo,
enableLogin: !!enableLogin.enable,
logout,
login,
}

View File

@ -16,14 +16,26 @@ function initRefetchSources() {
const refetchSourcesAtom = atom(initRefetchSources())
export function useRefetch() {
const [refetchSource, setRefetchSource] = useAtom(refetchSourcesAtom)
const { enableLogin, loggedIn, login } = useLogin()
const toaster = useToast()
const refresh = useCallback((...sources: SourceID[]) => {
if (loggedIn) {
const obj = Object.fromEntries(sources.map(id => [id, Date.now()]))
setRefetchSource(prev => ({
...prev,
...obj,
}))
}, [setRefetchSource])
} else if (enableLogin) {
toaster("登录后可以强制拉取最新数据", {
type: "warning",
action: {
label: "登录",
onClick: login,
},
})
}
}, [setRefetchSource, loggedIn, toaster, login, enableLogin])
const getRefreshId = useCallback((id: SourceID) => refetchSource[id], [refetchSource])

View File

@ -7,7 +7,7 @@ import { safeParseString } from "~/utils"
async function uploadMetadata(metadata: PrimitiveMetadata) {
const jwt = safeParseString(localStorage.getItem("jwt"))
if (!jwt) return
await myFetch("/api/me/sync", {
await myFetch("/me/sync", {
method: "POST",
headers: {
Authorization: `Bearer ${jwt}`,
@ -22,7 +22,7 @@ async function uploadMetadata(metadata: PrimitiveMetadata) {
async function downloadMetadata(): Promise<PrimitiveMetadata | undefined> {
const jwt = safeParseString(localStorage.getItem("jwt"))
if (!jwt) return
const { data, updatedTime } = await myFetch("/api/me/sync", {
const { data, updatedTime } = await myFetch("/me/sync", {
headers: {
Authorization: `Bearer ${jwt}`,
},

View File

@ -10,8 +10,6 @@ const router = createRouter({
context: {
queryClient,
},
defaultPreload: "intent",
defaultPreloadStaleTime: 0,
})
const rootElement = document.getElementById("app")!

View File

@ -15,14 +15,6 @@ export const Route = createRootRouteWithContext<{
}>()({
component: RootComponent,
notFoundComponent: NotFoundComponent,
beforeLoad: () => {
const query = new URLSearchParams(window.location.search)
if (query.has("login") && query.has("user") && query.has("jwt")) {
localStorage.setItem("user", query.get("user")!)
localStorage.setItem("jwt", JSON.stringify(query.get("jwt")!))
window.history.replaceState({}, document.title, window.location.pathname)
}
},
})
function NotFoundComponent() {

View File

@ -40,4 +40,5 @@ export class Timer {
export const myFetch = $fetch.create({
timeout: 15000,
retry: 0,
baseURL: "/api",
})

1
src/vite-env.d.ts vendored
View File

@ -2,4 +2,3 @@
/// <reference types="vite-plugin-pwa/react" />
/// <reference types="vite-plugin-pwa/info" />
/// <reference lib="webworker" />
declare const __LOGIN_URL__: string

View File

@ -1,4 +1,3 @@
import process from "node:process"
import { join } from "node:path"
import { defineConfig } from "vite"
import react from "@vitejs/plugin-react-swc"
@ -15,13 +14,6 @@ dotenv.config({
})
export default defineConfig({
define: {
__LOGIN_URL__: process.env.G_CLIENT_ID ? `"https://github.com/login/oauth/authorize?client_id=${process.env.G_CLIENT_ID}"` : `"/api/login"`,
},
build: {
sourcemap: true,
minify: false,
},
resolve: {
alias: {
"~": join(projectDir, "src"),