From b0c310620ec78df5434eb8e46551c80889b3a086 Mon Sep 17 00:00:00 2001 From: TripleThreads Date: Mon, 24 Aug 2020 16:25:39 +0300 Subject: [PATCH] add authentication on navigation a.k.a navigation guards --- covid-19-app-web/src/auth/login-checker.js | 40 ++++++---- .../src/components/core/AppBar.vue | 19 ++++- covid-19-app-web/src/router/admin.js | 60 +++++++++++++-- covid-19-app-web/src/router/index.js | 5 +- covid-19-app-web/src/router/user-routes.js | 74 ++++++++++++++++--- .../src/views-admin/auth/Login.vue | 16 ++-- covid-19-app-web/src/views/Auth/Login.vue | 13 +++- 7 files changed, 175 insertions(+), 52 deletions(-) diff --git a/covid-19-app-web/src/auth/login-checker.js b/covid-19-app-web/src/auth/login-checker.js index 03e8cd50..98be2383 100644 --- a/covid-19-app-web/src/auth/login-checker.js +++ b/covid-19-app-web/src/auth/login-checker.js @@ -1,24 +1,32 @@ import store from "@/store/"; -import router from "../router"; /* * this file handles an authentication that we need to check before a route executes * */ -export const ifNotAuthenticated = (to, from, next) => { - store.dispatch("resetMessage").then(); - if (store.getters.getToken === null) { - next(); - return; // return if not authenticated - } - router.push({ name: "Login" }); -}; -export const ifAuthenticated = (to, from, next) => { - store.dispatch("resetMessage").then(); - if (store.getters.getToken !== null) { +export function checkRole(to, from, next) { + if (to.matched.some(record => record.meta.requiresAuth)) { + if (store.getters.getToken === null) { + next({ + path: `${store.getters.getLanguagePreference}/login`, + query: { nextUrl: to.fullPath } + }); + } else { + if ( + to.matched.some( + record => + record.meta.roles && + record.meta.roles.includes(store.getters.getUser.role) + ) + ) { + next(); + } else { + next({ + path: `${store.getters.getLanguagePreference}/404` + }); + } + } + } else { next(); - return; } - console.log(true); - router.push(`${store.getters.getLanguagePreference}/login`); -}; +} diff --git a/covid-19-app-web/src/components/core/AppBar.vue b/covid-19-app-web/src/components/core/AppBar.vue index 4564fd1f..60441670 100644 --- a/covid-19-app-web/src/components/core/AppBar.vue +++ b/covid-19-app-web/src/components/core/AppBar.vue @@ -195,10 +195,21 @@ style="border-radius: 20px 0 0 0" class="px-3 overflow-hidden" > - - {{ $t(item.text) }} - {{ item.icon }} - + diff --git a/covid-19-app-web/src/router/admin.js b/covid-19-app-web/src/router/admin.js index f3b8863a..64e88d57 100644 --- a/covid-19-app-web/src/router/admin.js +++ b/covid-19-app-web/src/router/admin.js @@ -11,24 +11,70 @@ const SymptomDetails = () => import("../views-admin/symptoms/SymptomDetails.vue"); export const admin = [ - { name: "AdminLogin", path: "login", component: Login }, - { name: "CreateAccount", path: "register", component: CreateAccount }, + { + name: "AdminLogin", + path: "login", + component: Login, + meta: { + guest: true + } + }, + { + name: "CreateAccount", + path: "register", + component: CreateAccount, + meta: { + guest: true + } + }, { name: "ChangePassword", path: "change-password", - component: ChangePassword + component: ChangePassword, + meta: { + requiresAuth: true, + roles: ["ephi_user"] + } }, { name: "ResetPassword", path: "reset-password", - component: ForgotPassword + component: ForgotPassword, + meta: { + requiresAuth: true, + roles: ["ephi_user"] + } + }, + { + name: "Symptoms", + path: "symptoms", + component: Symptoms, + meta: { + requiresAuth: true, + roles: ["ephi_user"] + } + }, + { + name: "InviteAdmin", + path: "invite-admin", + component: InviteAdmin, + meta: { + requiresAuth: true, + roles: ["ephi_user"] + } }, - { name: "Symptoms", path: "symptoms", component: Symptoms }, - { name: "InviteAdmin", path: "invite-admin", component: InviteAdmin }, { name: "SymptomDetails", path: "symptoms/:id/details", component: SymptomDetails }, - { name: "Dashboard", path: "/", component: Dashboard } + { + name: "Dashboard", + path: "/", + component: Dashboard, + meta: { + requiresAuth: true, + roles: ["ephi_user"] + } + } ]; diff --git a/covid-19-app-web/src/router/index.js b/covid-19-app-web/src/router/index.js index 3990c268..6f78f7e5 100644 --- a/covid-19-app-web/src/router/index.js +++ b/covid-19-app-web/src/router/index.js @@ -4,6 +4,7 @@ import store from "@/store/"; import { languages } from "@/plugins/i18n"; import { admin } from "./admin"; import { userRoutes } from "./user-routes"; +import { checkRole } from "../auth/login-checker"; Vue.use(VueRouter); @@ -50,5 +51,7 @@ const router = new VueRouter({ mode: "history", routes }); -console.log(router); + +router.beforeEach(checkRole); + export default router; diff --git a/covid-19-app-web/src/router/user-routes.js b/covid-19-app-web/src/router/user-routes.js index b95ca268..5f9e8f68 100644 --- a/covid-19-app-web/src/router/user-routes.js +++ b/covid-19-app-web/src/router/user-routes.js @@ -1,5 +1,3 @@ -import { ifAuthenticated, ifNotAuthenticated } from "../auth/login-checker"; - const NotFound = () => import("@/views/Errors/404.vue"); const Home = () => import("@/views/Home/Home.vue"); const Information = () => import("@/views/Information/Information.vue"); @@ -13,34 +11,86 @@ const Login = () => import("@/views/Auth/Login.vue"); const Register = () => import("@/views/Auth/Register.vue"); export const userRoutes = [ - { path: "information", name: "Learn", component: Information }, + { + path: "information", + name: "Learn", + component: Information, + meta: { + guest: true + } + }, { path: "privacy-policy", name: "PrivacyPolicy", - component: PrivacyPolicy + component: PrivacyPolicy, + meta: { + guest: true + } }, { path: "references", name: "References", component: References }, { path: "profile", name: "Profile", component: Profile, - beforeEnter: ifAuthenticated + meta: { + requiresAuth: true, + roles: ["ephi_user", "basic"] + } }, { path: "register", name: "Register", component: Register, - beforeEnter: ifNotAuthenticated + meta: { + guest: true + } }, { path: "login", name: "Login", component: Login, - beforeEnter: ifNotAuthenticated + meta: { + guest: true + } + }, + { + path: "about", + name: "About", + component: About, + meta: { + guest: true + } + }, + { + path: "news", + name: "News", + component: News, + meta: { + guest: true + } + }, + { + path: "map", + name: "Map", + component: HeatMap, + meta: { + guest: true + } }, - { path: "about", name: "About", component: About }, - { path: "news", name: "News", component: News }, - { path: "map", name: "Map", component: HeatMap }, - { path: "", name: "Home", component: Home }, - { path: "*", name: "404", component: NotFound } + { + path: "", + name: "Home", + component: Home, + meta: { + guest: true + } + }, + { + path: "*", + name: "404", + component: NotFound, + meta: { + notFound: true + } + } ]; diff --git a/covid-19-app-web/src/views-admin/auth/Login.vue b/covid-19-app-web/src/views-admin/auth/Login.vue index f511f82f..a38502b4 100644 --- a/covid-19-app-web/src/views-admin/auth/Login.vue +++ b/covid-19-app-web/src/views-admin/auth/Login.vue @@ -57,14 +57,6 @@ > {{ $t("auth.login") }} - - {{ $t("auth.goToSignUp") }} - @@ -105,9 +97,13 @@ export default { store.dispatch("setUser", { user: res.data.user }); store.dispatch("setToken", { token: res.data.token }); store.dispatch("setStateMessage", "Successfully logged in"); - if (res.data.user.role === "ephi_user") + if (this.$route.query.nextUrl !== null) { + this.$router.push(this.$route.query.nextUrl); + } else if (res.data.user.role === "ephi_user") { this.$router.push({ name: "Dashboard" }); - else this.$router.push({ name: "Home" }); + } else { + this.$router.push({ name: "Home" }); + } }, error => { store.dispatch("setStateMessage", error.response.data); diff --git a/covid-19-app-web/src/views/Auth/Login.vue b/covid-19-app-web/src/views/Auth/Login.vue index a0d20f29..7c020f7e 100644 --- a/covid-19-app-web/src/views/Auth/Login.vue +++ b/covid-19-app-web/src/views/Auth/Login.vue @@ -85,9 +85,14 @@ export default { rules: Rules }; }, + created() { + console.log(this.$route.query.nextUrl); + }, methods: { submit() { this.loading = true; + let query = this.$route.query; + console.log(query); ajax .post("auth/login", this.user) .then( @@ -95,9 +100,13 @@ export default { store.dispatch("setUser", { user: res.data.user }); store.dispatch("setToken", { token: res.data.token }); store.dispatch("setStateMessage", "Successfully logged in"); - if (res.data.user.role === "ephi_user") + if (query.nextUrl) { + this.$router.push(query.nextUrl); + } else if (res.data.user.role === "ephi_user") { this.$router.push({ name: "Dashboard" }); - else this.$router.push({ name: "Home" }); + } else { + this.$router.push({ name: "Home" }); + } }, error => { store.dispatch("setStateMessage", error.response.data);