diff --git a/packages/client/src/api/auth.js b/packages/client/src/api/auth.js index 68ca5dbc80..9ac09f5571 100644 --- a/packages/client/src/api/auth.js +++ b/packages/client/src/api/auth.js @@ -18,6 +18,15 @@ export const logIn = async ({ email, password }) => { }) } +/** + * Logs the user out and invaidates their session. + */ +export const logOut = async () => { + return await API.post({ + url: "/api/global/auth/logout", + }) +} + /** * Fetches the currently logged in user object */ diff --git a/packages/client/src/stores/auth.js b/packages/client/src/stores/auth.js index 1fa4ae17b0..f50f7a52c1 100644 --- a/packages/client/src/stores/auth.js +++ b/packages/client/src/stores/auth.js @@ -1,5 +1,6 @@ import * as API from "../api" import { writable } from "svelte/store" +import { initialise } from "./initialise.js" const createAuthStore = () => { const store = writable(null) @@ -11,8 +12,14 @@ const createAuthStore = () => { } const logOut = async () => { + try { + await API.logOut() + } catch (error) { + // Do nothing + } + + // Manually destroy cookie to be sure window.document.cookie = `budibase:auth=; budibase:currentapp=; Path=/; Expires=Thu, 01 Jan 1970 00:00:01 GMT;` - window.location = "/builder/auth/login" } return { diff --git a/packages/client/src/stores/routes.js b/packages/client/src/stores/routes.js index 1d5dca1645..d50677493b 100644 --- a/packages/client/src/stores/routes.js +++ b/packages/client/src/stores/routes.js @@ -18,8 +18,8 @@ const createRouteStore = () => { const fetchRoutes = async () => { const routeConfig = await API.fetchRoutes() let routes = [] - Object.values(routeConfig.routes).forEach(route => { - Object.entries(route.subpaths).forEach(([path, config]) => { + Object.values(routeConfig.routes || {}).forEach(route => { + Object.entries(route.subpaths || {}).forEach(([path, config]) => { routes.push({ path, screenId: config.screenId, @@ -83,12 +83,23 @@ const createRouteStore = () => { const setRouterLoaded = () => { store.update(state => ({ ...state, routerLoaded: true })) } + const createFullURL = relativeURL => { + if (!relativeURL?.startsWith("/")) { + return relativeURL + } + if (!window.location.href.includes("#")) { + return `${window.location.href}#${relativeURL}` + } + const base = window.location.href.split("#")[0] + return `${base}#${relativeURL}` + } return { subscribe: store.subscribe, actions: { fetchRoutes, navigate, + createFullURL, setRouteParams, setQueryParams, setActiveRoute, diff --git a/packages/client/src/utils/buttonActions.js b/packages/client/src/utils/buttonActions.js index 6b4dd4235a..1ab3b26976 100644 --- a/packages/client/src/utils/buttonActions.js +++ b/packages/client/src/utils/buttonActions.js @@ -112,8 +112,18 @@ const refreshDataProviderHandler = async (action, context) => { ) } -const logoutHandler = async () => { +const logoutHandler = async action => { await authStore.actions.logOut() + let returnUrl = "/builder/auth/login" + let internal = false + if (action.parameters.returnUrl) { + internal = action.parameters.returnUrl?.startsWith("/") + returnUrl = routeStore.actions.createFullURL(action.parameters.returnUrl) + } + window.location.href = returnUrl + if (internal) { + window.location.reload() + } } const clearFormHandler = async (action, context) => {