Browse Source

Getting rid of the CLOUD environment variable, this makes no sense anymore, now there is isDev() and isProd() which will work out the current state of the cluster.

gh-pages
mike12345567 6 years ago
parent
commit
73cf53d149
  1. 1
      hosting/docker-compose.yaml
  2. 1
      packages/server/Dockerfile
  3. 1
      packages/server/scripts/dev/manage.js
  4. 5
      packages/server/src/api/controllers/application.js
  5. 4
      packages/server/src/api/controllers/auth.js
  6. 10
      packages/server/src/api/controllers/component.js
  7. 2
      packages/server/src/api/controllers/query.js
  8. 10
      packages/server/src/api/controllers/static/index.js
  9. 2
      packages/server/src/api/index.js
  10. 2
      packages/server/src/api/routes/static.js
  11. 4
      packages/server/src/api/routes/tests/apikeys.spec.js
  12. 9
      packages/server/src/api/routes/tests/hosting.spec.js
  13. 2
      packages/server/src/api/routes/tests/query.spec.js
  14. 2
      packages/server/src/api/routes/tests/row.spec.js
  15. 10
      packages/server/src/api/routes/tests/utilities/index.js
  16. 2
      packages/server/src/automations/actions.js
  17. 4
      packages/server/src/automations/index.js
  18. 2
      packages/server/src/automations/steps/createRow.js
  19. 2
      packages/server/src/automations/steps/createUser.js
  20. 2
      packages/server/src/automations/steps/deleteRow.js
  21. 32
      packages/server/src/automations/tests/automation.spec.js
  22. 10
      packages/server/src/automations/tests/createRow.spec.js
  23. 8
      packages/server/src/automations/tests/createUser.spec.js
  24. 8
      packages/server/src/automations/tests/deleteRow.spec.js
  25. 17
      packages/server/src/automations/tests/utilities/index.js
  26. 5
      packages/server/src/db/client.js
  27. 10
      packages/server/src/db/dynamoClient.js
  28. 21
      packages/server/src/environment.js
  29. 2
      packages/server/src/middleware/authorized.js
  30. 8
      packages/server/src/middleware/selfhost.js
  31. 21
      packages/server/src/middleware/tests/authorized.spec.js
  32. 35
      packages/server/src/middleware/tests/selfhost.spec.js
  33. 19
      packages/server/src/middleware/tests/usageQuota.spec.js
  34. 4
      packages/server/src/middleware/usageQuota.js
  35. 3
      packages/server/src/tests/utilities/TestConfiguration.js
  36. 10
      packages/server/src/utilities/builder/hosting.js
  37. 16
      packages/server/src/utilities/index.js
  38. 2
      packages/server/src/utilities/rowProcessor.js
  39. 5
      packages/server/src/utilities/usageQuota.js

1
hosting/docker-compose.yaml

@ -11,7 +11,6 @@ services:
- "${APP_PORT}:4002"
environment:
SELF_HOSTED: 1
CLOUD: 1
COUCH_DB_URL: http://${COUCH_DB_USER}:${COUCH_DB_PASSWORD}@couchdb-service:5984
WORKER_URL: http://worker-service:4003
MINIO_URL: http://minio-service:9000

1
packages/server/Dockerfile

@ -2,7 +2,6 @@ FROM node:12-alpine
WORKDIR /app
ENV CLOUD=1
ENV PORT=4001
ENV COUCH_DB_URL=https://couchdb.budi.live:5984
ENV BUDIBASE_ENVIRONMENT=PRODUCTION

1
packages/server/scripts/dev/manage.js

@ -43,7 +43,6 @@ async function init() {
COUCH_DB_PASSWORD: "budibase",
COUCH_DB_USER: "budibase",
SELF_HOSTED: 1,
CLOUD: 1,
}
let envFile = ""
Object.keys(envFileJson).forEach(key => {

5
packages/server/src/api/controllers/application.js

@ -30,8 +30,6 @@ const { getAllApps } = require("../../utilities")
const { USERS_TABLE_SCHEMA } = require("../../constants")
const {
getDeployedApps,
getHostingInfo,
HostingTypes,
} = require("../../utilities/builder/hosting")
const URL_REGEX_SLASH = /\/|\\/g
@ -71,8 +69,7 @@ async function getAppUrlIfNotInUse(ctx) {
url = encodeURI(`${ctx.request.body.name}`)
}
url = `/${url.replace(URL_REGEX_SLASH, "")}`.toLowerCase()
const hostingInfo = await getHostingInfo()
if (hostingInfo.type === HostingTypes.CLOUD) {
if (!env.SELF_HOSTED) {
return url
}
const deployedApps = await getDeployedApps()

4
packages/server/src/api/controllers/auth.js

@ -45,9 +45,9 @@ exports.authenticate = async ctx => {
roleId: dbUser.roleId,
version: app.version,
}
// if in cloud add the user api key, unless self hosted
// if in prod add the user api key, unless self hosted
/* istanbul ignore next */
if (env.CLOUD && !env.SELF_HOSTED) {
if (env.isProd() && !env.SELF_HOSTED) {
const { apiKey } = await getAPIKey(ctx.user.appId)
payload.apiKey = apiKey
}

10
packages/server/src/api/controllers/component.js

@ -2,6 +2,7 @@ const CouchDB = require("../../db")
const { join } = require("../../utilities/centralPath")
const { budibaseTempDir } = require("../../utilities/budibaseDir")
const fileSystem = require("../../utilities/fileSystem")
const env = require("../../environment")
exports.fetchAppComponentDefinitions = async function(ctx) {
const appId = ctx.params.appId || ctx.appId
@ -11,13 +12,8 @@ exports.fetchAppComponentDefinitions = async function(ctx) {
let componentManifests = await Promise.all(
app.componentLibraries.map(async library => {
let manifest
if (ctx.isDev) {
manifest = require(join(
budibaseTempDir(),
library,
ctx.isDev ? "" : "package",
"manifest.json"
))
if (env.isDev()) {
manifest = require(join(budibaseTempDir(), library, "manifest.json"))
} else {
manifest = await fileSystem.getComponentLibraryManifest(appId, library)
}

2
packages/server/src/api/controllers/query.js

@ -93,7 +93,7 @@ exports.find = async function(ctx) {
const db = new CouchDB(ctx.user.appId)
const query = enrichQueries(await db.get(ctx.params.queryId))
// remove properties that could be dangerous in real app
if (env.CLOUD) {
if (env.isProd()) {
delete query.fields
delete query.parameters
delete query.schema

10
packages/server/src/api/controllers/static/index.js

@ -87,7 +87,7 @@ exports.serveApp = async function(ctx) {
const { head, html, css } = App.render({
title: appInfo.name,
production: env.CLOUD,
production: env.isProd(),
appId,
objectStoreUrl: objectStoreUrl(),
})
@ -106,7 +106,7 @@ exports.serveAttachment = async function(ctx) {
const attachmentsPath = resolve(budibaseAppsDir(), appId, "attachments")
// Serve from object store
if (env.CLOUD) {
if (env.isProd()) {
const S3_URL = join(objectStoreUrl(), appId, "attachments", ctx.file)
const response = await fetch(S3_URL)
const body = await response.text()
@ -137,15 +137,13 @@ exports.serveComponentLibrary = async function(ctx) {
"dist"
)
if (ctx.isDev) {
if (env.isDev()) {
componentLibraryPath = join(
budibaseTempDir(),
decodeURI(ctx.query.library),
"dist"
)
}
if (env.CLOUD) {
} else {
let componentLib = "componentlibrary"
if (ctx.user.version) {
componentLib += `-${ctx.user.version}`

2
packages/server/src/api/index.js

@ -3,7 +3,6 @@ const authenticated = require("../middleware/authenticated")
const compress = require("koa-compress")
const zlib = require("zlib")
const { budibaseAppsDir } = require("../utilities/budibaseDir")
const { isDev } = require("../utilities")
const { mainRoutes, authRoutes, staticRoutes } = require("./routes")
const pkg = require("../../package.json")
@ -29,7 +28,6 @@ router
jwtSecret: env.JWT_SECRET,
useAppRootPath: true,
}
ctx.isDev = isDev()
await next()
})
.use("/health", ctx => (ctx.status = 200))

2
packages/server/src/api/routes/static.js

@ -13,7 +13,7 @@ router.param("file", async (file, ctx, next) => {
ctx.file = file && file.includes(".") ? file : "index.html"
// Serving the client library from your local dir in dev
if (ctx.isDev && ctx.file.startsWith("budibase-client")) {
if (env.isDev() && ctx.file.startsWith("budibase-client")) {
ctx.devPath = budibaseTempDir()
}

4
packages/server/src/api/routes/tests/apikeys.spec.js

@ -13,7 +13,7 @@ describe("/api/keys", () => {
describe("fetch", () => {
it("should allow fetching", async () => {
await setup.switchToCloudForFunction(async () => {
await setup.switchToSelfHosted(async () => {
const res = await request
.get(`/api/keys`)
.set(config.defaultHeaders())
@ -34,7 +34,7 @@ describe("/api/keys", () => {
describe("update", () => {
it("should allow updating a value", async () => {
await setup.switchToCloudForFunction(async () => {
await setup.switchToSelfHosted(async () => {
const res = await request
.put(`/api/keys/TEST`)
.send({

9
packages/server/src/api/routes/tests/hosting.spec.js

@ -107,17 +107,16 @@ describe("/hosting", () => {
})
describe("getDeployedApps", () => {
it("should get apps when in builder", async () => {
const res = await request
it("should fail when not self hosted", async () => {
await request
.get(`/api/hosting/apps`)
.set(config.defaultHeaders())
.expect("Content-Type", /json/)
.expect(200)
expect(res.body.app1).toEqual({url: "/app1"})
.expect(400)
})
it("should get apps when in cloud", async () => {
await setup.switchToCloudForFunction(async () => {
await setup.switchToSelfHosted(async () => {
const res = await request
.get(`/api/hosting/apps`)
.set(config.defaultHeaders())

2
packages/server/src/api/routes/tests/query.spec.js

@ -89,7 +89,7 @@ describe("/queries", () => {
})
it("should find a query in cloud", async () => {
await setup.switchToCloudForFunction(async () => {
await setup.switchToSelfHosted(async () => {
const query = await config.createQuery()
const res = await request
.get(`/api/queries/${query._id}`)

2
packages/server/src/api/routes/tests/row.spec.js

@ -410,7 +410,7 @@ describe("/rows", () => {
tableId: table._id,
})
// the environment needs configured for this
await setup.switchToCloudForFunction(async () => {
await setup.switchToSelfHosted(async () => {
const enriched = await outputProcessing(config.getAppId(), table, [row])
expect(enriched[0].attachment[0].url).toBe(`/app-assets/assets/${config.getAppId()}/test/thing`)
})

10
packages/server/src/api/routes/tests/utilities/index.js

@ -35,18 +35,18 @@ exports.getConfig = () => {
return config
}
exports.switchToCloudForFunction = async func => {
exports.switchToSelfHosted = async func => {
// self hosted stops any attempts to Dynamo
env.CLOUD = true
env.SELF_HOSTED = true
env._set("NODE_ENV", "production")
env._set("SELF_HOSTED", true)
let error
try {
await func()
} catch (err) {
error = err
}
env.CLOUD = false
env.SELF_HOSTED = false
env._set("NODE_ENV", "jest")
env._set("SELF_HOSTED", false)
// don't throw error until after reset
if (error) {
throw error

2
packages/server/src/automations/actions.js

@ -41,7 +41,7 @@ module.exports.getAction = async function(actionName) {
return BUILTIN_ACTIONS[actionName]
}
// worker pools means that a worker may not have manifest
if (env.CLOUD && MANIFEST == null) {
if (env.isProd() && MANIFEST == null) {
MANIFEST = await module.exports.init()
}
// env setup to get async packages

4
packages/server/src/automations/index.js

@ -34,10 +34,10 @@ module.exports.init = async function() {
await actions.init()
triggers.automationQueue.process(async job => {
try {
if (env.CLOUD && job.data.automation && !env.SELF_HOSTED) {
if (env.USE_QUOTAS) {
job.data.automation.apiKey = await updateQuota(job.data.automation)
}
if (env.BUDIBASE_ENVIRONMENT === "PRODUCTION") {
if (env.isProd()) {
await runWorker(job)
} else {
await singleThread(job)

2
packages/server/src/automations/steps/createRow.js

@ -85,7 +85,7 @@ module.exports.run = async function({ inputs, appId, apiKey, emitter }) {
inputs.row.tableId,
inputs.row
)
if (env.CLOUD) {
if (env.isProd()) {
await usage.update(apiKey, usage.Properties.ROW, 1)
}
await rowController.save(ctx)

2
packages/server/src/automations/steps/createUser.js

@ -72,7 +72,7 @@ module.exports.run = async function({ inputs, appId, apiKey, emitter }) {
}
try {
if (env.CLOUD) {
if (env.isProd()) {
await usage.update(apiKey, usage.Properties.USER, 1)
}
await userController.create(ctx)

2
packages/server/src/automations/steps/deleteRow.js

@ -70,7 +70,7 @@ module.exports.run = async function({ inputs, appId, apiKey, emitter }) {
}
try {
if (env.CLOUD) {
if (env.isProd()) {
await usage.update(apiKey, usage.Properties.ROW, -1)
}
await rowController.destroy(ctx)

32
packages/server/src/automations/tests/automation.spec.js

@ -47,27 +47,23 @@ describe("Run through some parts of the automations system", () => {
expect(thread).toHaveBeenCalled()
})
it("should be able to init in cloud", async () => {
env.CLOUD = true
env.BUDIBASE_ENVIRONMENT = "PRODUCTION"
await triggers.externalTrigger(basicAutomation(), { a: 1 })
await wait(100)
// haven't added a mock implementation so getAPIKey of usageQuota just returns undefined
expect(usageQuota.update).toHaveBeenCalledWith("test", "automationRuns", 1)
expect(workerJob).toBeDefined()
env.BUDIBASE_ENVIRONMENT = "JEST"
env.CLOUD = false
it("should be able to init in prod", async () => {
await setup.runInProd(async () => {
await triggers.externalTrigger(basicAutomation(), { a: 1 })
await wait(100)
// haven't added a mock implementation so getAPIKey of usageQuota just returns undefined
expect(usageQuota.update).toHaveBeenCalledWith("test", "automationRuns", 1)
expect(workerJob).toBeDefined()
})
})
it("try error scenario", async () => {
env.CLOUD = true
env.BUDIBASE_ENVIRONMENT = "PRODUCTION"
// the second call will throw an error
await triggers.externalTrigger(basicAutomation(), { a: 1 })
await wait(100)
expect(console.error).toHaveBeenCalled()
env.BUDIBASE_ENVIRONMENT = "JEST"
env.CLOUD = false
await setup.runInProd(async () => {
// the second call will throw an error
await triggers.externalTrigger(basicAutomation(), { a: 1 })
await wait(100)
expect(console.error).toHaveBeenCalled()
})
})
it("should be able to check triggering row filling", async () => {

10
packages/server/src/automations/tests/createRow.spec.js

@ -42,12 +42,12 @@ describe("test the create row action", () => {
})
it("check usage quota attempts", async () => {
env.CLOUD = true
await setup.runStep(setup.actions.CREATE_ROW.stepId, {
row
await setup.runInProd(async () => {
await setup.runStep(setup.actions.CREATE_ROW.stepId, {
row
})
expect(usageQuota.update).toHaveBeenCalledWith(setup.apiKey, "rows", 1)
})
expect(usageQuota.update).toHaveBeenCalledWith(setup.apiKey, "rows", 1)
env.CLOUD = false
})
it("should check invalid inputs return an error", async () => {

8
packages/server/src/automations/tests/createUser.spec.js

@ -35,9 +35,9 @@ describe("test the create user action", () => {
})
it("check usage quota attempts", async () => {
env.CLOUD = true
await setup.runStep(setup.actions.CREATE_USER.stepId, user)
expect(usageQuota.update).toHaveBeenCalledWith(setup.apiKey, "users", 1)
env.CLOUD = false
await setup.runInProd(async () => {
await setup.runStep(setup.actions.CREATE_USER.stepId, user)
expect(usageQuota.update).toHaveBeenCalledWith(setup.apiKey, "users", 1)
})
})
})

8
packages/server/src/automations/tests/deleteRow.spec.js

@ -36,10 +36,10 @@ describe("test the delete row action", () => {
})
it("check usage quota attempts", async () => {
env.CLOUD = true
await setup.runStep(setup.actions.DELETE_ROW.stepId, inputs)
expect(usageQuota.update).toHaveBeenCalledWith(setup.apiKey, "rows", -1)
env.CLOUD = false
await setup.runInProd(async () => {
await setup.runStep(setup.actions.DELETE_ROW.stepId, inputs)
expect(usageQuota.update).toHaveBeenCalledWith(setup.apiKey, "rows", -1)
})
})
it("should check invalid inputs return an error", async () => {

17
packages/server/src/automations/tests/utilities/index.js

@ -2,6 +2,7 @@ const TestConfig = require("../../../tests/utilities/TestConfiguration")
const actions = require("../../actions")
const logic = require("../../logic")
const emitter = require("../../../events/index")
const env = require("../../../environment")
let config
@ -16,6 +17,22 @@ exports.afterAll = () => {
config.end()
}
exports.runInProd = async fn => {
env._set("NODE_ENV", "production")
env._set("USE_QUOTAS", 1)
let error
try {
await fn()
} catch (err) {
error = err
}
env._set("NODE_ENV", "jest")
env._set("USE_QUOTAS", null)
if (error) {
throw error
}
}
exports.runStep = async function runStep(stepId, inputs) {
let step
if (

5
packages/server/src/db/client.js

@ -5,7 +5,6 @@ const find = require("pouchdb-find")
const env = require("../environment")
const COUCH_DB_URL = env.COUCH_DB_URL || "http://localhost:10000/db/"
const isInMemory = env.NODE_ENV === "jest"
PouchDB.plugin(replicationStream.plugin)
PouchDB.plugin(find)
@ -13,10 +12,10 @@ PouchDB.adapter("writableStream", replicationStream.adapters.writableStream)
let POUCH_DB_DEFAULTS = {
prefix: COUCH_DB_URL,
skip_setup: !!env.CLOUD,
skip_setup: env.isProd(),
}
if (isInMemory) {
if (env.isTest()) {
PouchDB.plugin(require("pouchdb-adapter-memory"))
POUCH_DB_DEFAULTS = {
prefix: undefined,

10
packages/server/src/db/dynamoClient.js

@ -1,4 +1,4 @@
let _ = require("lodash")
let { merge } = require("lodash")
let env = require("../environment")
const AWS_REGION = env.AWS_REGION ? env.AWS_REGION : "eu-west-1"
@ -38,7 +38,7 @@ class Table {
params.Key[this._sort] = sort
}
if (otherProps) {
params = _.merge(params, otherProps)
params = merge(params, otherProps)
}
let response = await docClient.get(params).promise()
return response.Item
@ -77,7 +77,7 @@ class Table {
params.ConditionExpression += "attribute_exists(#PRIMARY)"
}
if (otherProps) {
params = _.merge(params, otherProps)
params = merge(params, otherProps)
}
return docClient.update(params).promise()
}
@ -94,7 +94,7 @@ class Table {
Item: item,
}
if (otherProps) {
params = _.merge(params, otherProps)
params = merge(params, otherProps)
}
return docClient.put(params).promise()
}
@ -119,7 +119,7 @@ exports.init = endpoint => {
exports.apiKeyTable = new Table(TableInfo.API_KEYS)
exports.userTable = new Table(TableInfo.USERS)
if (env.CLOUD) {
if (env.isProd()) {
exports.init(`https://dynamodb.${AWS_REGION}.amazonaws.com`)
} else {
env._set("AWS_ACCESS_KEY_ID", "KEY_ID")

21
packages/server/src/environment.js

@ -1,15 +1,20 @@
function isTest() {
return (
process.env.NODE_ENV === "jest" ||
process.env.NODE_ENV === "cypress" ||
process.env.JEST_WORKER_ID != null
)
}
function isDev() {
return (
!process.env.CLOUD &&
process.env.NODE_ENV !== "production" &&
process.env.NODE_ENV !== "jest" &&
process.env.NODE_ENV !== "cypress" &&
process.env.JEST_WORKER_ID == null
process.env.BUDIBASE_ENVIRONMENT !== "production"
)
}
let LOADED = false
if (!LOADED && isDev()) {
if (!LOADED && isDev() && !isTest()) {
require("dotenv").config()
LOADED = true
}
@ -21,12 +26,12 @@ module.exports = {
COUCH_DB_URL: process.env.COUCH_DB_URL,
MINIO_URL: process.env.MINIO_URL,
WORKER_URL: process.env.WORKER_URL,
CLOUD: process.env.CLOUD,
SELF_HOSTED: process.env.SELF_HOSTED,
AWS_REGION: process.env.AWS_REGION,
ENABLE_ANALYTICS: process.env.ENABLE_ANALYTICS,
MINIO_ACCESS_KEY: process.env.MINIO_ACCESS_KEY,
MINIO_SECRET_KEY: process.env.MINIO_SECRET_KEY,
USE_QUOTAS: process.env.USE_QUOTAS,
// environment
NODE_ENV: process.env.NODE_ENV,
JEST_WORKER_ID: process.env.JEST_WORKER_ID,
@ -51,5 +56,9 @@ module.exports = {
process.env[key] = value
module.exports[key] = value
},
isTest,
isDev,
isProd: () => {
return !isDev()
},
}

2
packages/server/src/middleware/authorized.js

@ -18,7 +18,7 @@ function hasResource(ctx) {
}
module.exports = (permType, permLevel = null) => async (ctx, next) => {
if (env.CLOUD && ctx.headers["x-api-key"] && ctx.headers["x-instanceid"]) {
if (env.isProd() && ctx.headers["x-api-key"] && ctx.headers["x-instanceid"]) {
// api key header passed by external webhook
if (await isAPIKeyValid(ctx.headers["x-api-key"])) {
ctx.auth = {

8
packages/server/src/middleware/selfhost.js

@ -1,14 +1,8 @@
const env = require("../environment")
const hosting = require("../utilities/builder/hosting")
// if added as a middleware will stop requests unless builder is in self host mode
// or cloud is in self host
module.exports = async (ctx, next) => {
if (env.CLOUD && env.SELF_HOSTED) {
await next()
return
}
const hostingInfo = await hosting.getHostingInfo()
if (hostingInfo.type === hosting.HostingTypes.SELF) {
if (env.SELF_HOSTED) {
await next()
return
}

21
packages/server/src/middleware/tests/authorized.spec.js

@ -3,8 +3,15 @@ const env = require("../../environment")
const apiKey = require("../../utilities/security/apikey")
const { AuthTypes } = require("../../constants")
const { PermissionTypes, PermissionLevels } = require("../../utilities/security/permissions")
const { Test } = require("supertest")
jest.mock("../../environment")
jest.mock("../../environment", () => ({
prod: false,
isTest: () => true,
isProd: () => this.prod,
_set: (key, value) => {
this.prod = value === "production"
}
})
)
jest.mock("../../utilities/security/apikey")
class TestConfiguration {
@ -47,8 +54,8 @@ class TestConfiguration {
this.ctx.request.url = url
}
setCloudEnv(isCloud) {
env.CLOUD = isCloud
setEnvironment(isProd) {
env._set("NODE_ENV", isProd ? "production" : "jest")
}
setRequestHeaders(headers) {
@ -79,7 +86,7 @@ describe("Authorization middleware", () => {
beforeEach(() => {
config = new TestConfiguration()
config.setCloudEnv(true)
config.setEnvironment(true)
config.setRequestHeaders({
"x-api-key": "abc123",
"x-instanceid": "instance123",
@ -115,7 +122,7 @@ describe("Authorization middleware", () => {
beforeEach(() => {
config = new TestConfiguration()
config.setCloudEnv(true)
config.setEnvironment(true)
config.setAuthenticated(true)
})
@ -138,7 +145,7 @@ describe("Authorization middleware", () => {
})
it("throws if the user has only builder permissions", async () => {
config.setCloudEnv(false)
config.setEnvironment(false)
config.setMiddlewareRequiredPermission(PermissionTypes.BUILDER)
config.setUser({
role: {

35
packages/server/src/middleware/tests/selfhost.spec.js

@ -1,6 +1,5 @@
const selfHostMiddleware = require("../selfhost");
const selfHostMiddleware = require("../selfhost")
const env = require("../../environment")
const hosting = require("../../utilities/builder/hosting");
jest.mock("../../environment")
jest.mock("../../utilities/builder/hosting")
@ -20,16 +19,6 @@ class TestConfiguration {
return this.middleware(this.ctx, this.next)
}
setCloudHosted() {
env.CLOUD = 1
env.SELF_HOSTED = 0
}
setSelfHosted() {
env.CLOUD = 0
env.SELF_HOSTED = 1
}
afterEach() {
jest.clearAllMocks()
}
@ -46,30 +35,10 @@ describe("Self host middleware", () => {
config.afterEach()
})
it("calls next() when CLOUD and SELF_HOSTED env vars are set", async () => {
env.CLOUD = 1
it("calls next() when SELF_HOSTED env var is set", async () => {
env.SELF_HOSTED = 1
await config.executeMiddleware()
expect(config.next).toHaveBeenCalled()
})
it("throws when hostingInfo type is cloud", async () => {
config.setSelfHosted()
hosting.getHostingInfo.mockImplementationOnce(() => ({ type: hosting.HostingTypes.CLOUD }))
await config.executeMiddleware()
expect(config.throw).toHaveBeenCalledWith(400, "Endpoint unavailable in cloud hosting.")
expect(config.next).not.toHaveBeenCalled()
})
it("calls the self hosting middleware to pass through to next() when the hostingInfo type is self", async () => {
config.setSelfHosted()
hosting.getHostingInfo.mockImplementationOnce(() => ({ type: hosting.HostingTypes.SELF }))
await config.executeMiddleware()
expect(config.next).toHaveBeenCalled()
})
})

19
packages/server/src/middleware/tests/usageQuota.spec.js

@ -5,7 +5,12 @@ const env = require("../../environment")
jest.mock("../../db")
jest.mock("../../utilities/usageQuota")
jest.mock("../../environment")
jest.mock("../../environment", () => ({
isTest: () => true,
isProd: () => false,
isDev: () => true,
_set: () => {},
}))
class TestConfiguration {
constructor() {
@ -32,12 +37,14 @@ class TestConfiguration {
return this.middleware(this.ctx, this.next)
}
cloudHosted(bool) {
setProd(bool) {
if (bool) {
env.CLOUD = 1
env.isDev = () => false
env.isProd = () => true
this.ctx.auth = { apiKey: "test" }
} else {
env.CLOUD = 0
env.isDev = () => true
env.isProd = () => false
}
}
@ -102,7 +109,7 @@ describe("usageQuota middleware", () => {
it("calculates and persists the correct usage quota for the relevant action", async () => {
config.setUrl("/rows")
config.cloudHosted(true)
config.setProd(true)
await config.executeMiddleware()
@ -112,7 +119,7 @@ describe("usageQuota middleware", () => {
it("calculates the correct file size from a file upload call and adds it to quota", async () => {
config.setUrl("/upload")
config.cloudHosted(true)
config.setProd(true)
config.setFiles([
{
size: 100

4
packages/server/src/middleware/usageQuota.js

@ -44,8 +44,8 @@ module.exports = async (ctx, next) => {
}
}
// if running in builder or a self hosted cloud usage quotas should not be executed
if (!env.CLOUD || env.SELF_HOSTED) {
// if in development or a self hosted cloud usage quotas should not be executed
if (env.isDev() || env.SELF_HOSTED) {
return next()
}
// update usage for uploads to be the total size

3
packages/server/src/tests/utilities/TestConfiguration.js

@ -71,7 +71,8 @@ class TestConfiguration {
roleId: BUILTIN_ROLE_IDS.BUILDER,
}
const builderToken = jwt.sign(builderUser, env.JWT_SECRET)
const type = env.CLOUD ? "cloud" : "local"
// can be "production" for test case
const type = env.isProd() ? "cloud" : "local"
const headers = {
Accept: "application/json",
Cookie: [`budibase:builder:${type}=${builderToken}`],

10
packages/server/src/utilities/builder/hosting.js

@ -85,15 +85,11 @@ exports.getTemplatesUrl = async (appId, type, name) => {
}
exports.getDeployedApps = async () => {
const hostingInfo = await exports.getHostingInfo()
if (
(!env.CLOUD && hostingInfo.type === exports.HostingTypes.CLOUD) ||
(env.CLOUD && !env.SELF_HOSTED)
) {
if (!env.SELF_HOSTED) {
throw "Can only check apps for self hosted environments"
}
const workerUrl = !env.CLOUD ? await exports.getWorkerUrl() : env.WORKER_URL
const hostingKey = !env.CLOUD ? hostingInfo.selfHostKey : env.HOSTING_KEY
const workerUrl = env.WORKER_URL
const hostingKey = env.HOSTING_KEY
try {
const response = await fetch(`${workerUrl}/api/apps`, {
method: "GET",

16
packages/server/src/utilities/index.js

@ -20,10 +20,18 @@ exports.isDev = env.isDev
* @returns {string|undefined} If an appId was found it will be returned.
*/
exports.getAppId = ctx => {
let appId = confirmAppId(ctx.headers["x-budibase-app-id"])
if (!appId) {
appId = confirmAppId(env.CLOUD ? ctx.subdomains[1] : ctx.params.appId)
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)
@ -43,7 +51,7 @@ exports.getAppId = ctx => {
* @returns {string} The name of the token trying to find
*/
exports.getCookieName = (name = "builder") => {
let environment = env.CLOUD ? "cloud" : "local"
let environment = env.isProd() ? "cloud" : "local"
return `budibase:${name}:${environment}`
}

2
packages/server/src/utilities/rowProcessor.js

@ -180,7 +180,7 @@ exports.outputProcessing = async (appId, table, rows) => {
rows
)
// update the attachments URL depending on hosting
if (env.CLOUD && env.SELF_HOSTED) {
if (env.isProd() && env.SELF_HOSTED) {
for (let [property, column] of Object.entries(table.schema)) {
if (column.type === FieldTypes.ATTACHMENT) {
for (let row of outputRows) {

5
packages/server/src/utilities/usageQuota.js

@ -50,7 +50,7 @@ exports.Properties = {
}
exports.getAPIKey = async appId => {
if (env.SELF_HOSTED) {
if (!env.USE_QUOTAS) {
return { apiKey: null }
}
return apiKeyTable.get({ primary: appId })
@ -65,8 +65,7 @@ exports.getAPIKey = async appId => {
* also been reset after this call.
*/
exports.update = async (apiKey, property, usage) => {
// don't try validate in builder
if (!env.CLOUD || env.SELF_HOSTED) {
if (!env.USE_QUOTAS) {
return
}
try {

Loading…
Cancel
Save