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), }