mirror of
https://github.com/beak-insights/felicity-lims.git
synced 2025-02-22 16:03:00 +08:00
fix user auth errors
This commit is contained in:
parent
4d5a53a029
commit
306148e125
13 changed files with 84 additions and 47 deletions
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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(){
|
|||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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(){
|
||||
|
|
|
@ -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 });
|
||||
|
|
|
@ -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 = <ActionTree<IState, RootState>>{
|
|||
// 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 = <ActionTree<IState, RootState>>{
|
|||
.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);
|
||||
},
|
||||
|
|
|
@ -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 = <MutationTree<IState>>{
|
|||
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 = <MutationTree<IState>>{
|
|||
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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
<ul>
|
||||
<li
|
||||
v-for="group in groups"
|
||||
:key="group.uid"
|
||||
:key="group?.uid"
|
||||
href="#"
|
||||
@click.prevent.stop="selectGroup(group)"
|
||||
:class="[
|
||||
|
@ -45,7 +45,7 @@
|
|||
<hr>
|
||||
<div div class="flex justify-start mt-2">
|
||||
<h3 class="mr-2 text-gray-600 font-semibold">Pages: </h3>
|
||||
<span v-for="item in userGroup.pages" class="mr-2">{{ item?.toLowerCase() }} </span>
|
||||
<span v-for="item in userGroup?.pages" class="mr-2">{{ item?.toLowerCase() }} </span>
|
||||
</div>
|
||||
</section>
|
||||
<div>
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
</script>
|
|
@ -254,7 +254,7 @@
|
|||
initialValues: {
|
||||
priority: 0,
|
||||
samples: [],
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
const { value: clientRequestId } = useField('clientRequestId');
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import vue from '@vitejs/plugin-vue'
|
||||
|
||||
export default {
|
||||
plugins: [vue()]
|
||||
plugins: [vue()],
|
||||
}
|
Loading…
Reference in a new issue