From 4af98fb75bade7a5e93ff35a381b285c16136633 Mon Sep 17 00:00:00 2001 From: Simone Gotti Date: Thu, 26 Sep 2019 10:03:44 +0200 Subject: [PATCH] Redirect to previous url after login --- src/App.vue | 8 - src/main.js | 14 +- src/util/auth.js | 13 ++ src/util/data.js | 537 +++++++++++++++++++++++-------------------- src/views/Login.vue | 20 +- src/views/Oauth2.vue | 15 +- 6 files changed, 332 insertions(+), 275 deletions(-) diff --git a/src/App.vue b/src/App.vue index f5f52a6..fe48af6 100644 --- a/src/App.vue +++ b/src/App.vue @@ -149,14 +149,6 @@ export default { }; }, watch: { - user: function(user) { - if (user) { - this.$router.push({ - name: "user", - params: { username: this.user.username } - }); - } - }, $route: function() { this.userDropdownActive = false; this.createDropdownActive = false; diff --git a/src/main.js b/src/main.js index 17bdaa7..6b89bf4 100644 --- a/src/main.js +++ b/src/main.js @@ -1,26 +1,24 @@ -import '@/css/tailwind.scss' +import "@/css/tailwind.scss"; +import { getUser } from "@/util/auth"; import "@mdi/font/css/materialdesignicons.css"; - import Vue from "vue"; import Vue2Filters from "vue2-filters"; import App from "./App.vue"; import router from "./router"; import store from "./store"; -import { getUser } from "@/util/auth"; - Vue.use(Vue2Filters); // TODO(sgotti) use vuex for login/logout new Vue({ router, store, - created: function () { - let user = getUser() + created: function() { + let user = getUser(); if (user) { - store.dispatch('setUser', user) + store.dispatch("setUser", user); } - store.dispatch("setRegisterUser", null) + store.dispatch("setRegisterUser", null); }, render: h => h(App) }).$mount("#app"); diff --git a/src/util/auth.js b/src/util/auth.js index 55e3b8b..499540c 100644 --- a/src/util/auth.js +++ b/src/util/auth.js @@ -2,6 +2,7 @@ import store from "@/store"; const ID_TOKEN_KEY = 'id_token'; const USER_KEY = 'user'; +const LOGIN_REDIRECT_KEY = 'login_redirect'; let API_URL = window.CONFIG.API_URL; let API_BASE_PATH = window.CONFIG.API_BASE_PATH; @@ -125,3 +126,15 @@ export function isLoggedIn() { const idToken = getIdToken(); return !!idToken; } + +export function getLoginRedirect() { + return sessionStorage.getItem(LOGIN_REDIRECT_KEY); +} + +export function setLoginRedirect(url) { + sessionStorage.setItem(LOGIN_REDIRECT_KEY, url); +} + +export function unsetLoginRedirect() { + return sessionStorage.removeItem(LOGIN_REDIRECT_KEY); +} \ No newline at end of file diff --git a/src/util/data.js b/src/util/data.js index 1bc92a2..2ecaceb 100644 --- a/src/util/data.js +++ b/src/util/data.js @@ -2,361 +2,388 @@ import router from "@/router"; import { apiurl, fetch as authfetch, loginapi, registerapi } from "@/util/auth"; export async function fetch(url, init, signal) { - try { - let res = await authfetch(url, init, signal) - if (!res.ok) { - if (res.status === 401) { - router.push({ name: "login" }) - // if we return a response containing an error what happens is - // that router.push mounts the login view before the calling - // component processed the response and the calling component - // may set the "unauthorized" error as a global error hiding the - // login view. - // So return an empty response so the caller won't set a global - // error (but in the console will appear other errors since also - // data is null) + try { + let res = await authfetch(url, init, signal); + if (!res.ok) { + if (res.status === 401) { + router.push({ + name: "login", + query: { redirect: router.currentRoute.fullPath } + }); + // if we return a response containing an error what happens is + // that router.push mounts the login view before the calling + // component processed the response and the calling component + // may set the "unauthorized" error as a global error hiding the + // login view. + // So return an empty response so the caller won't set a global + // error (but in the console will appear other errors since also + // data is null) - // TODO(sgotti) find a way to make this cleaner. The solution - // could be to find a way to firstly let the component handle - // the error and the do the router push... - return - } - let data = await res.json() - return { data: null, error: data.message } - } else { - if (res.status == 204) { - return { data: null, error: null } - } - return { data: await res.json(), error: null } - } - } catch (e) { - if (e.name == 'AbortError') { - return { data: null, error: null, aborted: true, } - } - return { data: null, error: "api call failed: " + e.message } + // TODO(sgotti) find a way to make this cleaner. The solution + // could be to find a way to firstly let the component handle + // the error and the do the router push... + return; + } + let data = await res.json(); + return { data: null, error: data.message }; + } else { + if (res.status == 204) { + return { data: null, error: null }; + } + return { data: await res.json(), error: null }; } + } catch (e) { + if (e.name == "AbortError") { + return { data: null, error: null, aborted: true }; + } + return { data: null, error: "api call failed: " + e.message }; + } } export async function login(username, password, remotesourcename) { - let init = { - method: "POST", - body: JSON.stringify({ - remote_source_name: remotesourcename, - login_name: username, - password: password - }) - } + let init = { + method: "POST", + body: JSON.stringify({ + remote_source_name: remotesourcename, + login_name: username, + password: password + }) + }; - try { - let res = await loginapi(init) - if (!res.ok) { - let data = await res.json() - return { data: null, error: data.message } - } else { - return { data: await res.json(), error: null } - } - } catch (e) { - return { data: null, error: "api call failed: " + e.message } + try { + let res = await loginapi(init); + if (!res.ok) { + let data = await res.json(); + return { data: null, error: data.message }; + } else { + return { data: await res.json(), error: null }; } + } catch (e) { + return { data: null, error: "api call failed: " + e.message }; + } } -export async function register(username, remotesourcename, remoteloginname, remotepassword) { - let init = { - method: "POST", - body: JSON.stringify({ - username: username, - remote_source_name: remotesourcename, - remote_source_login_name: remoteloginname, - remote_source_login_password: remotepassword - }) - } +export async function register( + username, + remotesourcename, + remoteloginname, + remotepassword +) { + let init = { + method: "POST", + body: JSON.stringify({ + username: username, + remote_source_name: remotesourcename, + remote_source_login_name: remoteloginname, + remote_source_login_password: remotepassword + }) + }; - try { - let res = await registerapi(init) - if (!res.ok) { - let data = await res.json() - return { data: null, error: data.message } - } else { - return { data: await res.json(), error: null } - } - } catch (e) { - return { data: null, error: "api call failed: " + e.message } + try { + let res = await registerapi(init); + if (!res.ok) { + let data = await res.json(); + return { data: null, error: data.message }; + } else { + return { data: await res.json(), error: null }; } + } catch (e) { + return { data: null, error: "api call failed: " + e.message }; + } } export async function fetchCurrentUser(signal) { - let path = "/user" - return await fetch(apiurl(path), null, signal); + let path = "/user"; + return await fetch(apiurl(path), null, signal); } export async function fetchOrgMembers(orgref, signal) { - let path = "/orgs/" + orgref + "/members" - return await fetch(apiurl(path), null, signal); + let path = "/orgs/" + orgref + "/members"; + return await fetch(apiurl(path), null, signal); } export async function fetchRuns(group, startRunID, lastrun, signal) { - let u = apiurl("/runs"); - if (group) { - u.searchParams.append("group", group) - } - if (lastrun) { - u.searchParams.append("lastrun", true) - } - if (startRunID) { - u.searchParams.append("start", startRunID) - } + let u = apiurl("/runs"); + if (group) { + u.searchParams.append("group", group); + } + if (lastrun) { + u.searchParams.append("lastrun", true); + } + if (startRunID) { + u.searchParams.append("start", startRunID); + } - return await fetch(u, null, signal) + return await fetch(u, null, signal); } export async function fetchRun(runid, signal) { - return await fetch(apiurl("/runs/" + runid), null, signal); + return await fetch(apiurl("/runs/" + runid), null, signal); } export async function fetchTask(runid, taskid, signal) { - return await fetch(apiurl("/runs/" + runid + "/tasks/" + taskid), signal) + return await fetch(apiurl("/runs/" + runid + "/tasks/" + taskid), signal); } export async function fetchUser(username, signal) { - let path = "/users/" + username - return await fetch(apiurl(path), null, signal); + let path = "/users/" + username; + return await fetch(apiurl(path), null, signal); } export async function fetchProjectGroup(projectgroupref, signal) { - let path = "/projectgroups/" + encodeURIComponent(projectgroupref) + let path = "/projectgroups/" + encodeURIComponent(projectgroupref); - return await fetch(apiurl(path), null, signal); + return await fetch(apiurl(path), null, signal); } export async function fetchProjectGroupSubgroups(projectgroupref, signal) { - let path = "/projectgroups/" + encodeURIComponent(projectgroupref) - path += "/subgroups"; + let path = "/projectgroups/" + encodeURIComponent(projectgroupref); + path += "/subgroups"; - return await fetch(apiurl(path), null, signal); + return await fetch(apiurl(path), null, signal); } export async function fetchProjectGroupProjects(projectgroupref, signal) { - let path = "/projectgroups/" + encodeURIComponent(projectgroupref) - path += "/projects"; + let path = "/projectgroups/" + encodeURIComponent(projectgroupref); + path += "/projects"; - return await fetch(apiurl(path), null, signal); + return await fetch(apiurl(path), null, signal); } export async function fetchProject(ref, signal) { - let path = "/projects/" + encodeURIComponent(ref) + let path = "/projects/" + encodeURIComponent(ref); - return await fetch(apiurl(path), null, signal); + return await fetch(apiurl(path), null, signal); } export async function fetchSecrets(ownertype, ref, all, signal) { - let path - if (ownertype == "project") { - path = "/projects/" - } else if (ownertype == "projectgroup") { - path = "/projectgroups/" - } - path += encodeURIComponent(ref); - path += "/secrets"; - if (all) { - path += "?tree&removeoverridden"; - } - return await fetch(apiurl(path), null, signal); + let path; + if (ownertype == "project") { + path = "/projects/"; + } else if (ownertype == "projectgroup") { + path = "/projectgroups/"; + } + path += encodeURIComponent(ref); + path += "/secrets"; + if (all) { + path += "?tree&removeoverridden"; + } + return await fetch(apiurl(path), null, signal); } export async function fetchVariables(ownertype, ref, all, signal) { - let path - if (ownertype == "project") { - path = "/projects/" - } else if (ownertype == "projectgroup") { - path = "/projectgroups/" - } - path += encodeURIComponent(ref); - path += "/variables"; - if (all) { - path += "?tree&removeoverridden"; - } - return await fetch(apiurl(path), null, signal); + let path; + if (ownertype == "project") { + path = "/projects/"; + } else if (ownertype == "projectgroup") { + path = "/projectgroups/"; + } + path += encodeURIComponent(ref); + path += "/variables"; + if (all) { + path += "?tree&removeoverridden"; + } + return await fetch(apiurl(path), null, signal); } export async function createOrganization(orgname, visibility, signal) { - let path = "/orgs" - let init = { - method: "POST", - body: JSON.stringify({ - name: orgname, - visibility: visibility, - }) - } - return await fetch(apiurl(path), init, signal) + let path = "/orgs"; + let init = { + method: "POST", + body: JSON.stringify({ + name: orgname, + visibility: visibility + }) + }; + return await fetch(apiurl(path), init, signal); } export async function createUserToken(username, tokenname, signal) { - let path = "/users/" + username + "/tokens" - let init = { - method: "POST", - body: JSON.stringify({ - token_name: tokenname, - }) - } - return await fetch(apiurl(path), init, signal) + let path = "/users/" + username + "/tokens"; + let init = { + method: "POST", + body: JSON.stringify({ + token_name: tokenname + }) + }; + return await fetch(apiurl(path), init, signal); } export async function deleteUserToken(username, tokenname, signal) { - let path = "/users/" + username + "/tokens/" + tokenname - let init = { - method: "DELETE", - } - return await fetch(apiurl(path), init, signal) + let path = "/users/" + username + "/tokens/" + tokenname; + let init = { + method: "DELETE" + }; + return await fetch(apiurl(path), init, signal); } -export async function createUserLinkedAccount(username, remotesourcename, loginname, password, signal) { - let path = "/users/" + username + "/linkedaccounts" - let init = { - method: "POST", - body: JSON.stringify({ - remote_source_name: remotesourcename, - remote_source_login_name: loginname, - remote_source_login_password: password, - }) - } - return await fetch(apiurl(path), init, signal) +export async function createUserLinkedAccount( + username, + remotesourcename, + loginname, + password, + signal +) { + let path = "/users/" + username + "/linkedaccounts"; + let init = { + method: "POST", + body: JSON.stringify({ + remote_source_name: remotesourcename, + remote_source_login_name: loginname, + remote_source_login_password: password + }) + }; + return await fetch(apiurl(path), init, signal); } export async function deleteLinkedAccount(username, laid, signal) { - let path = "/users/" + username + "/linkedaccounts/" + laid - let init = { - method: "DELETE", - } - return await fetch(apiurl(path), init, signal) + let path = "/users/" + username + "/linkedaccounts/" + laid; + let init = { + method: "DELETE" + }; + return await fetch(apiurl(path), init, signal); } export async function restartRun(runid, fromStart, signal) { - let path = "/runs/" + runid + "/actions" - let init = { - method: "PUT", - body: JSON.stringify({ - action_type: "restart", - from_start: fromStart - }) - } - return await fetch(apiurl(path), init, signal) + let path = "/runs/" + runid + "/actions"; + let init = { + method: "PUT", + body: JSON.stringify({ + action_type: "restart", + from_start: fromStart + }) + }; + return await fetch(apiurl(path), init, signal); } export async function cancelRun(runid, signal) { - let path = "/runs/" + runid + "/actions" - let init = { - method: "PUT", - body: JSON.stringify({ - action_type: "cancel" - }) - } - return await fetch(apiurl(path), init, signal) + let path = "/runs/" + runid + "/actions"; + let init = { + method: "PUT", + body: JSON.stringify({ + action_type: "cancel" + }) + }; + return await fetch(apiurl(path), init, signal); } export async function stopRun(runid, signal) { - let path = "/runs/" + runid + "/actions" - let init = { - method: "PUT", - body: JSON.stringify({ - action_type: "stop" - }) - } - return await fetch(apiurl(path), init, signal) + let path = "/runs/" + runid + "/actions"; + let init = { + method: "PUT", + body: JSON.stringify({ + action_type: "stop" + }) + }; + return await fetch(apiurl(path), init, signal); } export async function approveTask(runid, taskid, signal) { - let path = "/runs/" + runid + "/tasks/" + taskid + "/actions" - let init = { - method: "PUT", - body: JSON.stringify({ - action_type: "approve" - }) - } - return await fetch(apiurl(path), init, signal) + let path = "/runs/" + runid + "/tasks/" + taskid + "/actions"; + let init = { + method: "PUT", + body: JSON.stringify({ + action_type: "approve" + }) + }; + return await fetch(apiurl(path), init, signal); } export async function fetchRemoteSources(signal) { - let path = "/remotesources" - return await fetch(apiurl(path), null, signal); + let path = "/remotesources"; + return await fetch(apiurl(path), null, signal); } export async function userRemoteRepos(remotesourceid, signal) { - let path = "/user/remoterepos/" + remotesourceid - return await fetch(apiurl(path, null, signal)); + let path = "/user/remoterepos/" + remotesourceid; + return await fetch(apiurl(path, null, signal)); } export async function createProjectGroup(parentref, name, visibility, signal) { - let path = "/projectgroups" - let init = { - method: "POST", - body: JSON.stringify({ - name: name, - parent_ref: parentref, - visibility: visibility - }) - } - return await fetch(apiurl(path), init, signal) + let path = "/projectgroups"; + let init = { + method: "POST", + body: JSON.stringify({ + name: name, + parent_ref: parentref, + visibility: visibility + }) + }; + return await fetch(apiurl(path), init, signal); } -export async function updateProjectGroup(projectgroupref, name, visibility, signal) { - let path = "/projectgroups/" + encodeURIComponent(projectgroupref) - let init = { - method: "PUT", - body: JSON.stringify({ - name: name, - visibility: visibility, - }) - } - return await fetch(apiurl(path), init, signal) +export async function updateProjectGroup( + projectgroupref, + name, + visibility, + signal +) { + let path = "/projectgroups/" + encodeURIComponent(projectgroupref); + let init = { + method: "PUT", + body: JSON.stringify({ + name: name, + visibility: visibility + }) + }; + return await fetch(apiurl(path), init, signal); } -export async function createProject(parentref, name, visibility, remotesourcename, remoterepopath, signal) { - let path = "/projects" - let init = { - method: "POST", - body: JSON.stringify({ - name: name, - parent_ref: parentref, - visibility: visibility, - remote_source_name: remotesourcename, - repo_path: remoterepopath, - }) - } - return await fetch(apiurl(path), init, signal) +export async function createProject( + parentref, + name, + visibility, + remotesourcename, + remoterepopath, + signal +) { + let path = "/projects"; + let init = { + method: "POST", + body: JSON.stringify({ + name: name, + parent_ref: parentref, + visibility: visibility, + remote_source_name: remotesourcename, + repo_path: remoterepopath + }) + }; + return await fetch(apiurl(path), init, signal); } export async function updateProject(projectref, name, visibility, signal) { - let path = "/projects/" + encodeURIComponent(projectref) - let init = { - method: "PUT", - body: JSON.stringify({ - name: name, - visibility: visibility, - }) - } - return await fetch(apiurl(path), init, signal) + let path = "/projects/" + encodeURIComponent(projectref); + let init = { + method: "PUT", + body: JSON.stringify({ + name: name, + visibility: visibility + }) + }; + return await fetch(apiurl(path), init, signal); } export async function deleteProject(projectref, signal) { - let path = "/projects/" + encodeURIComponent(projectref) - let init = { - method: "DELETE", - } - return await fetch(apiurl(path), init, signal) + let path = "/projects/" + encodeURIComponent(projectref); + let init = { + method: "DELETE" + }; + return await fetch(apiurl(path), init, signal); } export async function projectUpdateRepoLinkedAccount(projectref, signal) { - let path = "/projects/" + encodeURIComponent(projectref) + "/updaterepolinkedaccount" - let init = { - method: "PUT", - } - return await fetch(apiurl(path), init, signal) + let path = + "/projects/" + encodeURIComponent(projectref) + "/updaterepolinkedaccount"; + let init = { + method: "PUT" + }; + return await fetch(apiurl(path), init, signal); } export async function deleteProjectGroup(projectgroupref, signal) { - let path = "/projectgroups/" + encodeURIComponent(projectgroupref) - let init = { - method: "DELETE", - } - return await fetch(apiurl(path), init, signal) -} \ No newline at end of file + let path = "/projectgroups/" + encodeURIComponent(projectgroupref); + let init = { + method: "DELETE" + }; + return await fetch(apiurl(path), init, signal); +} diff --git a/src/views/Login.vue b/src/views/Login.vue index 1d3c20e..ae0f78d 100644 --- a/src/views/Login.vue +++ b/src/views/Login.vue @@ -38,7 +38,12 @@