diff --git a/packages/server/src/api/routes/static.js b/packages/server/src/api/routes/static.js index 6e53f6d35f..14465f32a4 100644 --- a/packages/server/src/api/routes/static.js +++ b/packages/server/src/api/routes/static.js @@ -24,8 +24,10 @@ router.param("file", async (file, ctx, next) => { return next() }) +// only used in development for retrieving the client library, +// in production the client lib is always stored in the object store. if (env.isDev()) { - router.get("/assets/client", controller.serveClientLibrary) + router.get("/api/assets/client", controller.serveClientLibrary) } router diff --git a/packages/server/src/constants/index.js b/packages/server/src/constants/index.js index 379cfb8aa5..1e8ebb2721 100644 --- a/packages/server/src/constants/index.js +++ b/packages/server/src/constants/index.js @@ -1,5 +1,8 @@ const { BUILTIN_ROLE_IDS } = require("../utilities/security/roles") +exports.LOGO_URL = + "https://d33wubrfki0l68.cloudfront.net/aac32159d7207b5085e74a7ef67afbb7027786c5/2b1fd/img/logo/bb-emblem.svg" + exports.FieldTypes = { STRING: "string", LONGFORM: "longform", diff --git a/packages/server/src/constants/layouts.js b/packages/server/src/constants/layouts.js index b7b9af32b6..2ec657e817 100644 --- a/packages/server/src/constants/layouts.js +++ b/packages/server/src/constants/layouts.js @@ -1,4 +1,4 @@ -const { getLogoUrl } = require("../utilities") +const { LOGO_URL } = require("../constants") const BASE_LAYOUT_PROP_IDS = { PRIVATE: "layout_private_master", @@ -109,7 +109,7 @@ const BASE_LAYOUTS = [ active: {}, selected: {}, }, - logoUrl: getLogoUrl(), + logoUrl: LOGO_URL, title: "", backgroundColor: "", color: "", diff --git a/packages/server/src/constants/screens.js b/packages/server/src/constants/screens.js index 54dcc2551d..ac6112a63f 100644 --- a/packages/server/src/constants/screens.js +++ b/packages/server/src/constants/screens.js @@ -1,6 +1,6 @@ const { BUILTIN_ROLE_IDS } = require("../utilities/security/roles") const { BASE_LAYOUT_PROP_IDS } = require("./layouts") -const { getLogoUrl } = require("../utilities") +const { LOGO_URL } = require("../constants") exports.createHomeScreen = () => ({ description: "", @@ -92,7 +92,7 @@ exports.createLoginScreen = app => ({ active: {}, selected: {}, }, - logo: getLogoUrl(), + logo: LOGO_URL, title: `Log in to ${app.name}`, buttonText: "Log In", _children: [], diff --git a/packages/server/src/utilities/index.js b/packages/server/src/utilities/index.js index 5195c6d072..733afd2870 100644 --- a/packages/server/src/utilities/index.js +++ b/packages/server/src/utilities/index.js @@ -87,14 +87,23 @@ 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" } -exports.getLogoUrl = () => { - return "https://d33wubrfki0l68.cloudfront.net/aac32159d7207b5085e74a7ef67afbb7027786c5/2b1fd/img/logo/bb-emblem.svg" -} - +/** + * 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). + * NOTE: this operation is fine in self hosting, but cannot be used when hosting many + * different users/companies apps as there is no security around it - all apps are returned. + * @return {Promise} returns the app information document stored in each app database. + */ exports.getAllApps = async () => { let allDbs = await CouchDB.allDbs() const appDbNames = allDbs.filter(dbName => dbName.startsWith(APP_PREFIX)) @@ -109,10 +118,20 @@ exports.getAllApps = async () => { } } +/** + * Makes sure that a URL has the correct number of slashes, while maintaining the + * http(s):// double slashes. + * @param {string} url The URL to test and remove any extra double slashes. + * @return {string} The updated url. + */ exports.checkSlashesInUrl = url => { return url.replace(/(https?:\/\/)|(\/)+/g, "$1$2") } +/** + * Gets the address of the object store, depending on whether self hosted or in cloud. + * @return {string} The base URL of the object store (MinIO or S3). + */ exports.objectStoreUrl = () => { if (env.SELF_HOSTED) { // can use a relative url for this as all goes through the proxy (this is hosted in minio) @@ -122,10 +141,19 @@ exports.objectStoreUrl = () => { } } +/** + * In production the client library is stored in the object store, however in development + * we use the symlinked version produced by lerna, located in node modules. We link to this + * via a specific endpoint (under /api/assets/client). + * @param {string} appId In production we need the appId to look up the correct bucket, as the + * version of the client lib may differ between apps. + * @return {string} The URL to be inserted into appPackage response or server rendered + * app index file. + */ exports.clientLibraryPath = appId => { if (env.isProd()) { return `${exports.objectStoreUrl()}/${appId}/budibase-client.js` } else { - return `/assets/client` + return `/api/assets/client` } }