Some more re-work, more testing needed to auth stuff.
This commit is contained in:
parent
e0353feff1
commit
a1fd261af6
|
@ -2,7 +2,7 @@ import { attachChildren } from "./render/attachChildren"
|
||||||
import { createTreeNode } from "./render/prepareRenderComponent"
|
import { createTreeNode } from "./render/prepareRenderComponent"
|
||||||
import { screenRouter } from "./render/screenRouter"
|
import { screenRouter } from "./render/screenRouter"
|
||||||
import { createStateManager } from "./state/stateManager"
|
import { createStateManager } from "./state/stateManager"
|
||||||
import { parseAppIdFromCookie } from "./render/getAppId"
|
import { getAppIdFromPath } from "./render/getAppId"
|
||||||
|
|
||||||
export const createApp = ({
|
export const createApp = ({
|
||||||
componentLibraries,
|
componentLibraries,
|
||||||
|
@ -38,7 +38,7 @@ export const createApp = ({
|
||||||
window,
|
window,
|
||||||
})
|
})
|
||||||
const fallbackPath = window.location.pathname.replace(
|
const fallbackPath = window.location.pathname.replace(
|
||||||
parseAppIdFromCookie(window.document.cookie),
|
getAppIdFromPath(),
|
||||||
""
|
""
|
||||||
)
|
)
|
||||||
routeTo(currentUrl || fallbackPath)
|
routeTo(currentUrl || fallbackPath)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { createApp } from "./createApp"
|
import { createApp } from "./createApp"
|
||||||
import { builtins, builtinLibName } from "./render/builtinComponents"
|
import { builtins, builtinLibName } from "./render/builtinComponents"
|
||||||
import { parseAppIdFromCookie } from "./render/getAppId"
|
import { getAppIdFromPath } from "./render/getAppId"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* create a web application from static budibase definition files.
|
* create a web application from static budibase definition files.
|
||||||
|
@ -9,7 +9,7 @@ import { parseAppIdFromCookie } from "./render/getAppId"
|
||||||
export const loadBudibase = async opts => {
|
export const loadBudibase = async opts => {
|
||||||
const _window = (opts && opts.window) || window
|
const _window = (opts && opts.window) || window
|
||||||
// const _localStorage = (opts && opts.localStorage) || localStorage
|
// const _localStorage = (opts && opts.localStorage) || localStorage
|
||||||
const appId = parseAppIdFromCookie(_window.document.cookie)
|
const appId = getAppIdFromPath()
|
||||||
const frontendDefinition = _window["##BUDIBASE_FRONTEND_DEFINITION##"]
|
const frontendDefinition = _window["##BUDIBASE_FRONTEND_DEFINITION##"]
|
||||||
|
|
||||||
const user = {}
|
const user = {}
|
||||||
|
|
|
@ -1,14 +1,3 @@
|
||||||
export const parseAppIdFromCookie = docCookie => {
|
export const getAppIdFromPath = () => {
|
||||||
const cookie =
|
return location.pathname.split("/")[1]
|
||||||
docCookie.split(";").find(c => c.trim().startsWith("budibase:token")) ||
|
|
||||||
docCookie.split(";").find(c => c.trim().startsWith("builder:token"))
|
|
||||||
|
|
||||||
if (!cookie) return location.pathname.replace(/\//g, "")
|
|
||||||
|
|
||||||
const base64Token = cookie.substring(lengthOfKey)
|
|
||||||
|
|
||||||
const user = JSON.parse(atob(base64Token.split(".")[1]))
|
|
||||||
return user.appId
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const lengthOfKey = "budibase:token=".length
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import regexparam from "regexparam"
|
import regexparam from "regexparam"
|
||||||
import appStore from "../state/store"
|
import appStore from "../state/store"
|
||||||
import { parseAppIdFromCookie } from "./getAppId"
|
import { getAppIdFromPath } from "./getAppId"
|
||||||
|
|
||||||
export const screenRouter = ({ screens, onScreenSelected, window }) => {
|
export const screenRouter = ({ screens, onScreenSelected, window }) => {
|
||||||
function sanitize(url) {
|
function sanitize(url) {
|
||||||
|
@ -27,7 +27,7 @@ export const screenRouter = ({ screens, onScreenSelected, window }) => {
|
||||||
|
|
||||||
const makeRootedPath = url => {
|
const makeRootedPath = url => {
|
||||||
if (isRunningLocally()) {
|
if (isRunningLocally()) {
|
||||||
const appId = parseAppIdFromCookie(window.document.cookie)
|
const appId = getAppIdFromPath()
|
||||||
if (url) {
|
if (url) {
|
||||||
url = sanitize(url)
|
url = sanitize(url)
|
||||||
if (!url.startsWith("/")) {
|
if (!url.startsWith("/")) {
|
||||||
|
|
|
@ -9,7 +9,7 @@ export const load = async (page, screens, url, host = "test.com") => {
|
||||||
const cookieJar = new jsdom.CookieJar()
|
const cookieJar = new jsdom.CookieJar()
|
||||||
const cookie = `${btoa("{}")}.${btoa('{"appId":"TEST_APP_ID"}')}.signature`
|
const cookie = `${btoa("{}")}.${btoa('{"appId":"TEST_APP_ID"}')}.signature`
|
||||||
cookieJar.setCookie(
|
cookieJar.setCookie(
|
||||||
`budibase:token=${cookie};domain=${host};path=/`,
|
`budibase:local:TEST_APP_ID=${cookie};domain=${host};path=/`,
|
||||||
fullUrl,
|
fullUrl,
|
||||||
{
|
{
|
||||||
looseMode: false,
|
looseMode: false,
|
||||||
|
|
|
@ -4,6 +4,7 @@ const bcrypt = require("../../utilities/bcrypt")
|
||||||
const env = require("../../environment")
|
const env = require("../../environment")
|
||||||
const { getAPIKey } = require("../../utilities/usageQuota")
|
const { getAPIKey } = require("../../utilities/usageQuota")
|
||||||
const { generateUserID } = require("../../db/utils")
|
const { generateUserID } = require("../../db/utils")
|
||||||
|
const { getCookieName } = require("../../utilities")
|
||||||
|
|
||||||
exports.authenticate = async ctx => {
|
exports.authenticate = async ctx => {
|
||||||
const appId = ctx.user.appId
|
const appId = ctx.user.appId
|
||||||
|
@ -48,16 +49,18 @@ exports.authenticate = async ctx => {
|
||||||
const expires = new Date()
|
const expires = new Date()
|
||||||
expires.setDate(expires.getDate() + 1)
|
expires.setDate(expires.getDate() + 1)
|
||||||
|
|
||||||
ctx.cookies.set(`budibase:token`, token, {
|
ctx.cookies.set(getCookieName(appId), token, {
|
||||||
expires,
|
expires,
|
||||||
path: "/",
|
path: "/",
|
||||||
httpOnly: false,
|
httpOnly: false,
|
||||||
overwrite: true,
|
overwrite: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
delete dbUser.password
|
||||||
ctx.body = {
|
ctx.body = {
|
||||||
token,
|
token,
|
||||||
...dbUser,
|
...dbUser,
|
||||||
|
appId,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ctx.throw(401, "Invalid credentials.")
|
ctx.throw(401, "Invalid credentials.")
|
||||||
|
|
|
@ -9,6 +9,7 @@ const {
|
||||||
} = require("../utilities/accessLevels")
|
} = require("../utilities/accessLevels")
|
||||||
const env = require("../environment")
|
const env = require("../environment")
|
||||||
const { AuthTypes } = require("../constants")
|
const { AuthTypes } = require("../constants")
|
||||||
|
const { getAppId, getCookieName } = require("../utilities")
|
||||||
|
|
||||||
module.exports = async (ctx, next) => {
|
module.exports = async (ctx, next) => {
|
||||||
if (ctx.path === "/_builder") {
|
if (ctx.path === "/_builder") {
|
||||||
|
@ -16,8 +17,10 @@ module.exports = async (ctx, next) => {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const appToken = ctx.cookies.get("budibase:token")
|
const appId = getAppId(ctx)
|
||||||
const builderToken = ctx.cookies.get("builder:token")
|
|
||||||
|
const appToken = ctx.cookies.get(getCookieName(appId))
|
||||||
|
const builderToken = ctx.cookies.get(getCookieName())
|
||||||
|
|
||||||
let token
|
let token
|
||||||
// if running locally in the builder itself
|
// if running locally in the builder itself
|
||||||
|
@ -31,16 +34,6 @@ module.exports = async (ctx, next) => {
|
||||||
|
|
||||||
if (!token) {
|
if (!token) {
|
||||||
ctx.auth.authenticated = false
|
ctx.auth.authenticated = false
|
||||||
|
|
||||||
let appId = env.CLOUD ? ctx.subdomains[1] : ctx.params.appId
|
|
||||||
|
|
||||||
// if appId can't be determined from path param or subdomain
|
|
||||||
if (!appId && ctx.request.headers.referer) {
|
|
||||||
const url = new URL(ctx.request.headers.referer)
|
|
||||||
// remove leading and trailing slashes from appId
|
|
||||||
appId = url.pathname.replace(/\//g, "")
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.user = {
|
ctx.user = {
|
||||||
appId,
|
appId,
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,9 @@ const { BUILDER_LEVEL_ID } = require("../accessLevels")
|
||||||
const env = require("../../environment")
|
const env = require("../../environment")
|
||||||
const CouchDB = require("../../db")
|
const CouchDB = require("../../db")
|
||||||
const jwt = require("jsonwebtoken")
|
const jwt = require("jsonwebtoken")
|
||||||
|
const { DocumentTypes, SEPARATOR } = require("../../db/utils")
|
||||||
|
const { getCookieName } = require("../index")
|
||||||
|
const APP_PREFIX = DocumentTypes.APP + SEPARATOR
|
||||||
|
|
||||||
module.exports = async (ctx, appId, version) => {
|
module.exports = async (ctx, appId, version) => {
|
||||||
const builderUser = {
|
const builderUser = {
|
||||||
|
@ -20,15 +23,18 @@ module.exports = async (ctx, appId, version) => {
|
||||||
const expiry = new Date()
|
const expiry = new Date()
|
||||||
expiry.setDate(expiry.getDate() + 30)
|
expiry.setDate(expiry.getDate() + 30)
|
||||||
// set the builder token
|
// set the builder token
|
||||||
ctx.cookies.set("builder:token", token, {
|
ctx.cookies.set(getCookieName(), token, {
|
||||||
expires: expiry,
|
expires: expiry,
|
||||||
httpOnly: false,
|
httpOnly: false,
|
||||||
overwrite: true,
|
overwrite: true,
|
||||||
})
|
})
|
||||||
// need to clear all app tokens or else unable to use the app in the builder
|
// need to clear all app tokens or else unable to use the app in the builder
|
||||||
let allDbNames = await CouchDB.allDbs()
|
let allDbNames = await CouchDB.allDbs()
|
||||||
allDbNames.map(dbName => {})
|
allDbNames.map(dbName => {
|
||||||
ctx.cookies.set(`budibase:${appId}`, "", {
|
if (dbName.startsWith(APP_PREFIX)) {
|
||||||
|
ctx.cookies.set(getCookieName(dbName), "", {
|
||||||
overwrite: true,
|
overwrite: true,
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,32 @@ exports.isDev = () => {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given a request tries to find the appId, which can be located in various places
|
||||||
|
* @param {object} ctx The main request body to look through.
|
||||||
|
* @returns {string|undefined} If an appId was found it will be returned.
|
||||||
|
*/
|
||||||
exports.getAppId = ctx => {
|
exports.getAppId = ctx => {
|
||||||
|
let appId = env.CLOUD ? ctx.subdomains[1] : ctx.params.appId
|
||||||
|
// look in body if can't find it in subdomain
|
||||||
|
if (!appId && ctx.request.body && ctx.request.body.appId) {
|
||||||
|
appId = ctx.request.body.appId
|
||||||
|
}
|
||||||
|
// if appId can't be determined from path param or subdomain
|
||||||
|
if (!appId && ctx.request.headers.referer) {
|
||||||
|
const url = new URL(ctx.request.headers.referer)
|
||||||
|
// remove leading and trailing slashes from appId
|
||||||
|
appId = url.pathname.replace(/\//g, "")
|
||||||
|
}
|
||||||
|
return appId
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the name of the cookie which is to be updated/retrieved
|
||||||
|
* @param {string|undefined|null} appId OPTIONAL can specify the specific app if previewing etc
|
||||||
|
* @returns {string} The name of the token trying to find
|
||||||
|
*/
|
||||||
|
exports.getCookieName = (appId = null) => {
|
||||||
|
let mid = env.CLOUD ? "cloud" : "local"
|
||||||
|
return `budibase:${mid}:${appId ? appId : "builder"}`
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue