all kinds of frontend sec. adaptations
Some checks failed
continuous-integration/drone/push Build is failing
Some checks failed
continuous-integration/drone/push Build is failing
This commit is contained in:
@ -1,4 +1,5 @@
|
||||
import { createContext, useContext, useEffect, useMemo, useState, PropsWithChildren } from 'react'
|
||||
import { createContext, useContext, useEffect, useMemo, useState } from 'react'
|
||||
import type { PropsWithChildren } from 'react'
|
||||
import { userManager } from './oidc'
|
||||
import type { User } from 'oidc-client-ts'
|
||||
|
||||
@ -42,13 +43,19 @@ userManager.events.removeAccessTokenExpired(onExpired)
|
||||
|
||||
|
||||
// Spegla token till sessionStorage så ky kan läsa den
|
||||
// i useEffect som speglar token:
|
||||
useEffect(() => {
|
||||
const token = user?.access_token ?? null
|
||||
if (token) sessionStorage.setItem('access_token', token)
|
||||
else sessionStorage.removeItem('access_token')
|
||||
const token = user?.access_token ?? null
|
||||
if (token) {
|
||||
sessionStorage.setItem('access_token', token)
|
||||
console.debug('access_token set')
|
||||
} else {
|
||||
sessionStorage.removeItem('access_token')
|
||||
}
|
||||
}, [user])
|
||||
|
||||
|
||||
|
||||
const api: AuthCtx = useMemo(() => ({
|
||||
user,
|
||||
isAuthenticated: !!user && !user.expired,
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { UserManager, WebStorageStateStore, Log, type UserManagerSettings } from 'oidc-client-ts'
|
||||
|
||||
|
||||
console.log('AUTHORITY:', import.meta.env.VITE_OIDC_AUTHORITY)
|
||||
const settings: UserManagerSettings = {
|
||||
authority: import.meta.env.VITE_OIDC_AUTHORITY!,
|
||||
client_id: import.meta.env.VITE_OIDC_CLIENT_ID!,
|
||||
|
||||
@ -8,6 +8,7 @@ import { DueTomorrowPage } from '@/pages/DueTomorrowPage'
|
||||
import AuthCallbackPage from '@/pages/AuthCallbackPage'
|
||||
import SilentRenewPage from '@/pages/SilentRenewPage'
|
||||
import LogoutPage from '@/pages/LogoutPage'
|
||||
import { RequireAuth } from 'auth/RequireAuth'
|
||||
|
||||
const router = createBrowserRouter([
|
||||
{ path: '/auth/callback', element: <AuthCallbackPage /> },
|
||||
@ -15,7 +16,11 @@ const router = createBrowserRouter([
|
||||
{ path: '/logout', element: <LogoutPage /> },
|
||||
{
|
||||
path: '/',
|
||||
element: <RootLayout />,
|
||||
element: (
|
||||
<RequireAuth>
|
||||
<RootLayout />
|
||||
</RequireAuth>
|
||||
),
|
||||
children: [
|
||||
{ index: true, element: <DashboardPage /> },
|
||||
{ path: 'households/:householdId/board', element: <HouseholdBoardPage /> },
|
||||
|
||||
@ -2,8 +2,16 @@ import { useQuery } from '@tanstack/react-query'
|
||||
import { fetchMe } from './api'
|
||||
|
||||
export function MeBadge() {
|
||||
const { data, isLoading, isError } = useQuery({ queryKey: ['me'], queryFn: fetchMe, retry: 0 })
|
||||
const hasToken = !!sessionStorage.getItem('access_token')
|
||||
const { data, isLoading, isError } = useQuery({
|
||||
queryKey: ['me'],
|
||||
queryFn: fetchMe,
|
||||
enabled: hasToken, // 👈 vänta tills token finns
|
||||
retry: 0,
|
||||
})
|
||||
|
||||
if (!hasToken) return <span className="opacity-60">ej inloggad</span>
|
||||
if (isLoading) return <span className="opacity-60">…</span>
|
||||
if (isError) return <span className="opacity-60">ej inloggad</span>
|
||||
if (isError) return <span className="opacity-60">fel</span>
|
||||
return <span className="opacity-80 text-sm">{data?.name || data?.preferred_username || 'me'}</span>
|
||||
}
|
||||
|
||||
@ -1,15 +1,29 @@
|
||||
import { useEffect } from 'react'
|
||||
// src/pages/AuthCallbackPage.tsx
|
||||
import { useEffect, useRef } from 'react'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import { userManager } from 'auth/oidc'
|
||||
|
||||
|
||||
export default function AuthCallbackPage() {
|
||||
const navigate = useNavigate()
|
||||
useEffect(() => {
|
||||
userManager.signinRedirectCallback().then((res) => {
|
||||
const target = (res?.state as any)?.returnTo || '/'
|
||||
navigate(target, { replace: true })
|
||||
})
|
||||
}, [navigate])
|
||||
return <p>Completing sign-in…</p>
|
||||
const navigate = useNavigate()
|
||||
const handled = useRef(false)
|
||||
|
||||
useEffect(() => {
|
||||
if (handled.current) return // 👈 skydd mot StrictMode dubbelkörning
|
||||
handled.current = true
|
||||
|
||||
;(async () => {
|
||||
try {
|
||||
const res = await userManager.signinRedirectCallback()
|
||||
const target = (res?.state as any)?.returnTo || '/'
|
||||
// Städa bort ?code&state ur URL:en:
|
||||
window.history.replaceState({}, '', target)
|
||||
navigate(target, { replace: true })
|
||||
} catch (err) {
|
||||
console.error('signinRedirectCallback failed:', err)
|
||||
navigate('/', { replace: true })
|
||||
}
|
||||
})()
|
||||
}, [navigate])
|
||||
|
||||
return <p>Completing sign-in…</p>
|
||||
}
|
||||
Reference in New Issue
Block a user