From dc20151c196583007a7388c0c406b4114332c2f1 Mon Sep 17 00:00:00 2001
From: mike12345567 <me@michaeldrury.co.uk>
Date: Wed, 14 Apr 2021 16:00:58 +0100
Subject: [PATCH] Some more server-side fixes, updating it so that builders
 have permissions to do anything for now (means that a builder user doesn't
 have to be present in app database to work.

---
 packages/auth/src/index.js                   |  3 +-
 packages/server/src/middleware/authorized.js |  4 +-
 packages/server/src/utilities/index.js       | 86 --------------------
 packages/server/src/utilities/users.js       | 11 ++-
 4 files changed, 14 insertions(+), 90 deletions(-)

diff --git a/packages/auth/src/index.js b/packages/auth/src/index.js
index b94a02ea7d..71fd512193 100644
--- a/packages/auth/src/index.js
+++ b/packages/auth/src/index.js
@@ -7,7 +7,7 @@ const { StaticDatabases } = require("./db/utils")
 const { jwt, local, google, authenticated } = require("./middleware")
 const { Cookies, UserStatus } = require("./constants")
 const { hash, compare } = require("./hashing")
-const { getAppId, setCookie, getCookie, clearCookie } = require("./utils")
+const { getAppId, setCookie, getCookie, clearCookie, isClient } = require("./utils")
 const {
   generateUserID,
   getUserParams,
@@ -48,4 +48,5 @@ module.exports = {
   getCookie,
   clearCookie,
   authenticated,
+  isClient,
 }
diff --git a/packages/server/src/middleware/authorized.js b/packages/server/src/middleware/authorized.js
index db3c81e95e..589529fadc 100644
--- a/packages/server/src/middleware/authorized.js
+++ b/packages/server/src/middleware/authorized.js
@@ -30,8 +30,10 @@ module.exports = (permType, permLevel = null) => async (ctx, next) => {
     ctx.roleId
   )
 
+  // builders for now have permission to do anything
+  // TODO: in future should consider separating permissions with an require("@budibase/auth").isClient check
   let isBuilder = ctx.user && ctx.user.builder && ctx.user.builder.global
-  if (permType === PermissionTypes.BUILDER && isBuilder) {
+  if (isBuilder) {
     return next()
   } else if (permType === PermissionTypes.BUILDER && !isBuilder) {
     return ctx.throw(403, "Not Authorized")
diff --git a/packages/server/src/utilities/index.js b/packages/server/src/utilities/index.js
index 5b5c2bef06..d9aeae60df 100644
--- a/packages/server/src/utilities/index.js
+++ b/packages/server/src/utilities/index.js
@@ -6,96 +6,10 @@ const { OBJ_STORE_DIRECTORY } = require("../constants")
 const BB_CDN = "https://cdn.app.budi.live/assets"
 const APP_PREFIX = DocumentTypes.APP + SEPARATOR
 
-function confirmAppId(possibleAppId) {
-  return possibleAppId && possibleAppId.startsWith(APP_PREFIX)
-    ? possibleAppId
-    : undefined
-}
-
 exports.wait = ms => new Promise(resolve => setTimeout(resolve, ms))
 
 exports.isDev = env.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 => {
-  const options = [ctx.headers["x-budibase-app-id"], ctx.params.appId]
-  if (ctx.subdomains) {
-    options.push(ctx.subdomains[1])
-  }
-  let appId
-  for (let option of options) {
-    appId = confirmAppId(option)
-    if (appId) {
-      break
-    }
-  }
-
-  // look in body if can't find it in subdomain
-  if (!appId && ctx.request.body && ctx.request.body.appId) {
-    appId = confirmAppId(ctx.request.body.appId)
-  }
-  let appPath =
-    ctx.request.headers.referrer ||
-    ctx.path.split("/").filter(subPath => subPath.startsWith(APP_PREFIX))
-  if (!appId && appPath.length !== 0) {
-    appId = confirmAppId(appPath[0])
-  }
-  return appId
-}
-
-/**
- * Get the name of the cookie which is to be updated/retrieved
- * @param {string} name The name/type of cookie.
- * @returns {string} The full name of the cookie to retrieve/update.
- */
-exports.getCookieName = name => {
-  return `budibase:${name}`
-}
-
-/**
- * Store a cookie for the request, has a hardcoded expiry.
- * @param {object} ctx The request which is to be manipulated.
- * @param {string} name The name of the cookie to set.
- * @param {string|object} value The value of cookie which will be set.
- */
-exports.setCookie = (ctx, value, name = "builder") => {
-  const expires = new Date()
-  expires.setDate(expires.getDate() + 1)
-
-  const cookieName = exports.getCookieName(name)
-  if (!value) {
-    ctx.cookies.set(cookieName)
-  } else {
-    ctx.cookies.set(cookieName, value, {
-      expires,
-      path: "/",
-      httpOnly: false,
-      overwrite: true,
-    })
-  }
-}
-
-/**
- * Utility function, simply calls setCookie with an empty string for value
- */
-exports.clearCookie = (ctx, name) => {
-  exports.setCookie(ctx, "", name)
-}
-
-/**
- * Checks if the API call being made (based on the provided ctx object) is from the client. If
- * the call is not from a client app then it is from the builder.
- * @param {object} ctx The koa context object to be tested.
- * @return {boolean} returns true if the call is from the client lib (a built app rather than the builder).
- */
-exports.isClient = ctx => {
-  return ctx.headers["x-budibase-type"] === "client"
-}
-
 /**
  * Lots of different points in the app need to find the full list of apps, this will
  * enumerate the entire CouchDB cluster and get the list of databases (every app).
diff --git a/packages/server/src/utilities/users.js b/packages/server/src/utilities/users.js
index f8246e4e91..fbed0ed5a9 100644
--- a/packages/server/src/utilities/users.js
+++ b/packages/server/src/utilities/users.js
@@ -11,10 +11,17 @@ exports.getFullUser = async ({ ctx, email, userId }) => {
   }
   const db = new CouchDB(ctx.appId)
   const global = await getGlobalUsers(ctx, ctx.appId, email)
-  const user = await db.get(generateUserMetadataID(email))
+  let metadata
+  try {
+    metadata = await db.get(generateUserMetadataID(email))
+  } catch (err) {
+    // it is fine if there is no user metadata, just remove global db info
+    delete global._id
+    delete global._rev
+  }
   return {
     ...global,
-    ...user,
+    ...metadata,
     // make sure the ID is always a local ID, not a global one
     _id: generateUserMetadataID(email),
   }