diff --git a/src/components/Sidebar.vue b/src/components/Sidebar.vue
index 456012f..c5aa259 100644
--- a/src/components/Sidebar.vue
+++ b/src/components/Sidebar.vue
@@ -3,9 +3,18 @@
import { useAuthStore } from '../stores/auth';
import Swal from 'sweetalert2';
import { useI18n } from 'vue-i18n';
+ import { useCompanyStore } from '../stores/company';
+ import { useVehiclesStore } from '../stores/vehicles';
+ import { useLoadsStore } from '../stores/loads';
+ import { useNotificationsStore } from '../stores/notifications';
const route = useRoute();
const auth = useAuthStore();
+ const company = useCompanyStore();
+ const vehicles = useVehiclesStore();
+ const loads = useLoadsStore();
+ const noty = useNotificationsStore();
+ const router = useRouter();
const { t } = useI18n()
const handleLogout = () => {
@@ -20,6 +29,11 @@
}).then(async(result) => {
if(result.isConfirmed) {
auth.logout();
+ company.clear();
+ vehicles.clear();
+ loads.clear();
+ noty.clear();
+ router.push({name: 'login'});
}
});
}
diff --git a/src/main.js b/src/main.js
index c934a84..0672e2c 100644
--- a/src/main.js
+++ b/src/main.js
@@ -6,10 +6,13 @@ import App from './App.vue'
import router from './router'
import i18n from './i18n/i18n'
+const pinia = createPinia();
const app = createApp(App)
-app.use(createPinia())
app.use(router)
+app.use(pinia)
+
app.use(i18n)
+
app.mount('#app')
diff --git a/src/router/index.js b/src/router/index.js
index 4c9bd79..c4a40a0 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -1,6 +1,7 @@
import { createRouter, createWebHistory } from 'vue-router'
import AuthLayout from '../layouts/AuthLayout.vue'
import PublicLayout from '../layouts/PublicLayout.vue'
+import { useAuthStore } from '../stores/auth';
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
@@ -30,6 +31,11 @@ const router = createRouter({
name: 'register-company',
component: () => import('../views/CompleteRegisterView.vue')
},
+ {
+ path: '/:pathMatch(.*)*',
+ name: 'not-found',
+ component: () => import('../views/LoginView.vue'),
+ }
]
},
{
@@ -68,88 +74,121 @@ const router = createRouter({
path: '/dashboard',
name: 'dashboard',
component: () => import('../layouts/AdminLayout.vue'),
- meta: { requiresAuth: true },
+ meta: {
+ requiresAuth: true,
+ roles: ['manager', 'staff', 'owner']
+ },
children: [
{
path: 'inicio',
name: 'home',
+ meta: { permissions: ['role_shipper', 'role_carrier'] },
component: () => import('../views/HomeView.vue'),
},
{
path: 'empresa',
name: 'company',
+ meta: { permissions: ['role_shipper', 'role_carrier'] },
component: () => import('../views/MyCompanyView.vue'),
},
{
path: 'profile',
name: 'profile',
+ meta: { permissions: ['role_shipper', 'role_carrier'] },
component: () => import('../views/EditProfileView.vue'),
},
{
path: 'empresa/:id',
name: 'public-users',
+ meta: { permissions: ['role_shipper', 'role_carrier'] },
component: () => import('../views/PublicUsersCompanyView.vue'),
},
{
path: 'ubicaciones',
name: 'locations',
+ meta: { permissions: ['role_shipper', 'role_carrier'] },
component: () => import('../views/LocationsView.vue'),
},
{
path: 'ofertas',
name: 'published-trucks',
+ meta: { permissions: ['role_carrier'] },
component: () => import('../views/TrucksPublishedView.vue'),
},
{
path: 'usuarios',
name: 'users',
+ meta: { permissions: ['role_shipper', 'role_carrier'] },
component: () => import('../views/UsersView.vue'),
},
{
path: 'calculadora',
name: 'calculator',
+ meta: { permissions: ['role_carrier'] },
component: () => import('../views/CalculatorView.vue'),
},
{
path: 'reportes',
name: 'reports',
+ meta: { permissions: ['role_shipper', 'role_carrier'] },
component: () => import('../views/ReportsView.vue'),
},
{
path: 'calendario',
name: 'calendar',
+ meta: {
+ permissions: ['role_shipper', 'role_carrier'],
+ roles: ['staff', 'manager', 'owner', 'store']
+ },
component: () => import('../views/CalendarView.vue'),
},
{
path: 'cargas',
+ meta: { permissions: ['role_shipper'] },
name: 'published-loads',
component: () => import('../views/LoadsPublishedView.vue'),
},
{
path: 'vehiculos',
name: 'vehicles',
+ meta: { permissions: ['role_carrier'] },
component: () => import('../views/VehiclesView.vue'),
},
{
path: 'transportistas',
name: 'carriers',
+ meta: { permissions: ['role_shipper'] },
component: () => import('../views/CarriersView.vue'),
},
{
path: 'embarcadores',
name: 'shippers',
+ meta: { permissions: ['role_carrier'] },
component: () => import('../views/ShippersView.vue'),
},
{
path: 'buscar-cargas',
name: 'search-loads',
+ meta: { permissions: ['role_carrier'] },
component: () => import('../views/SearchLoadsView.vue'),
},
{
- path: 'buscar-vehiclulos',
+ path: 'buscar-vehiculos',
name: 'search-vehicles',
+ meta: { permissions: ['role_shipper'] },
component: () => import('../views/SearchVehiclesView.vue'),
},
+ {
+ path: '403',
+ name: '403',
+ meta: { permissions: ['role_shipper', 'role_carrier'] },
+ component: () => import('../views/NotFoundView.vue'),
+ },
+ {
+ path: '/:pathMatch(.*)*',
+ name: 'not-found',
+ component: () => import('../views/HomeView.vue'),
+ }
]
}
]
@@ -158,16 +197,63 @@ const router = createRouter({
router.beforeEach( async(to, from, next) => {
const requiresAuth = to.matched.some(url => url.meta.requiresAuth)
if(requiresAuth === true) {
+ const auth = useAuthStore()
const session = localStorage.getItem('session');
- //Comprobamos si el usuario esta authenticado
+ const permissions = to.meta.permissions;
+ const roles = to.meta.roles;
+
if(session) {
+ await auth.checkSession()
+ const permissionUser = auth?.user?.permissions;
+ const role = auth?.user?.job_role;
+ if (!permissionUser) {
+ return next({name: 'login'}); // Redirige al login si no está autenticado
+ }
+
+ if (permissions && !permissions.includes(permissionUser)) {
+ if(role === 'store') { /// Check if user is store
+ return next({name: 'calendar'});
+ } else {
+ return next({name: 'home'});
+ }
+ }
+
+ if(roles && !roles.includes(role)) {
+ return next({name: 'calendar'});
+ }
+
next();
} else {
- next({name: 'login'})
+ return next({name: 'login'})
}
} else {
next();
}
});
+// router.beforeEach( async(to, from, next) => {
+// const requiresAuth = to.matched.some(url => url.meta.requiresAuth)
+// if(requiresAuth === true) {
+// const session = localStorage.getItem('session');
+// const role = localStorage.getItem('user');
+// const permissions = to.meta.permissions;
+// const auth = useAuthStore()
+// //Comprobamos si el usuario esta authenticado
+// if(session) {
+// if (!role) {
+// return next({name: 'login'}); // Redirige al login si no está autenticado
+// }
+
+// if (permissions && !permissions.includes(role)) {
+// return next({name: 'home'}); // Redirige a una página de acceso denegado si no tiene permisos
+// }
+// next();
+// } else {
+// return next({name: 'login'})
+// }
+// } else {
+// next();
+// }
+// });
+
export default router
diff --git a/src/stores/auth.js b/src/stores/auth.js
index 56e1093..95daecb 100644
--- a/src/stores/auth.js
+++ b/src/stores/auth.js
@@ -3,9 +3,7 @@ import { ref, onMounted } from "vue";
import { useRoute, useRouter } from 'vue-router';
import { renewToken } from '../services/auth';
import {useNotificationsStore} from './notifications';
-import {useCompanyStore} from './company';
import { useLoadsStore } from "./loads";
-import { useVehiclesStore } from "./vehicles";
import { updateMyUserProfile } from "../services/company";
export const useAuthStore = defineStore('auth', () => {
@@ -13,16 +11,14 @@ export const useAuthStore = defineStore('auth', () => {
const router = useRouter();
const route = useRoute();
const noty = useNotificationsStore();
- const company = useCompanyStore();
const loadStore = useLoadsStore();
- const vehiclesStore = useVehiclesStore();
- const notyStore = useNotificationsStore();
const sesion = ref('')
const checking = ref(false);
const authStatus = ref('checking');
const token = ref('')
const lang = ref('es');
const user = ref(null);
+ const isAuthenticated = ref(false);
const publicNames = [
'terms-conditions',
'notice-privacy',
@@ -34,15 +30,10 @@ export const useAuthStore = defineStore('auth', () => {
'register-company',
]
- onMounted( async() => {
- checkSession();
- });
-
-
const checkSession = async() => {
const session = localStorage.getItem('session');
authStatus.value = 'checking';
- if(session && !publicNames.includes(route.name)) {
+ if((session && !publicNames.includes(route.name)) && isAuthenticated.value === false && checking.value === false) {
checking.value = true;
const resp = await renewToken();
if(resp.msg === 'success') {
@@ -53,22 +44,24 @@ export const useAuthStore = defineStore('auth', () => {
localStorage.setItem('access', resp.data.accessToken);
localStorage.setItem('id', resp.data.user.company._id);
checking.value = false;
+ isAuthenticated.value = true;
} else {
noty.show = true;
noty.text = 'Sesión ha expirado, ingresa nuevamente';
noty.error = true;
checking.value = false;
+ isAuthenticated.value = false;
router.push({name: 'login'});
}
- }
+ }
authStatus.value = 'completed';
}
- const authenticationPromise = new Promise((resolve) => {
- onMounted(() => {
- resolve('success');
- });
- });
+ // const authenticationPromise = new Promise((resolve) => {
+ // onMounted(() => {
+ // resolve('success');
+ // });
+ // });
const updateProfile = async(data) => {
const response = await updateMyUserProfile(data);
@@ -90,17 +83,7 @@ export const useAuthStore = defineStore('auth', () => {
user.value = null;
checking.value = false;
authStatus.value = 'checking'
- notyStore.notifications = [];
- notyStore.newNoty = false;
- notyStore.show = false;
- notyStore.openNotifications = false;
- notyStore.toggleProfile = false;
-
- company.clear();
loadStore.clear();
- vehiclesStore.clear();
-
- router.push({name: 'login'});
}
return {
@@ -111,8 +94,9 @@ export const useAuthStore = defineStore('auth', () => {
checking,
authStatus,
checkSession,
- authenticationPromise,
+ // authenticationPromise,
updateProfile,
- lang
+ lang,
+ isAuthenticated
}
});
\ No newline at end of file
diff --git a/src/stores/notifications.js b/src/stores/notifications.js
index a190601..d486e21 100644
--- a/src/stores/notifications.js
+++ b/src/stores/notifications.js
@@ -34,6 +34,15 @@ export const useNotificationsStore = defineStore('notifications', () => {
return notifications.value = notifications.value.filter(noty => noty._id !== id);
}
+ const clear = () => {
+ notifications.value = [];
+ newNoty.value = false;
+ show.value = false;
+ openNotifications.value = false;
+ toggleProfile.value = false;
+ }
+
+
return {
text,
@@ -45,6 +54,7 @@ export const useNotificationsStore = defineStore('notifications', () => {
removeNoty,
toggleProfile,
openNotifications,
- toggleNotifications
+ toggleNotifications,
+ clear
}
});
\ No newline at end of file
diff --git a/src/views/CompleteRegisterView.vue b/src/views/CompleteRegisterView.vue
index e7f998f..6c30290 100644
--- a/src/views/CompleteRegisterView.vue
+++ b/src/views/CompleteRegisterView.vue
@@ -98,7 +98,7 @@
localStorage.setItem('id', result.data._id);
localStorage.setItem('session', auth.sesion);
- // localStorage.setItem('access', auth.token);
+ localStorage.setItem('access', auth.accessToken);
const userData = {
"first_name" : user.name,
@@ -109,6 +109,7 @@
let respUser = await updateMyUserProfile( userData );
if(respUser.msg === 'success') {
auth.user = respUser.data;
+ auth.isAuthenticated = true;
} else {
auth.user = userData;
}
diff --git a/src/views/LoginView.vue b/src/views/LoginView.vue
index f60f260..fef0369 100644
--- a/src/views/LoginView.vue
+++ b/src/views/LoginView.vue
@@ -48,6 +48,7 @@
sesion: resp.data.session_token,
token: resp.data.accessToken,
user: resp.data.user,
+ isAuthenticated: true
})
} else { // Completar registro
auth.$patch({
diff --git a/src/views/MyCompanyView.vue b/src/views/MyCompanyView.vue
index 7762bb2..3011154 100644
--- a/src/views/MyCompanyView.vue
+++ b/src/views/MyCompanyView.vue
@@ -27,7 +27,6 @@
})
const getInitialData = async() => {
- await auth.authenticationPromise;
await company.getCompanyData();
}
diff --git a/src/views/NotFoundView.vue b/src/views/NotFoundView.vue
new file mode 100644
index 0000000..b3a9d5a
--- /dev/null
+++ b/src/views/NotFoundView.vue
@@ -0,0 +1,13 @@
+
+
+
No encontrada
+
+
+
+
+
+
\ No newline at end of file