From 306148e125dbcff2b082d9f438ce555962400bfb Mon Sep 17 00:00:00 2001 From: Aurthur Musendame Date: Sun, 6 Mar 2022 22:39:34 +0200 Subject: [PATCH] fix user auth errors --- frontend/vite/src/auth.ts | 15 +++++++------ frontend/vite/src/axios.ts | 12 +++++----- frontend/vite/src/guards/actions.ts | 7 ++++-- frontend/vite/src/guards/pages.ts | 7 ++++-- frontend/vite/src/modules/alert_toast.ts | 22 +++++++++++++++++-- frontend/vite/src/modules/result_mutation.ts | 3 --- frontend/vite/src/router/index.ts | 5 +++-- frontend/vite/src/store/actions.ts | 16 +++++++++++--- frontend/vite/src/store/mutations.ts | 15 ++++++++++++- frontend/vite/src/utils.ts | 6 ++--- .../vite/src/views/admin/users/Groups.vue | 19 +++++----------- frontend/vite/src/views/sample/SamplesAdd.vue | 2 +- frontend/vite/vite.config.js | 2 +- 13 files changed, 84 insertions(+), 47 deletions(-) diff --git a/frontend/vite/src/auth.ts b/frontend/vite/src/auth.ts index d06c8784..61692108 100644 --- a/frontend/vite/src/auth.ts +++ b/frontend/vite/src/auth.ts @@ -3,19 +3,19 @@ import { IUser } from "./models/auth"; import { decrypter, encrypter } from "./utils" -const authToStorage = (data: any) => { - const crypted = encrypter(data, ENCRYPT_AUTH_KEY) - localStorage.setItem(STORAGE_AUTH_KEY, crypted); +const authToStorage = async (data: any) => { + const crypted = await encrypter(data, ENCRYPT_AUTH_KEY) + await localStorage.setItem(STORAGE_AUTH_KEY, crypted); } -const authFromStorage = (): { +const authFromStorage = async (): Promise<{ token?: string, tokenType?: string, user?: IUser -} => { - const data = decrypter(localStorage.getItem(STORAGE_AUTH_KEY), ENCRYPT_AUTH_KEY); +}> => { + const data = await decrypter(localStorage.getItem(STORAGE_AUTH_KEY), ENCRYPT_AUTH_KEY); if(USER_GROUP_OVERRIDE.length > 0) { - data?.user?.groups?.forEach(group => { + await data?.user?.groups?.forEach(group => { group.name = USER_GROUP_OVERRIDE }) } @@ -23,6 +23,7 @@ const authFromStorage = (): { } const authLogout = () => { + localStorage.removeItem(STORAGE_AUTH_KEY); } diff --git a/frontend/vite/src/axios.ts b/frontend/vite/src/axios.ts index 7d7b9758..756f9014 100644 --- a/frontend/vite/src/axios.ts +++ b/frontend/vite/src/axios.ts @@ -3,17 +3,17 @@ import { authFromStorage, authLogout } from './auth'; import { REST_BASE_URL } from './conf' -const getAuthHeaders = () => { - const token = authFromStorage()?.token; - if (token) { +const getAuthHeaders = async () => { + const auth = await authFromStorage(); + if (auth?.token) { return { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'GET, POST, PATCH, PUT, DELETE, OPTIONS', 'Access-Control-Allow-Headers': 'Origin, Content-Type, X-Auth-Token', - ...(token && { + ...(auth?.token && { 'x-felicity-user-id': "felicity-user", 'x-felicity-role': "felicity-administrator", - 'Authorization': `Bearer ${token}` + 'Authorization': `Bearer ${auth?.token}` }), } } @@ -24,7 +24,7 @@ const getAuthHeaders = () => { const axiosInstance = axios.create({ baseURL: REST_BASE_URL + "/api/v1/", timeout: 1000, - headers: getAuthHeaders() + headers: await getAuthHeaders() }) export default axiosInstance \ No newline at end of file diff --git a/frontend/vite/src/guards/actions.ts b/frontend/vite/src/guards/actions.ts index d794604e..5482840e 100644 --- a/frontend/vite/src/guards/actions.ts +++ b/frontend/vite/src/guards/actions.ts @@ -1,10 +1,13 @@ import { authFromStorage } from "../auth"; import { IGroup } from "../models/auth"; -function hasRights(action: string, objectName: string) { +async function hasRights(action: string, objectName: string) { - const auth = authFromStorage(); + const auth = await authFromStorage(); const groups = auth?.user?.groups + + if(!groups || groups?.length == 0 ) return false + const group = groups![0] as IGroup if (group) { diff --git a/frontend/vite/src/guards/pages.ts b/frontend/vite/src/guards/pages.ts index 0c5b5990..a6c58c94 100644 --- a/frontend/vite/src/guards/pages.ts +++ b/frontend/vite/src/guards/pages.ts @@ -1,9 +1,12 @@ import { authFromStorage } from "../auth"; import { IGroup } from "../models/auth"; -function canAccessPage(pageName: string) { - const auth = authFromStorage(); +async function canAccessPage(pageName: string) { + const auth = await authFromStorage(); const groups = auth?.user?.groups + + if(!groups || groups?.length == 0 ) return false + const group = groups![0] as IGroup; if (group) { diff --git a/frontend/vite/src/modules/alert_toast.ts b/frontend/vite/src/modules/alert_toast.ts index 6392c707..2336cae5 100644 --- a/frontend/vite/src/modules/alert_toast.ts +++ b/frontend/vite/src/modules/alert_toast.ts @@ -1,6 +1,8 @@ import Swal from 'sweetalert2'; import JSConfetti from 'js-confetti' import { Notyf } from 'notyf'; +import { useMutation } from '@urql/vue'; +import { useStore } from 'vuex'; const jsConfetti = new JSConfetti(); @@ -95,11 +97,28 @@ export default function useNotifyToast(){ return gqlOpertionalErrorHandler(gqlResponseHandler(res)) } + // --- exerimental + // example GQLMutation( + // ADD_ANALYSIS_REQUEST, + // {uid:10, ...}, + // SampleActionTypes.ADD_ANALYSIS_REQUEST, + // 'createAnalysisRequest' + // ) + function GQLMutation(query, payload, dispatch, dataKey) { + const store = useStore(); + const { executeMutation: mutator } = useMutation(query); + mutator(payload).then((result) => { + const data = gqlResponseHandler(result) + if(data) store.dispatch(dispatch, data[dataKey]); + }); + } + // -- return { toastSuccess, toastInfo, toastWarning, toastError, swalSuccess, swalInfo, swalWarning, swalError, - gqlResponseHandler, gqlErrorHandler, gqlOpertionalErrorHandler, gqlAllErrorHandler + gqlResponseHandler, gqlErrorHandler, gqlOpertionalErrorHandler, gqlAllErrorHandler, + GQLMutation } } @@ -107,4 +126,3 @@ export default function useNotifyToast(){ - diff --git a/frontend/vite/src/modules/result_mutation.ts b/frontend/vite/src/modules/result_mutation.ts index b18bc968..958b369e 100644 --- a/frontend/vite/src/modules/result_mutation.ts +++ b/frontend/vite/src/modules/result_mutation.ts @@ -1,9 +1,6 @@ -import { useStore } from "vuex" import useNotifyToast from "./alert_toast"; import { IAnalysisResult } from "../models/analysis"; -const store = useStore(); - const { toastWarning } = useNotifyToast(); export default function useResultMutationComposable(){ diff --git a/frontend/vite/src/router/index.ts b/frontend/vite/src/router/index.ts index 082627a9..ec401614 100644 --- a/frontend/vite/src/router/index.ts +++ b/frontend/vite/src/router/index.ts @@ -38,7 +38,7 @@ import NotAuthorised from '../views/Restricted.vue'; import { isTokenValid } from './checks'; import { authFromStorage } from '../auth'; -const auth = authFromStorage(); + const routes: RouteRecordRaw[] = [ @@ -343,7 +343,8 @@ const router = createRouter({ routes, }); -router.beforeEach((to, from, next) => { +router.beforeEach(async (to, from, next) => { + const auth = await authFromStorage(); if(to.path === '/') { next({ name: guards.pages.DASHBOARD }); diff --git a/frontend/vite/src/store/actions.ts b/frontend/vite/src/store/actions.ts index be798792..3c04cb13 100644 --- a/frontend/vite/src/store/actions.ts +++ b/frontend/vite/src/store/actions.ts @@ -19,6 +19,8 @@ export enum ActionTypes { FETCH_GROUPS_AND_PERMISSIONS = 'FETCH_GROUPS_AND_PERMISSIONS', FETCH_USERS = 'FETCH_USERS', UPDATE_GROUPS_PERMISSIONS = 'UPDATE_GROUPS_PERMISSIONS', + ADD_GROUP = 'ADD_GROUP', + UPDATE_GROUP = 'UPDATE_GROUP', FETCH_AUDIT_LOGS = 'FETCH_AUDIT_LOGS', RESET_AUDIT_LOGS = 'RESET_AUDIT_LOGS', @@ -43,12 +45,12 @@ export const actions = >{ // Auth async [ActionTypes.PERSIST_AUTH_DATA]({ commit }, payload) { const authData = payload.data.authenticateUser; - authToStorage(authData) - await commit(MutationTypes.PERSIST_AUTH_DATA, authData); + await authToStorage(authData) + return await commit(MutationTypes.PERSIST_AUTH_DATA, authData); }, async [ActionTypes.PERSIST_AUTH_FROM_LOCAL_STORAGE]({ commit }) { - const authData = authFromStorage() + const authData = await authFromStorage() await commit(MutationTypes.PERSIST_AUTH_DATA, authData); }, @@ -64,6 +66,14 @@ export const actions = >{ .then(payload => commit(MutationTypes.SET_GROUPS_AND_PERMISSIONS, payload.data.value)); }, + async [ActionTypes.ADD_GROUP]({ commit }, payload) { + commit(MutationTypes.ADD_GROUP, payload); + }, + + async [ActionTypes.UPDATE_GROUP]({ commit }, payload) { + commit(MutationTypes.UPDATE_GROUP, payload); + }, + async [ActionTypes.UPDATE_GROUPS_PERMISSIONS]({ commit }, payload) { commit(MutationTypes.UPDATE_GROUPS_PERMISSIONS, payload.data.updateGroupsAndPermissions); }, diff --git a/frontend/vite/src/store/mutations.ts b/frontend/vite/src/store/mutations.ts index 4fc647c2..160ed9fa 100644 --- a/frontend/vite/src/store/mutations.ts +++ b/frontend/vite/src/store/mutations.ts @@ -1,4 +1,5 @@ import { MutationTree } from 'vuex'; +import { IGroup } from '../models/auth'; import { IState, initialState } from './state'; export enum MutationTypes { @@ -8,6 +9,8 @@ export enum MutationTypes { SET_GROUPS_AND_PERMISSIONS = 'SET_GROUPS_AND_PERMISSIONS', UPDATE_GROUPS_PERMISSIONS = 'UPDATE_GROUPS_PERMISSIONS', + ADD_GROUP = 'ADD_GROUP', + UPDATE_GROUP = 'UPDATE_GROUP', RESET_AUDIT_LOGS = 'RESET_AUDIT_LOGS', SET_AUDIT_LOGS = 'SET_AUDIT_LOGS', @@ -22,11 +25,12 @@ export const mutations = >{ Object.assign(state, initialState()); }, - [MutationTypes.PERSIST_AUTH_DATA](state: IState, authData): void { + async [MutationTypes.PERSIST_AUTH_DATA](state: IState, authData) { state.auth = authData.user; state.token = authData.token; state.isAuthenticated = true; if(state.auth) state.auth.role = authData.user.groups[0]?.name; + return authData }, [MutationTypes.SET_USERS](state: IState, payload): void { @@ -38,6 +42,15 @@ export const mutations = >{ state.permissions = payload?.permissionAll; }, + [MutationTypes.ADD_GROUP](state: IState, payload): void { + state.groups?.push(payload) + }, + + [MutationTypes.UPDATE_GROUP](state: IState, payload: IGroup): void { + const index = state.groups?.findIndex(g => g.uid === payload?.uid); + if(index > -1) state!.groups[index] = payload; + }, + [MutationTypes.UPDATE_GROUPS_PERMISSIONS](state: IState, payload): void { let group = payload?.group; const index = state.groups?.findIndex(g => g.uid === group?.uid); diff --git a/frontend/vite/src/utils.ts b/frontend/vite/src/utils.ts index 43539944..99881f7e 100644 --- a/frontend/vite/src/utils.ts +++ b/frontend/vite/src/utils.ts @@ -2,10 +2,10 @@ import moment from 'moment'; import CryptoJs from 'crypto-js'; // https://www.aesencryptiononline.com/ to decrypto online -export const encrypter = (data: any, key: string) => CryptoJs.AES.encrypt(JSON.stringify(data), key).toString() -export const decrypter = (data: any, key: string) => { +export const encrypter = async (data: any, key: string) => await CryptoJs.AES.encrypt(JSON.stringify(data), key).toString() +export const decrypter = async (data: any, key: string) => { if(!data) return {} - return JSON.parse(CryptoJs.AES.decrypt(data, key).toString(CryptoJs.enc.Utf8)) + return await JSON.parse(CryptoJs.AES.decrypt(data, key).toString(CryptoJs.enc.Utf8)) } export const parseDate = function(str: any) { diff --git a/frontend/vite/src/views/admin/users/Groups.vue b/frontend/vite/src/views/admin/users/Groups.vue index 31f90892..9df160a2 100644 --- a/frontend/vite/src/views/admin/users/Groups.vue +++ b/frontend/vite/src/views/admin/users/Groups.vue @@ -16,7 +16,7 @@
  • Pages:

    - {{ item?.toLowerCase() }} + {{ item?.toLowerCase() }}
    @@ -237,15 +237,12 @@ const formAction = ref(true); let userGroup = reactive({}) as IGroup; - function selectGroup(group: IGroup): void { const pgs = group.pages as string; Object.assign(userGroup, { ...group, pages: pgs?.split(",") || [], }) - console.log(userGroup?.permissions) - console.log(permissions.value) permissions.value?.forEach(item => { item[1].forEach((perm: IPermission) => { perm.checked = false; @@ -279,7 +276,7 @@ if (formAction.value === true) { createGroup({ payload }).then((result) => { - store.dispatch(ActionTypes.UPDATE_GROUPS_PERMISSIONS, result); + store.dispatch(ActionTypes.ADD_GROUP, result?.data?.createGroup); }); }; if (formAction.value === false) { @@ -287,7 +284,7 @@ name: payload["name"], pages: payload["pages"], } }).then((result) => { - store.dispatch(ActionTypes.UPDATE_GROUPS_PERMISSIONS, result); + store.dispatch(ActionTypes.UPDATE_GROUP, result?.data?.updateGroup); }); }; showModal.value = false; @@ -306,15 +303,9 @@ const { executeMutation: updateGroupPermissions } = useMutation(UPDATE_GROUP_PERMS); function updateGroupPerms(group: IGroup, permission: IPermission): void { - console.log(group.name, permission.action,permission.target) updateGroupPermissions({ groupUid: group?.uid, permissionUid: permission?.uid }).then((result) => { - store.dispatch(ActionTypes.UPDATE_GROUPS_PERMISSIONS, result); + store.dispatch(ActionTypes.UPDATE_GROUP, result?.data?.updateGroupPermissions); }); } - function belongsToGroup(group: IGroup, permission: IPermission): boolean { - return group?.permissions!.some(perm => perm?.uid === permission?.uid); - } - - \ No newline at end of file diff --git a/frontend/vite/src/views/sample/SamplesAdd.vue b/frontend/vite/src/views/sample/SamplesAdd.vue index 86a945b8..01de6e43 100644 --- a/frontend/vite/src/views/sample/SamplesAdd.vue +++ b/frontend/vite/src/views/sample/SamplesAdd.vue @@ -254,7 +254,7 @@ initialValues: { priority: 0, samples: [], - } + }, }); const { value: clientRequestId } = useField('clientRequestId'); diff --git a/frontend/vite/vite.config.js b/frontend/vite/vite.config.js index 96bb02ed..c0b57b50 100644 --- a/frontend/vite/vite.config.js +++ b/frontend/vite/vite.config.js @@ -1,5 +1,5 @@ import vue from '@vitejs/plugin-vue' export default { - plugins: [vue()] + plugins: [vue()], } \ No newline at end of file