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