diff --git a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/ButtonActionEditor/actions/LogOut.svelte b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/ButtonActionEditor/actions/LogOut.svelte index 3434d63480..f0606d86b3 100644 --- a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/ButtonActionEditor/actions/LogOut.svelte +++ b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/ButtonActionEditor/actions/LogOut.svelte @@ -1,13 +1,38 @@
- This action doesn't require any additional settings. + + + Please enter the URL you would like to be redirected to after logging out. + If you don't enter a value, you'll be redirected to the login screen. + +
+ + (parameters.redirectUrl = value.detail)} + {bindings} + /> +
+
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..9cd2613e24 100644 --- a/packages/client/src/stores/auth.js +++ b/packages/client/src/stores/auth.js @@ -11,8 +11,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..2ef324d23c 100644 --- a/packages/client/src/utils/buttonActions.js +++ b/packages/client/src/utils/buttonActions.js @@ -112,8 +112,20 @@ const refreshDataProviderHandler = async (action, context) => { ) } -const logoutHandler = async () => { +const logoutHandler = async action => { await authStore.actions.logOut() + let redirectUrl = "/builder/auth/login" + let internal = false + if (action.parameters.redirectUrl) { + internal = action.parameters.redirectUrl?.startsWith("/") + redirectUrl = routeStore.actions.createFullURL( + action.parameters.redirectUrl + ) + } + window.location.href = redirectUrl + if (internal) { + window.location.reload() + } } const clearFormHandler = async (action, context) => { diff --git a/packages/worker/src/api/controllers/global/auth.js b/packages/worker/src/api/controllers/global/auth.js index 2ba12194ca..44ee99aee7 100644 --- a/packages/worker/src/api/controllers/global/auth.js +++ b/packages/worker/src/api/controllers/global/auth.js @@ -141,7 +141,9 @@ exports.resetUpdate = async ctx => { } exports.logout = async ctx => { - await platformLogout({ ctx, userId: ctx.user._id }) + if (ctx.user && ctx.user._id) { + await platformLogout({ ctx, userId: ctx.user._id }) + } ctx.body = { message: "User logged out." } }