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.
+
+
+ Redirect URL
+ (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." }
}