feat(fullstack): Set user roles per orga, scope notification to orga and role, add orga and role to JWT

This commit is contained in:
2025-09-15 19:23:06 +02:00
parent 83f1fa71b6
commit e3643d8318
25 changed files with 575 additions and 287 deletions

View File

@@ -93,7 +93,7 @@ export function useAuth() {
redirectGuestTo: '/login'
})
async function fetchSession() {
async function fetchSession(targetPath?: string) {
if (sessionFetching.value) {
console.log('already fetching session')
return
@@ -109,7 +109,7 @@ export function useAuth() {
sessionFetching.value = false
// Only fetch JWT and organizations if we have a session and not on public routes
if (session.value && !isPublicRoute()) {
if (session.value && !isPublicPath(targetPath)) {
await fetchJwtAndOrganizations()
}
@@ -160,10 +160,10 @@ export function useAuth() {
})
}
function isPublicRoute(routeToCheck?: RouteLocationNormalizedLoaded) {
const finalRoute = routeToCheck ?? route
function isPublicPath(path?: string) {
const finalPath = path ?? route.path
const publicRoutes = ['/login', '/signup', '/accept-invitation']
return publicRoutes.some((path) => finalRoute.path.startsWith(path))
return publicRoutes.some((path) => finalPath.startsWith(path))
}
async function signOut({ redirectTo }: { redirectTo?: RouteLocationRaw } = {}) {
@@ -195,7 +195,7 @@ export function useAuth() {
fetchSession,
client,
jwt,
isPublicRoute,
isPublicPath,
activeMember
}
}

View File

@@ -37,6 +37,19 @@ export function useUser() {
}
}
async function updateUser(id: string, userDto?: UserDto): Promise<UserDto> {
try {
return await userApi.updateUser(id, userDto)
} catch (e: unknown) {
if (e instanceof ResponseError) {
console.error(`Failed updating user with ID ${id}:`, e.response)
} else {
console.error(`Failed updating user with ID ${id}:`, e)
}
return Promise.reject(e)
}
}
async function deleteUser(id: string): Promise<void> {
try {
return await userApi.deleteUser(id)
@@ -53,6 +66,7 @@ export function useUser() {
return {
createUser,
getUserById,
updateUser,
deleteUser
}
}

View File

@@ -1,9 +1,4 @@
import {
UserApi,
Configuration,
type CreateUserDto,
type UserDto
} from '~/.api-client'
import { UserApi, Configuration, type CreateUserDto, type UserDto } from '~/.api-client'
import { cleanDoubleSlashes, withoutTrailingSlash } from 'ufo'
export function useUserApi() {
@@ -15,25 +10,32 @@ export function useUserApi() {
cleanDoubleSlashes(import.meta.client ? appBaseUrl + clientProxyBasePath : serverApiBaseUrl + serverApiBasePath)
)
const userApiClient = new UserApi(
new Configuration({ basePath, headers: { Authorization: jwt.value ? `Bearer ${jwt.value}` : '' } })
// Track changing JWT of user who accepts the invitation
const userApiClient = computed(
() =>
new UserApi(new Configuration({ basePath, headers: { Authorization: jwt.value ? `Bearer ${jwt.value}` : '' } }))
)
async function createUser(createUserDto: CreateUserDto): Promise<UserDto> {
return userApiClient.createUser({ createUserDto })
return userApiClient.value.createUser({ createUserDto })
}
async function getUserById(id: string): Promise<UserDto> {
return userApiClient.getUserById({ id })
return userApiClient.value.getUserById({ id })
}
async function updateUser(id: string, userDto?: UserDto): Promise<UserDto> {
return userApiClient.value.updateUser({ id, userDto })
}
async function deleteUser(id: string): Promise<void> {
return userApiClient.deleteUser({ id })
return userApiClient.value.deleteUser({ id })
}
return {
createUser,
getUserById,
updateUser,
deleteUser
}
}
}