commit
0f6e626005
|
@ -8,6 +8,7 @@ exports.Cookies = {
|
|||
Auth: "budibase:auth",
|
||||
Init: "budibase:init",
|
||||
OIDC_CONFIG: "budibase:oidc:config",
|
||||
RETURN_URL: "budibase:returnurl",
|
||||
}
|
||||
|
||||
exports.Headers = {
|
||||
|
|
|
@ -96,7 +96,12 @@ exports.getCookie = (ctx, name) => {
|
|||
* @param {string|object} value The value of cookie which will be set.
|
||||
* @param {object} opts options like whether to sign.
|
||||
*/
|
||||
exports.setCookie = (ctx, value, name = "builder", opts = { sign: true }) => {
|
||||
exports.setCookie = (
|
||||
ctx,
|
||||
value,
|
||||
name = "builder",
|
||||
opts = { sign: true, requestDomain: false }
|
||||
) => {
|
||||
if (value && opts && opts.sign) {
|
||||
value = jwt.sign(value, options.secretOrKey)
|
||||
}
|
||||
|
@ -108,7 +113,7 @@ exports.setCookie = (ctx, value, name = "builder", opts = { sign: true }) => {
|
|||
overwrite: true,
|
||||
}
|
||||
|
||||
if (environment.COOKIE_DOMAIN) {
|
||||
if (environment.COOKIE_DOMAIN && !opts.requestDomain) {
|
||||
config.domain = environment.COOKIE_DOMAIN
|
||||
}
|
||||
|
||||
|
|
|
@ -1,16 +1,26 @@
|
|||
export const Cookies = {
|
||||
Auth: "budibase:auth",
|
||||
CurrentApp: "budibase:currentapp",
|
||||
ReturnUrl: "budibase:returnurl",
|
||||
}
|
||||
|
||||
export function setCookie(name, value) {
|
||||
if (getCookie(name)) {
|
||||
removeCookie(name)
|
||||
}
|
||||
window.document.cookie = `${name}=${value}; Path=/;`
|
||||
}
|
||||
|
||||
export function getCookie(cookieName) {
|
||||
return document.cookie.split(";").some(cookie => {
|
||||
return cookie.trim().startsWith(`${cookieName}=`)
|
||||
})
|
||||
const value = `; ${document.cookie}`
|
||||
const parts = value.split(`; ${cookieName}=`)
|
||||
if (parts.length === 2) {
|
||||
return parts[1].split(";").shift()
|
||||
}
|
||||
}
|
||||
|
||||
export function removeCookie(cookieName) {
|
||||
if (getCookie(cookieName)) {
|
||||
document.cookie = `${cookieName}=; Max-Age=-99999999;`
|
||||
document.cookie = `${cookieName}=; Max-Age=-99999999; Path=/;`
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,12 @@
|
|||
import { isActive, redirect, params } from "@roxi/routify"
|
||||
import { admin, auth } from "stores/portal"
|
||||
import { onMount } from "svelte"
|
||||
import {
|
||||
Cookies,
|
||||
getCookie,
|
||||
removeCookie,
|
||||
setCookie,
|
||||
} from "builderStore/cookies"
|
||||
|
||||
let loaded = false
|
||||
|
||||
|
@ -67,6 +73,24 @@
|
|||
|
||||
$: {
|
||||
const apiReady = $admin.loaded && $auth.loaded
|
||||
|
||||
// firstly, set the return url
|
||||
if (
|
||||
loaded &&
|
||||
apiReady &&
|
||||
!$auth.user &&
|
||||
!getCookie(Cookies.ReturnUrl) &&
|
||||
// logout triggers a page refresh, so we don't want to set the return url
|
||||
!$auth.postLogout &&
|
||||
// don't set the return url on pre-login pages
|
||||
!$isActive("./auth") &&
|
||||
!$isActive("./invite") &&
|
||||
!$isActive("./admin")
|
||||
) {
|
||||
const url = window.location.pathname
|
||||
setCookie(Cookies.ReturnUrl, url)
|
||||
}
|
||||
|
||||
// if tenant is not set go to it
|
||||
if (
|
||||
loaded &&
|
||||
|
@ -90,13 +114,20 @@
|
|||
!$isActive("./invite") &&
|
||||
!$isActive("./admin")
|
||||
) {
|
||||
const returnUrl = encodeURIComponent(window.location.pathname)
|
||||
$redirect("./auth?", { returnUrl })
|
||||
$redirect("./auth")
|
||||
}
|
||||
// check if password reset required for user
|
||||
else if ($auth.user?.forceResetPassword) {
|
||||
$redirect("./auth/reset")
|
||||
}
|
||||
// lastly, redirect to the return url if it has been set
|
||||
else if (loaded && apiReady && $auth.user) {
|
||||
const returnUrl = getCookie(Cookies.ReturnUrl)
|
||||
if (returnUrl) {
|
||||
removeCookie(Cookies.ReturnUrl)
|
||||
window.location.href = returnUrl
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
notifications,
|
||||
Link,
|
||||
} from "@budibase/bbui"
|
||||
import { goto, params } from "@roxi/routify"
|
||||
import { goto } from "@roxi/routify"
|
||||
import { auth, organisation, oidc, admin } from "stores/portal"
|
||||
import GoogleButton from "./_components/GoogleButton.svelte"
|
||||
import OIDCButton from "./_components/OIDCButton.svelte"
|
||||
|
@ -34,14 +34,10 @@
|
|||
|
||||
if ($auth?.user?.forceResetPassword) {
|
||||
$goto("./reset")
|
||||
} else {
|
||||
if ($params["?returnUrl"]) {
|
||||
window.location = decodeURIComponent($params["?returnUrl"])
|
||||
} else {
|
||||
notifications.success("Logged in successfully")
|
||||
$goto("../portal")
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
notifications.error(err.message ? err.message : "Invalid Credentials")
|
||||
|
|
|
@ -9,6 +9,7 @@ export function createAuthStore() {
|
|||
tenantId: "default",
|
||||
tenantSet: false,
|
||||
loaded: false,
|
||||
postLogout: false,
|
||||
})
|
||||
const store = derived(auth, $store => {
|
||||
let initials = null
|
||||
|
@ -34,6 +35,7 @@ export function createAuthStore() {
|
|||
tenantId: $store.tenantId,
|
||||
tenantSet: $store.tenantSet,
|
||||
loaded: $store.loaded,
|
||||
postLogout: $store.postLogout,
|
||||
initials,
|
||||
isAdmin,
|
||||
isBuilder,
|
||||
|
@ -89,6 +91,13 @@ export function createAuthStore() {
|
|||
return info
|
||||
}
|
||||
|
||||
async function setPostLogout() {
|
||||
auth.update(store => {
|
||||
store.postLogout = true
|
||||
return store
|
||||
})
|
||||
}
|
||||
|
||||
async function getInitInfo() {
|
||||
const response = await api.get(`/api/global/auth/init`)
|
||||
const json = response.json()
|
||||
|
@ -145,6 +154,7 @@ export function createAuthStore() {
|
|||
await response.json()
|
||||
await setInitInfo({})
|
||||
setUser(null)
|
||||
setPostLogout()
|
||||
},
|
||||
updateSelf: async fields => {
|
||||
const newUser = { ...get(auth).user, ...fields }
|
||||
|
|
|
@ -63,8 +63,9 @@
|
|||
} else {
|
||||
// The user is not logged in, redirect them to login
|
||||
const returnUrl = `${window.location.pathname}${window.location.hash}`
|
||||
const encodedUrl = encodeURIComponent(returnUrl)
|
||||
window.location = `/builder/auth/login?returnUrl=${encodedUrl}`
|
||||
// TODO: reuse `Cookies` from builder when frontend-core is added
|
||||
window.document.cookie = `budibase:returnurl=${returnUrl}; Path=/`
|
||||
window.location = `/builder/auth/login`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ module S3Module {
|
|||
signatureVersion: {
|
||||
type: "string",
|
||||
required: false,
|
||||
default: "v4"
|
||||
default: "v4",
|
||||
},
|
||||
},
|
||||
query: {
|
||||
|
|
|
@ -47,6 +47,15 @@ module.exports = async (ctx, next) => {
|
|||
(!ctx.user || !ctx.user.builder || !ctx.user.builder.global)
|
||||
) {
|
||||
clearCookie(ctx, Cookies.CurrentApp)
|
||||
// have to set the return url on the server side as client side is not available
|
||||
setCookie(ctx, ctx.url, Cookies.RETURN_URL, {
|
||||
// don't sign so the browser can easily read
|
||||
sign: false,
|
||||
// use the request domain to match how ui handles the return url cookie.
|
||||
// it's important we don't use the shared domain here as the builder
|
||||
// can't delete from it without awareness of the domain.
|
||||
requestDomain: true,
|
||||
})
|
||||
return ctx.redirect("/")
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue