diff --git a/lerna.json b/lerna.json
index f4c90c684f..fc2b815e5c 100644
--- a/lerna.json
+++ b/lerna.json
@@ -1,5 +1,5 @@
{
- "version": "1.0.81-alpha.4",
+ "version": "1.0.81-alpha.7",
"npmClient": "yarn",
"packages": [
"packages/*"
diff --git a/packages/backend-core/package.json b/packages/backend-core/package.json
index 993b1ca946..be130ae5fc 100644
--- a/packages/backend-core/package.json
+++ b/packages/backend-core/package.json
@@ -1,6 +1,6 @@
{
"name": "@budibase/backend-core",
- "version": "1.0.81-alpha.4",
+ "version": "1.0.81-alpha.7",
"description": "Budibase backend core libraries used in server and worker",
"main": "src/index.js",
"author": "Budibase",
diff --git a/packages/backend-core/src/cloud/accounts.js b/packages/backend-core/src/cloud/accounts.js
index b2e8817ad6..5730bc67a5 100644
--- a/packages/backend-core/src/cloud/accounts.js
+++ b/packages/backend-core/src/cloud/accounts.js
@@ -22,3 +22,18 @@ exports.getAccount = async email => {
return json[0]
}
+
+exports.getStatus = async () => {
+ const response = await api.get(`/api/status`, {
+ headers: {
+ [Headers.API_KEY]: env.ACCOUNT_PORTAL_API_KEY,
+ },
+ })
+ const json = await response.json()
+
+ if (response.status !== 200) {
+ throw new Error(`Error getting status`)
+ }
+
+ return json
+}
diff --git a/packages/bbui/package.json b/packages/bbui/package.json
index 8308337ffd..5caca409b5 100644
--- a/packages/bbui/package.json
+++ b/packages/bbui/package.json
@@ -1,7 +1,7 @@
{
"name": "@budibase/bbui",
"description": "A UI solution used in the different Budibase projects.",
- "version": "1.0.81-alpha.4",
+ "version": "1.0.81-alpha.7",
"license": "MPL-2.0",
"svelte": "src/index.js",
"module": "dist/bbui.es.js",
@@ -38,7 +38,7 @@
],
"dependencies": {
"@adobe/spectrum-css-workflow-icons": "^1.2.1",
- "@budibase/string-templates": "^1.0.81-alpha.4",
+ "@budibase/string-templates": "^1.0.81-alpha.7",
"@spectrum-css/actionbutton": "^1.0.1",
"@spectrum-css/actiongroup": "^1.0.1",
"@spectrum-css/avatar": "^3.0.2",
diff --git a/packages/bbui/src/Banner/Banner.svelte b/packages/bbui/src/Banner/Banner.svelte
index f28ee09d9c..f41fb5f803 100644
--- a/packages/bbui/src/Banner/Banner.svelte
+++ b/packages/bbui/src/Banner/Banner.svelte
@@ -57,3 +57,10 @@
{/if}
+
+
diff --git a/packages/bbui/src/Banner/BannerDisplay.svelte b/packages/bbui/src/Banner/BannerDisplay.svelte
new file mode 100644
index 0000000000..aad742b1bd
--- /dev/null
+++ b/packages/bbui/src/Banner/BannerDisplay.svelte
@@ -0,0 +1,31 @@
+
+
+
+
+ {#if $banner.message}
+
+
+ {$banner.message}
+
+
+ {/if}
+
+
+
+
diff --git a/packages/bbui/src/Stores/banner.js b/packages/bbui/src/Stores/banner.js
new file mode 100644
index 0000000000..81a9ee2204
--- /dev/null
+++ b/packages/bbui/src/Stores/banner.js
@@ -0,0 +1,37 @@
+import { writable } from "svelte/store"
+
+export function createBannerStore() {
+ const DEFAULT_CONFIG = {}
+
+ const banner = writable(DEFAULT_CONFIG)
+
+ const show = async (
+ // eslint-disable-next-line
+ config = { message, type, extraButtonText, extraButtonAction, onChange }
+ ) => {
+ banner.update(store => {
+ return {
+ ...store,
+ ...config,
+ }
+ })
+ }
+
+ const showStatus = async () => {
+ const config = {
+ message: "Some systems are experiencing issues",
+ type: "negative",
+ extraButtonText: "View Status",
+ extraButtonAction: () => window.open("https://status.budibase.com/"),
+ }
+
+ await show(config)
+ }
+
+ return {
+ subscribe: banner.subscribe,
+ showStatus,
+ }
+}
+
+export const banner = createBannerStore()
diff --git a/packages/bbui/src/Stores/notifications.js b/packages/bbui/src/Stores/notifications.js
index 640f8218c4..74eed8628a 100644
--- a/packages/bbui/src/Stores/notifications.js
+++ b/packages/bbui/src/Stores/notifications.js
@@ -60,7 +60,7 @@ export const createNotificationStore = () => {
}
function id() {
- return "_" + Math.random().toString(36).substr(2, 9)
+ return "_" + Math.random().toString(36).slice(2, 9)
}
export const notifications = createNotificationStore()
diff --git a/packages/bbui/src/Tabs/Tabs.svelte b/packages/bbui/src/Tabs/Tabs.svelte
index 40e02058c1..6930a6cdb5 100644
--- a/packages/bbui/src/Tabs/Tabs.svelte
+++ b/packages/bbui/src/Tabs/Tabs.svelte
@@ -68,7 +68,7 @@
})
function id() {
- return "_" + Math.random().toString(36).substr(2, 9)
+ return "_" + Math.random().toString(36).slice(2, 9)
}
diff --git a/packages/bbui/src/index.js b/packages/bbui/src/index.js
index d3bc11cf9d..2b16f32b84 100644
--- a/packages/bbui/src/index.js
+++ b/packages/bbui/src/index.js
@@ -60,6 +60,7 @@ export { default as StatusLight } from "./StatusLight/StatusLight.svelte"
export { default as ColorPicker } from "./ColorPicker/ColorPicker.svelte"
export { default as InlineAlert } from "./InlineAlert/InlineAlert.svelte"
export { default as Banner } from "./Banner/Banner.svelte"
+export { default as BannerDisplay } from "./Banner/BannerDisplay.svelte"
export { default as MarkdownEditor } from "./Markdown/MarkdownEditor.svelte"
export { default as MarkdownViewer } from "./Markdown/MarkdownViewer.svelte"
export { default as RichTextField } from "./Form/RichTextField.svelte"
@@ -84,6 +85,7 @@ export { default as clickOutside } from "./Actions/click_outside"
// Stores
export { notifications, createNotificationStore } from "./Stores/notifications"
+export { banner } from "./Stores/banner"
// Helpers
export * as Helpers from "./helpers"
diff --git a/packages/builder/package.json b/packages/builder/package.json
index afe6b31c8a..bc81a17631 100644
--- a/packages/builder/package.json
+++ b/packages/builder/package.json
@@ -1,6 +1,6 @@
{
"name": "@budibase/builder",
- "version": "1.0.81-alpha.4",
+ "version": "1.0.81-alpha.7",
"license": "GPL-3.0",
"private": true,
"scripts": {
@@ -65,10 +65,10 @@
}
},
"dependencies": {
- "@budibase/bbui": "^1.0.81-alpha.4",
- "@budibase/client": "^1.0.81-alpha.4",
- "@budibase/frontend-core": "^1.0.81-alpha.4",
- "@budibase/string-templates": "^1.0.81-alpha.4",
+ "@budibase/bbui": "^1.0.81-alpha.7",
+ "@budibase/client": "^1.0.81-alpha.7",
+ "@budibase/frontend-core": "^1.0.81-alpha.7",
+ "@budibase/string-templates": "^1.0.81-alpha.7",
"@sentry/browser": "5.19.1",
"@spectrum-css/page": "^3.0.1",
"@spectrum-css/vars": "^3.0.1",
diff --git a/packages/builder/src/App.svelte b/packages/builder/src/App.svelte
index 60051ea043..0fb0fe59d5 100644
--- a/packages/builder/src/App.svelte
+++ b/packages/builder/src/App.svelte
@@ -1,13 +1,16 @@
+
+
+
diff --git a/packages/builder/src/pages/builder/portal/manage/users/_components/BasicOnboardingModal.svelte b/packages/builder/src/pages/builder/portal/manage/users/_components/BasicOnboardingModal.svelte
index 29e2d56ed0..8f01349765 100644
--- a/packages/builder/src/pages/builder/portal/manage/users/_components/BasicOnboardingModal.svelte
+++ b/packages/builder/src/pages/builder/portal/manage/users/_components/BasicOnboardingModal.svelte
@@ -11,7 +11,7 @@
import { users } from "stores/portal"
const [email, error, touched] = createValidationStore("", emailValidator)
- const password = Math.random().toString(36).substr(2, 20)
+ const password = Math.random().toString(36).slice(2, 20)
let builder = false,
admin = false
diff --git a/packages/builder/src/pages/builder/portal/manage/users/_components/ForceResetPasswordModal.svelte b/packages/builder/src/pages/builder/portal/manage/users/_components/ForceResetPasswordModal.svelte
index a380f0aa65..8a7a3940bf 100644
--- a/packages/builder/src/pages/builder/portal/manage/users/_components/ForceResetPasswordModal.svelte
+++ b/packages/builder/src/pages/builder/portal/manage/users/_components/ForceResetPasswordModal.svelte
@@ -7,7 +7,7 @@
export let user
- const password = Math.random().toString(36).substr(2, 20)
+ const password = Math.random().toString(36).slice(2, 20)
async function resetPassword() {
try {
diff --git a/packages/builder/src/stores/portal/admin.js b/packages/builder/src/stores/portal/admin.js
index dc68c43cc5..088d396291 100644
--- a/packages/builder/src/stores/portal/admin.js
+++ b/packages/builder/src/stores/portal/admin.js
@@ -1,6 +1,7 @@
import { writable, get } from "svelte/store"
import { API } from "api"
import { auth } from "stores/portal"
+import { banner } from "@budibase/bbui"
export function createAdminStore() {
const DEFAULT_CONFIG = {
@@ -30,6 +31,13 @@ export function createAdminStore() {
x => x?.checked
).length
await getEnvironment()
+
+ // enable system status checks in the cloud
+ if (get(admin).cloud) {
+ await getSystemStatus()
+ checkStatus()
+ }
+
admin.update(store => {
store.loaded = true
store.checklist = checklist
@@ -58,6 +66,21 @@ export function createAdminStore() {
})
}
+ const checkStatus = async () => {
+ const health = get(admin)?.status?.health
+ if (!health?.passing) {
+ await banner.showStatus()
+ }
+ }
+
+ async function getSystemStatus() {
+ const status = await API.getSystemStatus()
+ admin.update(store => {
+ store.status = status
+ return store
+ })
+ }
+
function unload() {
admin.update(store => {
store.loaded = false
diff --git a/packages/cli/package.json b/packages/cli/package.json
index bd734648c0..d938455bc0 100644
--- a/packages/cli/package.json
+++ b/packages/cli/package.json
@@ -1,6 +1,6 @@
{
"name": "@budibase/cli",
- "version": "1.0.81-alpha.4",
+ "version": "1.0.81-alpha.7",
"description": "Budibase CLI, for developers, self hosting and migrations.",
"main": "src/index.js",
"bin": {
diff --git a/packages/client/package.json b/packages/client/package.json
index 06ae8620ea..42ec4e7f1c 100644
--- a/packages/client/package.json
+++ b/packages/client/package.json
@@ -1,6 +1,6 @@
{
"name": "@budibase/client",
- "version": "1.0.81-alpha.4",
+ "version": "1.0.81-alpha.7",
"license": "MPL-2.0",
"module": "dist/budibase-client.js",
"main": "dist/budibase-client.js",
@@ -19,9 +19,9 @@
"dev:builder": "rollup -cw"
},
"dependencies": {
- "@budibase/bbui": "^1.0.81-alpha.4",
- "@budibase/frontend-core": "^1.0.81-alpha.4",
- "@budibase/string-templates": "^1.0.81-alpha.4",
+ "@budibase/bbui": "^1.0.81-alpha.7",
+ "@budibase/frontend-core": "^1.0.81-alpha.7",
+ "@budibase/string-templates": "^1.0.81-alpha.7",
"@spectrum-css/button": "^3.0.3",
"@spectrum-css/card": "^3.0.3",
"@spectrum-css/divider": "^1.0.3",
diff --git a/packages/frontend-core/package.json b/packages/frontend-core/package.json
index 8cf55845da..cd89b22102 100644
--- a/packages/frontend-core/package.json
+++ b/packages/frontend-core/package.json
@@ -1,12 +1,12 @@
{
"name": "@budibase/frontend-core",
- "version": "1.0.81-alpha.4",
+ "version": "1.0.81-alpha.7",
"description": "Budibase frontend core libraries used in builder and client",
"author": "Budibase",
"license": "MPL-2.0",
"svelte": "src/index.js",
"dependencies": {
- "@budibase/bbui": "^1.0.81-alpha.4",
+ "@budibase/bbui": "^1.0.81-alpha.7",
"lodash": "^4.17.21",
"svelte": "^3.46.2"
}
diff --git a/packages/frontend-core/src/api/other.js b/packages/frontend-core/src/api/other.js
index 71ea19ccce..6903a120db 100644
--- a/packages/frontend-core/src/api/other.js
+++ b/packages/frontend-core/src/api/other.js
@@ -17,6 +17,15 @@ export const buildOtherEndpoints = API => ({
})
},
+ /**
+ * Gets the current system status.
+ */
+ getSystemStatus: async () => {
+ return await API.get({
+ url: "/api/system/status",
+ })
+ },
+
/**
* Gets the list of available integrations.
*/
diff --git a/packages/server/package.json b/packages/server/package.json
index d514694f6f..5b45f0117e 100644
--- a/packages/server/package.json
+++ b/packages/server/package.json
@@ -1,7 +1,7 @@
{
"name": "@budibase/server",
"email": "hi@budibase.com",
- "version": "1.0.81-alpha.4",
+ "version": "1.0.81-alpha.7",
"description": "Budibase Web Server",
"main": "src/index.ts",
"repository": {
@@ -71,9 +71,9 @@
"license": "GPL-3.0",
"dependencies": {
"@apidevtools/swagger-parser": "^10.0.3",
- "@budibase/backend-core": "^1.0.81-alpha.4",
- "@budibase/client": "^1.0.81-alpha.4",
- "@budibase/string-templates": "^1.0.81-alpha.4",
+ "@budibase/backend-core": "^1.0.81-alpha.7",
+ "@budibase/client": "^1.0.81-alpha.7",
+ "@budibase/string-templates": "^1.0.81-alpha.7",
"@bull-board/api": "^3.7.0",
"@bull-board/koa": "^3.7.0",
"@elastic/elasticsearch": "7.10.0",
diff --git a/packages/server/scripts/docs/toSwagger.js b/packages/server/scripts/docs/toSwagger.js
index c9680143fc..1532e25fa6 100644
--- a/packages/server/scripts/docs/toSwagger.js
+++ b/packages/server/scripts/docs/toSwagger.js
@@ -51,7 +51,7 @@ function extractPaths(apidocJson) {
// Surrounds URL parameters with curly brackets -> :email with {email}
let pathKeys = []
for (let j = 1; j < matches.length; j++) {
- let key = matches[j].substr(1)
+ let key = matches[j].slice(1)
url = url.replace(matches[j], "{" + key + "}")
pathKeys.push(key)
}
diff --git a/packages/string-templates/package.json b/packages/string-templates/package.json
index 3fef167dcc..d542650223 100644
--- a/packages/string-templates/package.json
+++ b/packages/string-templates/package.json
@@ -1,6 +1,6 @@
{
"name": "@budibase/string-templates",
- "version": "1.0.81-alpha.4",
+ "version": "1.0.81-alpha.7",
"description": "Handlebars wrapper for Budibase templating.",
"main": "src/index.cjs",
"module": "dist/bundle.mjs",
diff --git a/packages/worker/package.json b/packages/worker/package.json
index 077b255e6b..2ce3b56c42 100644
--- a/packages/worker/package.json
+++ b/packages/worker/package.json
@@ -1,7 +1,7 @@
{
"name": "@budibase/worker",
"email": "hi@budibase.com",
- "version": "1.0.81-alpha.4",
+ "version": "1.0.81-alpha.7",
"description": "Budibase background service",
"main": "src/index.ts",
"repository": {
@@ -34,8 +34,8 @@
"author": "Budibase",
"license": "GPL-3.0",
"dependencies": {
- "@budibase/backend-core": "^1.0.81-alpha.4",
- "@budibase/string-templates": "^1.0.81-alpha.4",
+ "@budibase/backend-core": "^1.0.81-alpha.7",
+ "@budibase/string-templates": "^1.0.81-alpha.7",
"@koa/router": "^8.0.0",
"@sentry/node": "^6.0.0",
"@techpass/passport-openidconnect": "^0.3.0",
diff --git a/packages/worker/src/api/controllers/global/self.js b/packages/worker/src/api/controllers/global/self.js
index ea29c496e8..da4d82c46b 100644
--- a/packages/worker/src/api/controllers/global/self.js
+++ b/packages/worker/src/api/controllers/global/self.js
@@ -1,10 +1,20 @@
-const { getGlobalDB, getTenantId } = require("@budibase/backend-core/tenancy")
+const {
+ getGlobalDB,
+ getTenantId,
+ isUserInAppTenant,
+} = require("@budibase/backend-core/tenancy")
const { generateDevInfoID, SEPARATOR } = require("@budibase/backend-core/db")
const { user: userCache } = require("@budibase/backend-core/cache")
-const { hash, platformLogout } = require("@budibase/backend-core/utils")
+const {
+ hash,
+ platformLogout,
+ getCookie,
+ clearCookie,
+} = require("@budibase/backend-core/utils")
const { encrypt } = require("@budibase/backend-core/encryption")
const { newid } = require("@budibase/backend-core/utils")
const { getUser } = require("../../utilities")
+const { Cookies } = require("@budibase/backend-core/constants")
function newApiKey() {
return encrypt(`${getTenantId()}${SEPARATOR}${newid()}`)
@@ -48,6 +58,16 @@ exports.fetchAPIKey = async ctx => {
ctx.body = cleanupDevInfo(devInfo)
}
+const checkCurrentApp = ctx => {
+ const appCookie = getCookie(ctx, Cookies.CurrentApp)
+ if (appCookie && !isUserInAppTenant(appCookie.appId)) {
+ // there is a currentapp cookie from another tenant
+ // remove the cookie as this is incompatible with the builder
+ // due to builder and admin permissions being removed
+ clearCookie(ctx, Cookies.CurrentApp)
+ }
+}
+
exports.getSelf = async ctx => {
if (!ctx.user) {
ctx.throw(403, "User not logged in")
@@ -56,6 +76,9 @@ exports.getSelf = async ctx => {
ctx.params = {
id: userId,
}
+
+ checkCurrentApp(ctx)
+
// get the main body of the user
ctx.body = await getUser(userId)
// forward session information not found in db
diff --git a/packages/worker/src/api/controllers/system/status.js b/packages/worker/src/api/controllers/system/status.js
new file mode 100644
index 0000000000..9d2bd6ecda
--- /dev/null
+++ b/packages/worker/src/api/controllers/system/status.js
@@ -0,0 +1,15 @@
+const accounts = require("@budibase/backend-core/accounts")
+const env = require("../../../environment")
+
+exports.fetch = async ctx => {
+ if (!env.SELF_HOSTED && !env.DISABLE_ACCOUNT_PORTAL) {
+ const status = await accounts.getStatus()
+ ctx.body = status
+ } else {
+ ctx.body = {
+ health: {
+ passing: true,
+ },
+ }
+ }
+}
diff --git a/packages/worker/src/api/index.js b/packages/worker/src/api/index.js
index 76e45991ff..8be3c17866 100644
--- a/packages/worker/src/api/index.js
+++ b/packages/worker/src/api/index.js
@@ -39,7 +39,6 @@ const PUBLIC_ENDPOINTS = [
method: "GET",
},
{
- // TODO: Add an provisioning API key to this endpoint in the cloud
route: "/api/global/users/init",
method: "POST",
},
@@ -51,6 +50,10 @@ const PUBLIC_ENDPOINTS = [
route: "api/system/environment",
method: "GET",
},
+ {
+ route: "api/system/status",
+ method: "GET",
+ },
{
route: "/api/global/users/tenant/:id",
method: "GET",
diff --git a/packages/worker/src/api/routes/index.js b/packages/worker/src/api/routes/index.js
index b1c2435252..bc6e7842da 100644
--- a/packages/worker/src/api/routes/index.js
+++ b/packages/worker/src/api/routes/index.js
@@ -8,6 +8,7 @@ const roleRoutes = require("./global/roles")
const sessionRoutes = require("./global/sessions")
const environmentRoutes = require("./system/environment")
const tenantsRoutes = require("./system/tenants")
+const statusRoutes = require("./system/status")
const selfRoutes = require("./global/self")
exports.routes = [
@@ -21,5 +22,6 @@ exports.routes = [
sessionRoutes,
roleRoutes,
environmentRoutes,
+ statusRoutes,
selfRoutes,
]
diff --git a/packages/worker/src/api/routes/system/status.js b/packages/worker/src/api/routes/system/status.js
new file mode 100644
index 0000000000..a39801375b
--- /dev/null
+++ b/packages/worker/src/api/routes/system/status.js
@@ -0,0 +1,8 @@
+const Router = require("@koa/router")
+const controller = require("../../controllers/system/status")
+
+const router = Router()
+
+router.get("/api/system/status", controller.fetch)
+
+module.exports = router