refresh user

This commit is contained in:
john 2025-05-19 09:23:15 +02:00
parent 57e56dc33d
commit 17c9885ccc
6 changed files with 127 additions and 20 deletions

View file

@ -14,9 +14,7 @@ export async function generateApiSchema(openapiUrl, outputFilePath, pathToPretti
const request = new Request(openapiUrl)
const response = await fetch(request)
const json = await response.text()
const ast = await openapiTS(json, {
pathParamsAsTypes: true,
})
const ast = await openapiTS(json, {})
const prettierConfig = await resolveConfig(pathToPrettierRc, {
useCache: true,
})

View file

@ -10,6 +10,7 @@ import LogoutPage from './app/auth/pages/LogoutPage.tsx'
import UnauthorizedHandler from './app/auth/components/UnauthorizedHandler.tsx'
import AdminPage from './app/admin/pages/AdminPage.tsx'
import SignupCodesManagementPage from './app/admin/pages/subpages/SignupCodesManagementPage.tsx'
import RefreshUser from './app/auth/components/RefreshUser.tsx'
function App() {
const postService = new PostsService()
@ -19,6 +20,7 @@ function App() {
return (
<BrowserRouter>
<UnauthorizedHandler>
<RefreshUser authService={authService}>
<Routes>
<Route
path={'/'}
@ -35,6 +37,7 @@ function App() {
/>
</Route>
</Routes>
</RefreshUser>
</UnauthorizedHandler>
</BrowserRouter>
)

View file

@ -87,8 +87,7 @@ export interface paths {
requestBody: {
content: {
'multipart/form-data': {
/** Format: binary */
file?: string
file?: components['schemas']['IFormFile']
}
}
}
@ -112,7 +111,7 @@ export interface paths {
patch?: never
trace?: never
}
[path: `/media/${string}`]: {
'/media/{id}': {
parameters: {
query?: never
header?: never
@ -266,6 +265,45 @@ export interface paths {
patch?: never
trace?: never
}
'/auth/user/{userId}': {
parameters: {
query?: never
header?: never
path?: never
cookie?: never
}
get: {
parameters: {
query?: never
header?: never
path: {
userId: string
}
cookie?: never
}
requestBody?: never
responses: {
/** @description OK */
200: {
headers: {
[name: string]: unknown
}
content: {
'text/plain': components['schemas']['RefreshUserResult']
'application/json': components['schemas']['RefreshUserResult']
'text/json': components['schemas']['RefreshUserResult']
}
}
}
}
put?: never
post?: never
delete?: never
options?: never
head?: never
patch?: never
trace?: never
}
'/auth/signup-codes': {
parameters: {
query?: never
@ -362,6 +400,8 @@ export interface components {
/** Format: uuid */
next: string | null
}
/** Format: binary */
IFormFile: string
ListSignupCodesResult: {
signupCodes: components['schemas']['SignupCodeDto'][]
}
@ -397,6 +437,12 @@ export interface components {
/** Format: int32 */
height: number | null
}
RefreshUserResult: {
/** Format: uuid */
userId: string
username: string
isSuperUser: boolean
}
RegisterRequest: {
username: string
password: string

View file

@ -63,4 +63,35 @@ export class AuthService {
return res.data.signupCodes.map(SignupCode.fromDto)
}
async refreshUser(userId: string) {
if (this.getCookie('hasSession') !== 'true') {
return
}
const res = await client.GET(`/auth/user/{userId}`, {
params: {
path: { userId },
},
credentials: 'include',
})
if (!res.data) {
dispatchMessage('auth:user-refresh-failed', null)
} else {
dispatchMessage('auth:user-refreshed', { ...res.data })
}
}
private getCookie(cookieName: string): string | undefined {
const cookie = document.cookie
.split('; ')
.map((c) => {
const [name, value] = c.split('=')
return { name, value }
})
.find((c) => c.name === cookieName)
return cookie?.value
}
}

View file

@ -0,0 +1,27 @@
import { PropsWithChildren, useEffect, useRef } from 'react'
import { AuthService } from '../authService.ts'
import { useUser } from '../../user/userStore.ts'
interface RefreshUserProps {
authService: AuthService
}
export default function RefreshUser({
authService,
children,
}: PropsWithChildren<RefreshUserProps>) {
const { user } = useUser()
const didRefresh = useRef(false)
useEffect(() => {
const timeoutId = setTimeout(async () => {
if (didRefresh.current) return
if (user == null) return
didRefresh.current = true
await authService.refreshUser(user.userId)
})
return () => clearTimeout(timeoutId)
}, [authService, user])
return <>{children}</>
}

View file

@ -5,4 +5,6 @@ export interface MessageTypes {
'auth:registered': User
'auth:logged-out': null
'auth:unauthorized': null
'auth:user-refreshed': User
'auth:user-refresh-failed': null
}