Some more re-work, more testing needed to auth stuff.

This commit is contained in:
mike12345567 2020-11-02 20:14:10 +00:00
parent e0353feff1
commit a1fd261af6
9 changed files with 55 additions and 38 deletions

View File

@ -2,7 +2,7 @@ import { attachChildren } from "./render/attachChildren"
import { createTreeNode } from "./render/prepareRenderComponent"
import { screenRouter } from "./render/screenRouter"
import { createStateManager } from "./state/stateManager"
import { parseAppIdFromCookie } from "./render/getAppId"
import { getAppIdFromPath } from "./render/getAppId"
export const createApp = ({
componentLibraries,
@ -38,7 +38,7 @@ export const createApp = ({
window,
})
const fallbackPath = window.location.pathname.replace(
parseAppIdFromCookie(window.document.cookie),
getAppIdFromPath(),
""
)
routeTo(currentUrl || fallbackPath)

View File

@ -1,6 +1,6 @@
import { createApp } from "./createApp"
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.
@ -9,7 +9,7 @@ import { parseAppIdFromCookie } from "./render/getAppId"
export const loadBudibase = async opts => {
const _window = (opts && opts.window) || window
// const _localStorage = (opts && opts.localStorage) || localStorage
const appId = parseAppIdFromCookie(_window.document.cookie)
const appId = getAppIdFromPath()
const frontendDefinition = _window["##BUDIBASE_FRONTEND_DEFINITION##"]
const user = {}

View File

@ -1,14 +1,3 @@
export const parseAppIdFromCookie = docCookie => {
const cookie =
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
export const getAppIdFromPath = () => {
return location.pathname.split("/")[1]
}
const lengthOfKey = "budibase:token=".length

View File

@ -1,6 +1,6 @@
import regexparam from "regexparam"
import appStore from "../state/store"
import { parseAppIdFromCookie } from "./getAppId"
import { getAppIdFromPath } from "./getAppId"
export const screenRouter = ({ screens, onScreenSelected, window }) => {
function sanitize(url) {
@ -27,7 +27,7 @@ export const screenRouter = ({ screens, onScreenSelected, window }) => {
const makeRootedPath = url => {
if (isRunningLocally()) {
const appId = parseAppIdFromCookie(window.document.cookie)
const appId = getAppIdFromPath()
if (url) {
url = sanitize(url)
if (!url.startsWith("/")) {

View File

@ -9,7 +9,7 @@ export const load = async (page, screens, url, host = "test.com") => {
const cookieJar = new jsdom.CookieJar()
const cookie = `${btoa("{}")}.${btoa('{"appId":"TEST_APP_ID"}')}.signature`
cookieJar.setCookie(
`budibase:token=${cookie};domain=${host};path=/`,
`budibase:local:TEST_APP_ID=${cookie};domain=${host};path=/`,
fullUrl,
{
looseMode: false,

View File

@ -4,6 +4,7 @@ const bcrypt = require("../../utilities/bcrypt")
const env = require("../../environment")
const { getAPIKey } = require("../../utilities/usageQuota")
const { generateUserID } = require("../../db/utils")
const { getCookieName } = require("../../utilities")
exports.authenticate = async ctx => {
const appId = ctx.user.appId
@ -48,16 +49,18 @@ exports.authenticate = async ctx => {
const expires = new Date()
expires.setDate(expires.getDate() + 1)
ctx.cookies.set(`budibase:token`, token, {
ctx.cookies.set(getCookieName(appId), token, {
expires,
path: "/",
httpOnly: false,
overwrite: true,
})
delete dbUser.password
ctx.body = {
token,
...dbUser,
appId,
}
} else {
ctx.throw(401, "Invalid credentials.")

View File

@ -9,6 +9,7 @@ const {
} = require("../utilities/accessLevels")
const env = require("../environment")
const { AuthTypes } = require("../constants")
const { getAppId, getCookieName } = require("../utilities")
module.exports = async (ctx, next) => {
if (ctx.path === "/_builder") {
@ -16,8 +17,10 @@ module.exports = async (ctx, next) => {
return
}
const appToken = ctx.cookies.get("budibase:token")
const builderToken = ctx.cookies.get("builder:token")
const appId = getAppId(ctx)
const appToken = ctx.cookies.get(getCookieName(appId))
const builderToken = ctx.cookies.get(getCookieName())
let token
// if running locally in the builder itself
@ -31,16 +34,6 @@ module.exports = async (ctx, next) => {
if (!token) {
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 = {
appId,
}

View File

@ -2,6 +2,9 @@ const { BUILDER_LEVEL_ID } = require("../accessLevels")
const env = require("../../environment")
const CouchDB = require("../../db")
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) => {
const builderUser = {
@ -20,15 +23,18 @@ module.exports = async (ctx, appId, version) => {
const expiry = new Date()
expiry.setDate(expiry.getDate() + 30)
// set the builder token
ctx.cookies.set("builder:token", token, {
ctx.cookies.set(getCookieName(), token, {
expires: expiry,
httpOnly: false,
overwrite: true,
})
// need to clear all app tokens or else unable to use the app in the builder
let allDbNames = await CouchDB.allDbs()
allDbNames.map(dbName => {})
ctx.cookies.set(`budibase:${appId}`, "", {
overwrite: true,
allDbNames.map(dbName => {
if (dbName.startsWith(APP_PREFIX)) {
ctx.cookies.set(getCookieName(dbName), "", {
overwrite: true,
})
}
})
}

View File

@ -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 => {
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"}`
}