diff --git a/server/src/classes/User.js b/server/src/classes/User.js index 867431d..7b228b1 100755 --- a/server/src/classes/User.js +++ b/server/src/classes/User.js @@ -1,4 +1,4 @@ -import { addSeconds, differenceInSeconds } from 'date-fns' +import { addSeconds, differenceInSeconds, addHours } from 'date-fns' import { ad } from '../lib/activeDirectory' import prisma from '../prisma' import { Change, createClient } from 'ldapjs' @@ -330,7 +330,6 @@ class User { const jwtSecret = process.env.JWT_SECRET || 'a good secret' - // TODO: Add date-fns to calculate expiration const options = { expiresIn: process.env.JWT_EXPIRATION || '72h' } const token = jwt.sign(payload, jwtSecret, options) @@ -338,7 +337,8 @@ class User { return { user, token, - expiresIn: options.expiresIn + expiresIn: options.expiresIn, + expiresOn: addHours } } catch (e) { throw new Error( diff --git a/server/src/lib/activeDirectory/index.js b/server/src/lib/activeDirectory/index.js index 69709c6..5b22c54 100755 --- a/server/src/lib/activeDirectory/index.js +++ b/server/src/lib/activeDirectory/index.js @@ -1,7 +1,6 @@ import { promiseWrapper as AD } from 'activedirectory2' import config from './config' -// TODO: Refactor to instantiate in context creation function const ad = new AD(config) ad.checkBinding = async () => { diff --git a/web/src/plugins/vue-apollo.js b/web/src/plugins/vue-apollo.js index 55d9d2a..6c9aff9 100755 --- a/web/src/plugins/vue-apollo.js +++ b/web/src/plugins/vue-apollo.js @@ -138,7 +138,7 @@ export async function getLoggedUser() { }) return result.data.me } catch (e) { - console.log('Erro ao recuperar informações do usuário: ', e) + console.error('Erro ao recuperar informações do usuário: ', e) return null } diff --git a/web/src/router/index.js b/web/src/router/index.js index 112e5cb..d65031a 100755 --- a/web/src/router/index.js +++ b/web/src/router/index.js @@ -6,17 +6,20 @@ import { getLoggedUser } from '../plugins/vue-apollo' Vue.use(VueRouter) +/* + Roles matching: + If a route has no meta.roles property it's considered public + If a route has a empty meta.roles array, only auth is required + And if meta.roles has items, user.roles should satisfy it. +*/ + const routes = [ { path: '/', name: 'home', component: Home, meta: { - noAuth: false, - superAdmin: false, - tokenCreator: false, - servant: false, - student: false, + roles: [], title: null } }, @@ -24,7 +27,6 @@ const routes = [ path: '/about', name: 'about', meta: { - noAuth: true, title: 'Sobre' }, // route level code-splitting @@ -37,7 +39,6 @@ const routes = [ path: '/login', name: 'login', meta: { - noAuth: true, layout: 'Simple', title: 'Login' }, @@ -48,7 +49,8 @@ const routes = [ path: '/update-password', name: 'update-password', meta: { - title: 'Atualizar minha senha' + title: 'Atualizar minha senha', + roles: [] }, component: () => import( @@ -60,7 +62,7 @@ const routes = [ name: 'user-info', meta: { title: 'Inspecionar usuário', - superAdmin: true + roles: ['superAdmin'] }, component: () => import(/* webpackChunkName: "user-info" */ '../views/UserInfo.vue') @@ -70,7 +72,8 @@ const routes = [ name: 'replace-password', meta: { title: 'Redefinir uma senha', - superAdmin: true + + roles: ['superAdmin'] }, component: () => import( @@ -81,7 +84,8 @@ const routes = [ path: '/my-devices', name: 'my-devices', meta: { - title: 'Meus dispositivos' + title: 'Meus dispositivos', + roles: [] }, component: () => import(/* webpackChunkName: "my-devices" */ '../views/MyDevices.vue') @@ -90,8 +94,8 @@ const routes = [ path: '/create-token', name: 'create-token', meta: { - tokenCreator: true, - title: 'Criar um token' + title: 'Criar um token', + roles: ['tokenCreator'] }, component: () => import(/* webpackChunkName: "create-token" */ '../views/CreateToken.vue') @@ -100,7 +104,6 @@ const routes = [ path: '/use-token', name: 'use-token', meta: { - noAuth: true, layout: 'Simple', title: 'Token' }, @@ -114,7 +117,7 @@ const routes = [ meta: { layout: 'Simple', title: 'Imprimir token', - tokenCreator: true + roles: ['tokenCreator'] }, component: () => import(/* webpackChunkName: "print-token" */ '../views/PrintToken.vue') @@ -125,7 +128,7 @@ const routes = [ name: 'user-id', meta: { title: 'Crachá', - servant: true + roles: ['servant'] }, component: () => import(/* webpackChunkName: "user-id" */ '../views/UserId.vue') @@ -147,7 +150,7 @@ const routes = [ name: 'user-presence', meta: { title: 'No campus agora', - watcher: true + roles: ['watcher'] }, component: () => import( @@ -160,7 +163,7 @@ const routes = [ name: 'wifi-devices', meta: { title: 'Dispositivos Wi-Fi', - superAdmin: true + roles: ['superAdmin'] }, component: () => import(/* webpackChunkName: "wifi-devices" */ '../views/WifiDevices.vue') @@ -171,7 +174,7 @@ const routes = [ name: 'wifi-users', meta: { title: 'Usuários Wi-Fi', - superAdmin: true + roles: ['superAdmin'] }, component: () => import(/* webpackChunkName: "wifi-users" */ '../views/WifiUsers.vue') @@ -182,7 +185,7 @@ const routes = [ name: 'system-administration', meta: { title: 'Administração do sistema', - superAdmin: true + roles: ['superAdmin'] }, component: () => import( @@ -212,46 +215,31 @@ function updateTitle(title) { router.beforeEach(async (to, from, next) => { updateTitle(to.meta.title) - const loggedUser = await getLoggedUser() - if (loggedUser && to.matched.some(record => record.name === 'login')) - next({ name: 'home' }) - else { - if (to.matched.some(record => record.meta.noAuth)) next() - else { - if (!loggedUser) - next({ - name: 'login', - params: { - next: to.fullPath, - message: 'Você precisa fazer login para entrar nesta página.' - } - }) - else { - //TODO: improve user authorization - const doNotHaveAuthorization = - (to.matched.some(record => record.meta.superAdmin) && - !loggedUser.isSuperAdmin) || - (to.matched.some(record => record.meta.tokenCreator) && - !loggedUser.isTokenCreator) || - (to.matched.some(record => record.meta.servant) && - !loggedUser.isServant) || - (to.matched.some(record => record.meta.student) && - !loggedUser.isStudent) || - (to.matched.some(record => record.meta.watcher) && - !loggedUser.isWatcher) + const auth = await getLoggedUser() - if (doNotHaveAuthorization) - next({ - name: 'home', - params: { - message: 'Você não tem permissão para entrar nessa página.' - } - }) - else next() + if (auth && to.name === 'login') next({ name: 'home' }) + else if (!('roles' in to.meta)) next() + else if (!auth) + next({ + name: 'login', + params: { + next: to.fullPath, + message: 'Você precisa fazer login para entrar nesta página.' } - } - } + }) + else if ( + !to.meta.roles.length || + to.meta.roles.some(role => auth.roles.includes(role)) + ) + next() + else + next({ + name: 'home', + params: { + message: 'Você não tem permissão para entrar na página solicitada.' + } + }) }) export default router