Pull user profile

This commit is contained in:
LittleSheep 2025-01-01 23:05:19 +08:00
parent ac4afdcf06
commit 10092b403b
5 changed files with 102 additions and 7 deletions

BIN
bun.lockb

Binary file not shown.

View File

@ -19,7 +19,8 @@
"next": "15.1.3", "next": "15.1.3",
"react": "^19.0.0", "react": "^19.0.0",
"react-dom": "^19.0.0", "react-dom": "^19.0.0",
"react-hook-form": "^7.54.2" "react-hook-form": "^7.54.2",
"zustand": "^5.0.2"
}, },
"devDependencies": { "devDependencies": {
"typescript": "^5", "typescript": "^5",

View File

@ -3,6 +3,8 @@ import type { AppProps } from 'next/app'
import { Box, createTheme, CssBaseline, ThemeProvider } from '@mui/material' import { Box, createTheme, CssBaseline, ThemeProvider } from '@mui/material'
import { Roboto } from 'next/font/google' import { Roboto } from 'next/font/google'
import { CapAppBar } from '@/components/CapAppBar' import { CapAppBar } from '@/components/CapAppBar'
import { useUserStore } from '@/services/user'
import { useEffect } from 'react'
const fontRoboto = Roboto({ const fontRoboto = Roboto({
subsets: ['latin'], subsets: ['latin'],
@ -23,6 +25,12 @@ const siteTheme = createTheme({
}) })
export default function App({ Component, pageProps }: AppProps) { export default function App({ Component, pageProps }: AppProps) {
const userStore = useUserStore()
useEffect(() => {
userStore.fetchUser()
}, [])
return ( return (
<> <>
<style jsx global>{` <style jsx global>{`

View File

@ -2,7 +2,7 @@ import axios, { AxiosInstance } from 'axios'
import applyCaseMiddleware from 'axios-case-converter' import applyCaseMiddleware from 'axios-case-converter'
import { hasCookie, getCookie, setCookie } from 'cookies-next/client' import { hasCookie, getCookie, setCookie } from 'cookies-next/client'
const baseURL = 'https://api.solsynth.dev' const baseURL = 'https://api.sn.solsynth.dev'
export let sni: AxiosInstance = (() => { export let sni: AxiosInstance = (() => {
const inst = axios.create({ const inst = axios.create({
@ -29,12 +29,16 @@ async function refreshToken(): Promise<string | undefined> {
if (!hasCookie('nex_user_atk') || !hasCookie('nex_user_rtk')) return if (!hasCookie('nex_user_atk') || !hasCookie('nex_user_rtk')) return
const ogTk: string = getCookie('nex_user_atk')! const ogTk: string = getCookie('nex_user_atk')!
if (!isTokenExpired(ogTk)) return if (!isTokenExpired(ogTk)) return ogTk
const resp = await axios.post('/cgi/id/auth/token', { const resp = await axios.post(
refresh_token: getCookie('nex_user_rtk')!, '/cgi/id/auth/token',
grant_type: 'refresh_token', {
}) refresh_token: getCookie('nex_user_rtk')!,
grant_type: 'refresh_token',
},
{ baseURL },
)
const atk: string = resp.data['accessToken'] const atk: string = resp.data['accessToken']
const rtk: string = resp.data['refreshToken'] const rtk: string = resp.data['refreshToken']
setCookie('nex_user_atk', atk, { path: '/', maxAge: 2592000 }) setCookie('nex_user_atk', atk, { path: '/', maxAge: 2592000 })

82
src/services/user.ts Normal file
View File

@ -0,0 +1,82 @@
import { create } from 'zustand'
import { sni } from './network'
import { hasCookie } from 'cookies-next/client'
interface SnAccount {
id: number
createdAt: Date
updatedAt: Date
deletedAt?: Date | null
confirmedAt?: Date | null
contacts?: SnAccountContact[] | null
avatar: string
banner: string
description: string
name: string
nick: string
permNodes: Record<string, any>
profile?: SnAccountProfile | null
badges: SnAccountBadge[]
suspendedAt?: Date | null
affiliatedId?: number | null
affiliatedTo?: number | null
automatedBy?: number | null
automatedId?: number | null
}
interface SnAccountContact {
accountId: number
content: string
createdAt: Date
deletedAt?: Date | null
id: number
isPrimary: boolean
isPublic: boolean
type: number
updatedAt: Date
verifiedAt?: Date | null
}
interface SnAccountProfile {
id: number
accountId: number
birthday?: Date | null
createdAt: Date
deletedAt?: Date | null
experience: number
firstName: string
lastName: string
lastSeenAt?: Date | null
updatedAt: Date
}
interface SnAccountBadge {
id: number
createdAt: Date
updatedAt: Date
deletedAt?: Date | null
type: string
accountId: number
metadata: Record<string, any>
}
export interface UserStore {
account: SnAccount | undefined
fetchUser: () => Promise<SnAccount | undefined>
}
export const useUserStore = create<UserStore>((set) => ({
account: undefined,
fetchUser: async (): Promise<SnAccount | undefined> => {
if (!hasCookie('nex_user_atk')) return
try {
const resp = await sni.get<SnAccount>('/cgi/id/users/me')
set({ account: resp.data })
console.log('[Authenticator] Logged in as @' + resp.data.name)
return resp.data
} catch (err) {
console.error('[Authenticator] Unable to get user profile: ', err)
return
}
},
}))