refactor: session handling (#2398)

* refactor session handling

* simplify
This commit is contained in:
Bernd Storath
2026-01-13 10:11:13 +01:00
committed by GitHub
parent b85286f0ab
commit 51558c7027
11 changed files with 38 additions and 31 deletions
+1 -1
View File
@@ -3,7 +3,7 @@
"aaron-bond.better-comments",
"dbaeumer.vscode-eslint",
"antfu.goto-alias",
"esbenp.prettier-vscode",
"prettier.prettier-vscode",
"yoavbls.pretty-ts-errors",
"bradlc.vscode-tailwindcss",
"vue.volar",
+5 -5
View File
@@ -1,22 +1,22 @@
{
"editor.tabSize": 2,
"editor.useTabStops": false,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.defaultFormatter": "prettier.prettier-vscode",
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "always"
},
"[vue]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
"editor.defaultFormatter": "prettier.prettier-vscode"
},
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
"editor.defaultFormatter": "prettier.prettier-vscode"
},
"[json]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
"editor.defaultFormatter": "prettier.prettier-vscode"
},
"[markdown]": {
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.defaultFormatter": "prettier.prettier-vscode",
"editor.tabSize": 4,
"editor.useTabStops": false
},
+6 -4
View File
@@ -4,25 +4,27 @@ export default defineNuxtRouteMiddleware(async (to) => {
return;
}
const event = useRequestEvent();
const authStore = useAuthStore();
const userData = await authStore.getSession();
authStore.userData = await authStore.getSession(event);
// skip login if already logged in
if (to.path === '/login') {
if (userData?.username) {
if (authStore.userData?.username) {
return navigateTo('/', { redirectCode: 302 });
}
return;
}
// Require auth for every page other than Login
if (!userData?.username) {
if (!authStore.userData?.username) {
return navigateTo('/login', { redirectCode: 302 });
}
// Check for admin access
if (to.path.startsWith('/admin')) {
if (!hasPermissions(userData, 'admin', 'any')) {
if (!hasPermissions(authStore.userData, 'admin', 'any')) {
return abortNavigation('Not allowed to access Admin Panel');
}
}
-3
View File
@@ -38,9 +38,6 @@
</template>
<script setup lang="ts">
const authStore = useAuthStore();
authStore.update();
const { t } = useI18n();
const route = useRoute();
-2
View File
@@ -206,9 +206,7 @@
</template>
<script lang="ts" setup>
const authStore = useAuthStore();
const globalStore = useGlobalStore();
authStore.update();
const route = useRoute();
const id = route.params.id as string;
-3
View File
@@ -29,9 +29,6 @@
</template>
<script setup lang="ts">
const authStore = useAuthStore();
authStore.update();
const globalStore = useGlobalStore();
const clientsStore = useClientsStore();
-3
View File
@@ -67,9 +67,6 @@
</template>
<script setup lang="ts">
const authStore = useAuthStore();
authStore.update();
const toast = useToast();
const { t } = useI18n();
-1
View File
@@ -120,7 +120,6 @@
import { encodeQR } from 'qr';
const authStore = useAuthStore();
authStore.update();
const name = ref(authStore.userData?.name);
const email = ref(authStore.userData?.email);
+14 -7
View File
@@ -1,18 +1,25 @@
export const useAuthStore = defineStore('Auth', () => {
const { data: userData, refresh: update } = useFetch('/api/session', {
method: 'get',
});
import type { H3Event } from 'h3';
import type { SharedPublicUser } from '~~/shared/utils/permissions';
async function getSession() {
export const useAuthStore = defineStore('Auth', () => {
const userData = useState<SharedPublicUser | null>('user-data', () => null);
async function getSession(event?: H3Event) {
const fetch = event?.$fetch || $fetch;
try {
const { data } = await useFetch('/api/session', {
const data = await fetch('/api/session', {
method: 'get',
});
return data.value;
return data;
} catch {
return null;
}
}
async function update() {
const data = await getSession();
userData.value = data;
}
return { userData, update, getSession };
});
+7 -2
View File
@@ -1,9 +1,14 @@
import type { SharedPublicUser } from '~~/shared/utils/permissions';
export default defineEventHandler(async (event) => {
const session = await useWGSession(event);
if (!session.data.userId) {
// not logged in
return null;
throw createError({
statusCode: 401,
statusMessage: 'Not authenticated',
});
}
const user = await Database.users.get(session.data.userId);
@@ -21,5 +26,5 @@ export default defineEventHandler(async (event) => {
name: user.name,
email: user.email,
totpVerified: user.totpVerified,
};
} satisfies SharedPublicUser;
});
+5
View File
@@ -45,6 +45,11 @@ type SharedUserType =
| Pick<UserType, 'id' | 'role'>
| (Pick<UserType, 'id'> & { role: BrandedNumber });
export type SharedPublicUser = Pick<
UserType,
'id' | 'username' | 'name' | 'email' | 'totpVerified'
> & { role: BrandedNumber };
type PermissionCheck<Key extends keyof Permissions> =
| boolean
| ((user: SharedUserType, data: Permissions[Key]['dataType']) => boolean);