✨ Pull user profile
This commit is contained in:
		| @@ -19,7 +19,8 @@ | ||||
|     "next": "15.1.3", | ||||
|     "react": "^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": { | ||||
|     "typescript": "^5", | ||||
|   | ||||
| @@ -3,6 +3,8 @@ import type { AppProps } from 'next/app' | ||||
| import { Box, createTheme, CssBaseline, ThemeProvider } from '@mui/material' | ||||
| import { Roboto } from 'next/font/google' | ||||
| import { CapAppBar } from '@/components/CapAppBar' | ||||
| import { useUserStore } from '@/services/user' | ||||
| import { useEffect } from 'react' | ||||
|  | ||||
| const fontRoboto = Roboto({ | ||||
|   subsets: ['latin'], | ||||
| @@ -23,6 +25,12 @@ const siteTheme = createTheme({ | ||||
| }) | ||||
|  | ||||
| export default function App({ Component, pageProps }: AppProps) { | ||||
|   const userStore = useUserStore() | ||||
|  | ||||
|   useEffect(() => { | ||||
|     userStore.fetchUser() | ||||
|   }, []) | ||||
|  | ||||
|   return ( | ||||
|     <> | ||||
|       <style jsx global>{` | ||||
|   | ||||
| @@ -2,7 +2,7 @@ import axios, { AxiosInstance } from 'axios' | ||||
| import applyCaseMiddleware from 'axios-case-converter' | ||||
| 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 = (() => { | ||||
|   const inst = axios.create({ | ||||
| @@ -29,12 +29,16 @@ async function refreshToken(): Promise<string | undefined> { | ||||
|   if (!hasCookie('nex_user_atk') || !hasCookie('nex_user_rtk')) return | ||||
|  | ||||
|   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', { | ||||
|     refresh_token: getCookie('nex_user_rtk')!, | ||||
|     grant_type: 'refresh_token', | ||||
|   }) | ||||
|   const resp = await axios.post( | ||||
|     '/cgi/id/auth/token', | ||||
|     { | ||||
|       refresh_token: getCookie('nex_user_rtk')!, | ||||
|       grant_type: 'refresh_token', | ||||
|     }, | ||||
|     { baseURL }, | ||||
|   ) | ||||
|   const atk: string = resp.data['accessToken'] | ||||
|   const rtk: string = resp.data['refreshToken'] | ||||
|   setCookie('nex_user_atk', atk, { path: '/', maxAge: 2592000 }) | ||||
|   | ||||
							
								
								
									
										82
									
								
								src/services/user.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								src/services/user.ts
									
									
									
									
									
										Normal 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 | ||||
|     } | ||||
|   }, | ||||
| })) | ||||
		Reference in New Issue
	
	Block a user