diff --git a/package-lock.json b/package-lock.json index 7e63fe57104ff692f203149b34f440e2cd169539..d8241d9162867c7534eb80fe1a6482c42f63a13c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "dependencies": { "axios": "^1.6.8", "bootstrap": "^5.3.3", + "js-cookie": "^3.0.5", "oh-vue-icons": "^1.0.0-rc3", "pinia": "^2.1.7", "vue": "^3.4.21", @@ -5244,7 +5245,6 @@ "version": "3.0.5", "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz", "integrity": "sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==", - "dev": true, "engines": { "node": ">=14" } diff --git a/package.json b/package.json index 7f62401e3056a470b8fb54afb0fc7f6634551a86..ddb8161ec3e1e08315d7c798156312bcdeda16d3 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "dependencies": { "axios": "^1.6.8", "bootstrap": "^5.3.3", + "js-cookie": "^3.0.5", "oh-vue-icons": "^1.0.0-rc3", "pinia": "^2.1.7", "vue": "^3.4.21", diff --git a/src/router/index.ts b/src/router/index.ts index 98101c6423782c3fa0ebfca00d156b93fac31f5a..5711edbe06862397d7ece8bfce86b3a154412100 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -1,6 +1,7 @@ // Import necessary dependencies from Vue Router and your views import { createRouter, createWebHistory } from 'vue-router'; import LoginView from '../views/Authentication/LoginView.vue'; +import { useUserInfoStore } from '@/stores/UserStore'; const routes = [ { @@ -29,6 +30,17 @@ const routes = [ name: 'test', component: () => import('@/views/TestView.vue'), }, + { + path: 'admin', + name: 'admin', + component: () => import('@/views/TestView.vue'), + meta: { requiresAdmin: true } + }, + { + path: 'unauthorized', + name: 'unauthorized', + component: () => import('@/views/TestView.vue'), + }, ] }, { @@ -51,7 +63,15 @@ const router = createRouter({ }); router.beforeEach((to, from, next) => { + const requiresAuth = to.matched.some(record => record.meta.requiresAuth); + const requiresAdmin = to.matched.some(record => record.meta.requiresAdmin); + const userRole = useUserInfoStore().role; + + if (requiresAdmin && userRole !== 'admin') { + next({ name: 'unauthorized' }); + } else { next(); + } }); export default router; \ No newline at end of file diff --git a/src/stores/UserStore.ts b/src/stores/UserStore.ts new file mode 100644 index 0000000000000000000000000000000000000000..bd1a32d7b5dab2a33b1b73b1df068f9688fd9415 --- /dev/null +++ b/src/stores/UserStore.ts @@ -0,0 +1,74 @@ +import { OpenAPI } from '@/api'; +import Cookies from 'js-cookie'; +import { defineStore } from 'pinia'; + +const cookiesStorage: Storage = { + setItem(key, state) { + return Cookies.set(key, state, { expires: 3 }); + }, + getItem(key) { + const store = Cookies.get(key); + if (store === undefined) { + OpenAPI.TOKEN = ''; + return ''; + } + + OpenAPI.TOKEN = JSON.parse(Cookies.get(key) || '').accessToken; + return Cookies.get(key) || ''; + }, + length: 0, + clear: function (): void { + Cookies.remove('userInfo'); + }, + key: function (index: number): string | null { + throw new Error('Function not implemented.'); + }, + removeItem: function (key: string): void { + throw new Error('Function not implemented.'); + }, +}; + +export type UserStoreInfo = { + username?: string; + firstname?: string; + lastname?: string; + accessToken?: string; + role?: string; +}; + +export const useUserInfoStore = defineStore('UserInfoStore', { + state: () => ({ + username: '', + firstname: '', + lastname: '', + accessToken: '', + role: '', + }), + actions: { + setUserInfo(userinfo: UserStoreInfo) { + userinfo.username && (this.$state.username = userinfo.username); + userinfo.firstname && (this.$state.firstname = userinfo.firstname); + userinfo.lastname && (this.$state.lastname = userinfo.lastname); + userinfo.accessToken && (this.$state.accessToken = userinfo.accessToken); + userinfo.accessToken && (OpenAPI.TOKEN = this.$state.accessToken); + userinfo.role && (this.$state.role = userinfo.role); + }, + clearUserInfo() { + this.$state.username = ''; + this.$state.firstname = ''; + this.$state.lastname = ''; + this.$state.accessToken = ''; + this.$state.role = ''; + OpenAPI.TOKEN = undefined; + }, + }, + getters: { + isLoggedIn(): boolean { + return this.accessToken !== ''; + }, + }, + persist: { + enabled: true, + strategies: [{ key: 'userInfo', storage: cookiesStorage }], + }, +}); \ No newline at end of file