@budibase/backend-core 2.8.31-alpha.0 → 2.8.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/jest.config.js +4 -10
- package/dist/jest.config.js.map +1 -1
- package/dist/package.json +26 -14
- package/dist/src/auth/auth.js.map +1 -1
- package/dist/src/cache/appMetadata.d.ts +1 -7
- package/dist/src/cache/appMetadata.js +8 -5
- package/dist/src/cache/appMetadata.js.map +1 -1
- package/dist/src/cache/user.js.map +1 -1
- package/dist/src/constants/db.d.ts +39 -1
- package/dist/src/constants/db.js +43 -8
- package/dist/src/constants/db.js.map +1 -1
- package/dist/src/constants/misc.d.ts +0 -2
- package/dist/src/constants/misc.js +0 -2
- package/dist/src/constants/misc.js.map +1 -1
- package/dist/src/db/couch/index.d.ts +0 -1
- package/dist/src/db/couch/index.js +0 -1
- package/dist/src/db/couch/index.js.map +1 -1
- package/dist/src/db/searchIndexes/searchIndexes.js.map +1 -1
- package/dist/src/db/utils.js +2 -7
- package/dist/src/db/utils.js.map +1 -1
- package/dist/src/db/views.d.ts +1 -0
- package/dist/src/db/views.js +12 -1
- package/dist/src/db/views.js.map +1 -1
- package/dist/src/environment.d.ts +4 -11
- package/dist/src/environment.js +70 -21
- package/dist/src/environment.js.map +1 -1
- package/dist/src/events/identification.js +3 -3
- package/dist/src/events/identification.js.map +1 -1
- package/dist/src/logging/index.d.ts +1 -1
- package/dist/src/logging/index.js +3 -2
- package/dist/src/logging/index.js.map +1 -1
- package/dist/src/logging/pino/logger.js +24 -40
- package/dist/src/logging/pino/logger.js.map +1 -1
- package/dist/src/middleware/adminOnly.d.ts +2 -2
- package/dist/src/middleware/adminOnly.js +2 -2
- package/dist/src/middleware/adminOnly.js.map +1 -1
- package/dist/src/middleware/builderOnly.d.ts +2 -2
- package/dist/src/middleware/builderOnly.js +2 -16
- package/dist/src/middleware/builderOnly.js.map +1 -1
- package/dist/src/middleware/builderOrAdmin.d.ts +2 -2
- package/dist/src/middleware/builderOrAdmin.js +4 -17
- package/dist/src/middleware/builderOrAdmin.js.map +1 -1
- package/dist/src/security/permissions.d.ts +18 -31
- package/dist/src/security/permissions.js +57 -46
- package/dist/src/security/permissions.js.map +1 -1
- package/dist/src/security/roles.js +4 -7
- package/dist/src/security/roles.js.map +1 -1
- package/dist/src/{users/users.d.ts → users.d.ts} +2 -4
- package/dist/src/{users/users.js → users.js} +4 -24
- package/dist/src/users.js.map +1 -0
- package/dist/tests/core/utilities/jestUtils.d.ts +0 -7
- package/dist/tests/core/utilities/jestUtils.js +1 -14
- package/dist/tests/core/utilities/jestUtils.js.map +1 -1
- package/dist/tests/core/utilities/mocks/events.d.ts +1 -0
- package/dist/tests/core/utilities/mocks/events.js +1 -0
- package/dist/tests/core/utilities/mocks/events.js.map +1 -1
- package/dist/tests/core/utilities/mocks/licenses.d.ts +0 -1
- package/dist/tests/core/utilities/mocks/licenses.js +4 -8
- package/dist/tests/core/utilities/mocks/licenses.js.map +1 -1
- package/dist/tests/core/utilities/structures/accounts.js +3 -3
- package/dist/tests/core/utilities/structures/accounts.js.map +1 -1
- package/dist/tests/core/utilities/structures/scim.js +5 -1
- package/dist/tests/core/utilities/structures/scim.js.map +1 -1
- package/dist/tests/core/utilities/structures/sso.js +2 -2
- package/dist/tests/core/utilities/structures/sso.js.map +1 -1
- package/dist/tests/core/utilities/structures/users.d.ts +1 -3
- package/dist/tests/core/utilities/structures/users.js +1 -13
- package/dist/tests/core/utilities/structures/users.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/jest.config.ts +2 -1
- package/package.json +26 -14
- package/scripts/test.sh +2 -2
- package/src/auth/auth.ts +1 -1
- package/src/cache/appMetadata.ts +8 -10
- package/src/cache/tests/writethrough.spec.ts +7 -7
- package/src/cache/user.ts +1 -1
- package/src/constants/db.ts +42 -4
- package/src/constants/misc.ts +0 -2
- package/src/db/couch/index.ts +0 -1
- package/src/db/searchIndexes/searchIndexes.ts +1 -1
- package/src/db/utils.ts +3 -9
- package/src/db/views.ts +11 -0
- package/src/environment.ts +4 -24
- package/src/events/identification.ts +2 -3
- package/src/logging/index.ts +3 -1
- package/src/logging/pino/logger.ts +24 -45
- package/src/middleware/adminOnly.ts +6 -4
- package/src/middleware/builderOnly.ts +6 -15
- package/src/middleware/builderOrAdmin.ts +8 -16
- package/src/security/permissions.ts +21 -5
- package/src/security/roles.ts +1 -1
- package/src/security/tests/permissions.spec.ts +1 -1
- package/src/{users/users.ts → users.ts} +7 -33
- package/tests/core/utilities/jestUtils.ts +0 -21
- package/tests/core/utilities/mocks/events.ts +2 -0
- package/tests/core/utilities/mocks/licenses.ts +3 -7
- package/tests/core/utilities/structures/accounts.ts +5 -3
- package/tests/core/utilities/structures/scim.ts +5 -4
- package/tests/core/utilities/structures/sso.ts +2 -2
- package/tests/core/utilities/structures/users.ts +0 -19
- package/tsconfig.json +2 -2
- package/dist/src/db/constants.d.ts +0 -2
- package/dist/src/db/constants.js +0 -13
- package/dist/src/db/constants.js.map +0 -1
- package/dist/src/logging/system.d.ts +0 -9
- package/dist/src/logging/system.js +0 -101
- package/dist/src/logging/system.js.map +0 -1
- package/dist/src/users/db.d.ts +0 -38
- package/dist/src/users/db.js +0 -407
- package/dist/src/users/db.js.map +0 -1
- package/dist/src/users/events.d.ts +0 -5
- package/dist/src/users/events.js +0 -169
- package/dist/src/users/events.js.map +0 -1
- package/dist/src/users/index.d.ts +0 -4
- package/dist/src/users/index.js +0 -23
- package/dist/src/users/index.js.map +0 -1
- package/dist/src/users/lookup.d.ts +0 -13
- package/dist/src/users/lookup.js +0 -112
- package/dist/src/users/lookup.js.map +0 -1
- package/dist/src/users/users.js.map +0 -1
- package/dist/src/users/utils.d.ts +0 -14
- package/dist/src/users/utils.js +0 -92
- package/dist/src/users/utils.js.map +0 -1
- package/src/db/constants.ts +0 -10
- package/src/logging/system.ts +0 -81
- package/src/logging/tests/system.spec.ts +0 -61
- package/src/middleware/tests/builder.spec.ts +0 -180
- package/src/users/db.ts +0 -460
- package/src/users/events.ts +0 -176
- package/src/users/index.ts +0 -4
- package/src/users/lookup.ts +0 -102
- package/src/users/utils.ts +0 -55
package/jest.config.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { Config } from "@jest/types"
|
|
2
|
+
const preset = require("ts-jest/jest-preset")
|
|
2
3
|
|
|
3
4
|
const baseConfig: Config.InitialProjectOptions = {
|
|
5
|
+
...preset,
|
|
4
6
|
preset: "@trendyol/jest-testcontainers",
|
|
5
7
|
setupFiles: ["./tests/jestEnv.ts"],
|
|
6
8
|
setupFilesAfterEnv: ["./tests/jestSetup.ts"],
|
|
@@ -9,7 +11,6 @@ const baseConfig: Config.InitialProjectOptions = {
|
|
|
9
11
|
},
|
|
10
12
|
moduleNameMapper: {
|
|
11
13
|
"@budibase/types": "<rootDir>/../types/src",
|
|
12
|
-
"@budibase/shared-core": ["<rootDir>/../shared-core/src"],
|
|
13
14
|
},
|
|
14
15
|
}
|
|
15
16
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@budibase/backend-core",
|
|
3
|
-
"version": "2.8.31
|
|
3
|
+
"version": "2.8.31",
|
|
4
4
|
"description": "Budibase backend core libraries used in server and worker",
|
|
5
5
|
"main": "dist/src/index.js",
|
|
6
6
|
"types": "dist/src/index.d.ts",
|
|
@@ -16,15 +16,14 @@
|
|
|
16
16
|
"prepack": "cp package.json dist",
|
|
17
17
|
"build": "tsc -p tsconfig.build.json",
|
|
18
18
|
"build:dev": "yarn prebuild && tsc --build --watch --preserveWatchOutput",
|
|
19
|
-
"check:types": "tsc -p tsconfig.json --noEmit --paths null",
|
|
20
19
|
"test": "bash scripts/test.sh",
|
|
21
20
|
"test:watch": "jest --watchAll"
|
|
22
21
|
},
|
|
23
22
|
"dependencies": {
|
|
24
23
|
"@budibase/nano": "10.1.2",
|
|
25
24
|
"@budibase/pouchdb-replication-stream": "1.2.10",
|
|
26
|
-
"@budibase/
|
|
27
|
-
"@
|
|
25
|
+
"@budibase/types": "2.8.31",
|
|
26
|
+
"@shopify/jest-koa-mocks": "5.0.1",
|
|
28
27
|
"@techpass/passport-openidconnect": "0.3.2",
|
|
29
28
|
"aws-cloudfront-sign": "2.2.0",
|
|
30
29
|
"aws-sdk": "2.1030.0",
|
|
@@ -52,20 +51,18 @@
|
|
|
52
51
|
"pouchdb": "7.3.0",
|
|
53
52
|
"pouchdb-find": "7.2.2",
|
|
54
53
|
"redlock": "4.2.0",
|
|
55
|
-
"rotating-file-stream": "3.1.0",
|
|
56
54
|
"sanitize-s3-objectkey": "0.0.1",
|
|
57
55
|
"semver": "7.3.7",
|
|
58
56
|
"tar-fs": "2.1.1",
|
|
59
57
|
"uuid": "8.3.2"
|
|
60
58
|
},
|
|
61
59
|
"devDependencies": {
|
|
62
|
-
"@jest/test-sequencer": "29.
|
|
63
|
-
"@
|
|
64
|
-
"@swc/
|
|
65
|
-
"@swc/jest": "0.2.27",
|
|
60
|
+
"@jest/test-sequencer": "29.5.0",
|
|
61
|
+
"@swc/core": "^1.3.25",
|
|
62
|
+
"@swc/jest": "^0.2.24",
|
|
66
63
|
"@trendyol/jest-testcontainers": "^2.1.1",
|
|
67
64
|
"@types/chance": "1.1.3",
|
|
68
|
-
"@types/jest": "29.5.
|
|
65
|
+
"@types/jest": "29.5.0",
|
|
69
66
|
"@types/koa": "2.13.4",
|
|
70
67
|
"@types/lodash": "4.14.180",
|
|
71
68
|
"@types/node": "14.18.20",
|
|
@@ -77,17 +74,32 @@
|
|
|
77
74
|
"@types/uuid": "8.3.4",
|
|
78
75
|
"chance": "1.1.8",
|
|
79
76
|
"ioredis-mock": "8.7.0",
|
|
80
|
-
"jest": "29.
|
|
81
|
-
"jest-environment-node": "29.
|
|
82
|
-
"jest-serial-runner": "1.2.1",
|
|
77
|
+
"jest": "29.5.0",
|
|
78
|
+
"jest-environment-node": "29.5.0",
|
|
79
|
+
"jest-serial-runner": "^1.2.1",
|
|
83
80
|
"koa": "2.13.4",
|
|
84
81
|
"nodemon": "2.0.16",
|
|
85
82
|
"pino-pretty": "10.0.0",
|
|
86
83
|
"pouchdb-adapter-memory": "7.2.2",
|
|
87
84
|
"timekeeper": "2.2.0",
|
|
85
|
+
"ts-jest": "29.0.5",
|
|
88
86
|
"ts-node": "10.8.1",
|
|
89
87
|
"tsconfig-paths": "4.0.0",
|
|
90
88
|
"typescript": "4.7.3"
|
|
91
89
|
},
|
|
92
|
-
"
|
|
90
|
+
"nx": {
|
|
91
|
+
"targets": {
|
|
92
|
+
"build": {
|
|
93
|
+
"dependsOn": [
|
|
94
|
+
{
|
|
95
|
+
"projects": [
|
|
96
|
+
"@budibase/types"
|
|
97
|
+
],
|
|
98
|
+
"target": "build"
|
|
99
|
+
}
|
|
100
|
+
]
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
"gitHead": "4613b17c1e76328bf279998c821a17195fbaab37"
|
|
93
105
|
}
|
package/scripts/test.sh
CHANGED
package/src/auth/auth.ts
CHANGED
|
@@ -159,7 +159,7 @@ export async function updateUserOAuth(userId: string, oAuthConfig: any) {
|
|
|
159
159
|
|
|
160
160
|
try {
|
|
161
161
|
const db = getGlobalDB()
|
|
162
|
-
const dbUser = await db.get
|
|
162
|
+
const dbUser = await db.get(userId)
|
|
163
163
|
|
|
164
164
|
//Do not overwrite the refresh token if a valid one is not provided.
|
|
165
165
|
if (typeof details.refreshToken !== "string") {
|
package/src/cache/appMetadata.ts
CHANGED
|
@@ -2,14 +2,9 @@ import { getAppClient } from "../redis/init"
|
|
|
2
2
|
import { doWithDB, DocumentType } from "../db"
|
|
3
3
|
import { Database, App } from "@budibase/types"
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
INVALID
|
|
5
|
+
const AppState = {
|
|
6
|
+
INVALID: "invalid",
|
|
7
7
|
}
|
|
8
|
-
|
|
9
|
-
export interface DeletedApp {
|
|
10
|
-
state: AppState
|
|
11
|
-
}
|
|
12
|
-
|
|
13
8
|
const EXPIRY_SECONDS = 3600
|
|
14
9
|
|
|
15
10
|
/**
|
|
@@ -36,7 +31,7 @@ function isInvalid(metadata?: { state: string }) {
|
|
|
36
31
|
* @param {string} appId the id of the app to get metadata from.
|
|
37
32
|
* @returns {object} the app metadata.
|
|
38
33
|
*/
|
|
39
|
-
export async function getAppMetadata(appId: string)
|
|
34
|
+
export async function getAppMetadata(appId: string) {
|
|
40
35
|
const client = await getAppClient()
|
|
41
36
|
// try cache
|
|
42
37
|
let metadata = await client.get(appId)
|
|
@@ -66,8 +61,11 @@ export async function getAppMetadata(appId: string): Promise<App | DeletedApp> {
|
|
|
66
61
|
}
|
|
67
62
|
await client.store(appId, metadata, expiry)
|
|
68
63
|
}
|
|
69
|
-
|
|
70
|
-
|
|
64
|
+
// we've stored in the cache an object to tell us that it is currently invalid
|
|
65
|
+
if (isInvalid(metadata)) {
|
|
66
|
+
throw { status: 404, message: "No app metadata found" }
|
|
67
|
+
}
|
|
68
|
+
return metadata as App
|
|
71
69
|
}
|
|
72
70
|
|
|
73
71
|
/**
|
|
@@ -36,7 +36,7 @@ describe("writethrough", () => {
|
|
|
36
36
|
_id: docId,
|
|
37
37
|
value: 1,
|
|
38
38
|
})
|
|
39
|
-
const output = await db.get
|
|
39
|
+
const output = await db.get(response.id)
|
|
40
40
|
current = output
|
|
41
41
|
expect(output.value).toBe(1)
|
|
42
42
|
})
|
|
@@ -45,7 +45,7 @@ describe("writethrough", () => {
|
|
|
45
45
|
it("second put shouldn't update DB", async () => {
|
|
46
46
|
await config.doInTenant(async () => {
|
|
47
47
|
const response = await writethrough.put({ ...current, value: 2 })
|
|
48
|
-
const output = await db.get
|
|
48
|
+
const output = await db.get(response.id)
|
|
49
49
|
expect(current._rev).toBe(output._rev)
|
|
50
50
|
expect(output.value).toBe(1)
|
|
51
51
|
})
|
|
@@ -55,7 +55,7 @@ describe("writethrough", () => {
|
|
|
55
55
|
await config.doInTenant(async () => {
|
|
56
56
|
tk.freeze(Date.now() + DELAY + 1)
|
|
57
57
|
const response = await writethrough.put({ ...current, value: 3 })
|
|
58
|
-
const output = await db.get
|
|
58
|
+
const output = await db.get(response.id)
|
|
59
59
|
expect(response.rev).not.toBe(current._rev)
|
|
60
60
|
expect(output.value).toBe(3)
|
|
61
61
|
|
|
@@ -79,7 +79,7 @@ describe("writethrough", () => {
|
|
|
79
79
|
expect.arrayContaining([current._rev, current._rev, newRev])
|
|
80
80
|
)
|
|
81
81
|
|
|
82
|
-
const output = await db.get
|
|
82
|
+
const output = await db.get(current._id)
|
|
83
83
|
expect(output.value).toBe(4)
|
|
84
84
|
expect(output._rev).toBe(newRev)
|
|
85
85
|
|
|
@@ -107,7 +107,7 @@ describe("writethrough", () => {
|
|
|
107
107
|
})
|
|
108
108
|
expect(res.ok).toBe(true)
|
|
109
109
|
|
|
110
|
-
const output = await db.get
|
|
110
|
+
const output = await db.get(id)
|
|
111
111
|
expect(output.value).toBe(3)
|
|
112
112
|
expect(output._rev).toBe(res.rev)
|
|
113
113
|
})
|
|
@@ -130,8 +130,8 @@ describe("writethrough", () => {
|
|
|
130
130
|
const resp2 = await writethrough2.put({ _id: "db1", value: "second" })
|
|
131
131
|
expect(resp1.rev).toBeDefined()
|
|
132
132
|
expect(resp2.rev).toBeDefined()
|
|
133
|
-
expect((await db.get
|
|
134
|
-
expect((await db2.get
|
|
133
|
+
expect((await db.get("db1")).value).toBe("first")
|
|
134
|
+
expect((await db2.get("db1")).value).toBe("second")
|
|
135
135
|
})
|
|
136
136
|
})
|
|
137
137
|
})
|
package/src/cache/user.ts
CHANGED
|
@@ -12,7 +12,7 @@ const EXPIRY_SECONDS = 3600
|
|
|
12
12
|
*/
|
|
13
13
|
async function populateFromDB(userId: string, tenantId: string) {
|
|
14
14
|
const db = tenancy.getTenantDB(tenantId)
|
|
15
|
-
const user = await db.get
|
|
15
|
+
const user = await db.get(userId)
|
|
16
16
|
user.budibaseAccess = true
|
|
17
17
|
if (!env.SELF_HOSTED && !env.DISABLE_ACCOUNT_PORTAL) {
|
|
18
18
|
const account = await accounts.getAccount(user.email)
|
package/src/constants/db.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
export
|
|
1
|
+
export const SEPARATOR = "_"
|
|
2
|
+
export const UNICODE_MAX = "\ufff0"
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Can be used to create a few different forms of querying a view.
|
|
@@ -14,6 +14,8 @@ export enum ViewName {
|
|
|
14
14
|
USER_BY_APP = "by_app",
|
|
15
15
|
USER_BY_EMAIL = "by_email2",
|
|
16
16
|
BY_API_KEY = "by_api_key",
|
|
17
|
+
/** @deprecated - could be deleted */
|
|
18
|
+
USER_BY_BUILDERS = "by_builders",
|
|
17
19
|
LINK = "by_link",
|
|
18
20
|
ROUTING = "screen_routes",
|
|
19
21
|
AUTOMATION_LOGS = "automation_logs",
|
|
@@ -34,6 +36,42 @@ export enum InternalTable {
|
|
|
34
36
|
USER_METADATA = "ta_users",
|
|
35
37
|
}
|
|
36
38
|
|
|
39
|
+
export enum DocumentType {
|
|
40
|
+
USER = "us",
|
|
41
|
+
GROUP = "gr",
|
|
42
|
+
WORKSPACE = "workspace",
|
|
43
|
+
CONFIG = "config",
|
|
44
|
+
TEMPLATE = "template",
|
|
45
|
+
APP = "app",
|
|
46
|
+
DEV = "dev",
|
|
47
|
+
APP_DEV = "app_dev",
|
|
48
|
+
APP_METADATA = "app_metadata",
|
|
49
|
+
ROLE = "role",
|
|
50
|
+
MIGRATIONS = "migrations",
|
|
51
|
+
DEV_INFO = "devinfo",
|
|
52
|
+
AUTOMATION_LOG = "log_au",
|
|
53
|
+
ACCOUNT_METADATA = "acc_metadata",
|
|
54
|
+
PLUGIN = "plg",
|
|
55
|
+
DATASOURCE = "datasource",
|
|
56
|
+
DATASOURCE_PLUS = "datasource_plus",
|
|
57
|
+
APP_BACKUP = "backup",
|
|
58
|
+
TABLE = "ta",
|
|
59
|
+
ROW = "ro",
|
|
60
|
+
AUTOMATION = "au",
|
|
61
|
+
LINK = "li",
|
|
62
|
+
WEBHOOK = "wh",
|
|
63
|
+
INSTANCE = "inst",
|
|
64
|
+
LAYOUT = "layout",
|
|
65
|
+
SCREEN = "screen",
|
|
66
|
+
QUERY = "query",
|
|
67
|
+
DEPLOYMENTS = "deployments",
|
|
68
|
+
METADATA = "metadata",
|
|
69
|
+
MEM_VIEW = "view",
|
|
70
|
+
USER_FLAG = "flag",
|
|
71
|
+
AUTOMATION_METADATA = "meta_au",
|
|
72
|
+
AUDIT_LOG = "al",
|
|
73
|
+
}
|
|
74
|
+
|
|
37
75
|
export const StaticDatabases = {
|
|
38
76
|
GLOBAL: {
|
|
39
77
|
name: "global-db",
|
|
@@ -57,7 +95,7 @@ export const StaticDatabases = {
|
|
|
57
95
|
},
|
|
58
96
|
}
|
|
59
97
|
|
|
60
|
-
export const APP_PREFIX =
|
|
61
|
-
export const APP_DEV =
|
|
98
|
+
export const APP_PREFIX = DocumentType.APP + SEPARATOR
|
|
99
|
+
export const APP_DEV = DocumentType.APP_DEV + SEPARATOR
|
|
62
100
|
export const APP_DEV_PREFIX = APP_DEV
|
|
63
101
|
export const BUDIBASE_DATASOURCE_TYPE = "budibase"
|
package/src/constants/misc.ts
CHANGED
|
@@ -20,8 +20,6 @@ export enum Header {
|
|
|
20
20
|
TYPE = "x-budibase-type",
|
|
21
21
|
PREVIEW_ROLE = "x-budibase-role",
|
|
22
22
|
TENANT_ID = "x-budibase-tenant-id",
|
|
23
|
-
VERIFICATION_CODE = "x-budibase-verification-code",
|
|
24
|
-
RETURN_VERIFICATION_CODE = "x-budibase-return-verification-code",
|
|
25
23
|
TOKEN = "x-budibase-token",
|
|
26
24
|
CSRF_TOKEN = "x-csrf-token",
|
|
27
25
|
CORRELATION_ID = "x-budibase-correlation-id",
|
package/src/db/couch/index.ts
CHANGED
|
@@ -5,7 +5,7 @@ export async function createUserIndex() {
|
|
|
5
5
|
const db = getGlobalDB()
|
|
6
6
|
let designDoc
|
|
7
7
|
try {
|
|
8
|
-
designDoc = await db.get
|
|
8
|
+
designDoc = await db.get("_design/database")
|
|
9
9
|
} catch (err: any) {
|
|
10
10
|
if (err.status === 404) {
|
|
11
11
|
designDoc = { _id: "_design/database" }
|
package/src/db/utils.ts
CHANGED
|
@@ -2,7 +2,7 @@ import env from "../environment"
|
|
|
2
2
|
import { DEFAULT_TENANT_ID, SEPARATOR, DocumentType } from "../constants"
|
|
3
3
|
import { getTenantId, getGlobalDBName } from "../context"
|
|
4
4
|
import { doWithDB, directCouchAllDbs } from "./db"
|
|
5
|
-
import {
|
|
5
|
+
import { getAppMetadata } from "../cache/appMetadata"
|
|
6
6
|
import { isDevApp, isDevAppID, getProdAppID } from "../docIds/conversions"
|
|
7
7
|
import { App, Database } from "@budibase/types"
|
|
8
8
|
import { getStartEndKeyURL } from "../docIds"
|
|
@@ -101,9 +101,7 @@ export async function getAllApps({
|
|
|
101
101
|
const response = await Promise.allSettled(appPromises)
|
|
102
102
|
const apps = response
|
|
103
103
|
.filter(
|
|
104
|
-
(result: any) =>
|
|
105
|
-
result.status === "fulfilled" &&
|
|
106
|
-
result.value?.state !== AppState.INVALID
|
|
104
|
+
(result: any) => result.status === "fulfilled" && result.value != null
|
|
107
105
|
)
|
|
108
106
|
.map(({ value }: any) => value)
|
|
109
107
|
if (!all) {
|
|
@@ -128,11 +126,7 @@ export async function getAppsByIDs(appIds: string[]) {
|
|
|
128
126
|
)
|
|
129
127
|
// have to list the apps which exist, some may have been deleted
|
|
130
128
|
return settled
|
|
131
|
-
.filter(
|
|
132
|
-
promise =>
|
|
133
|
-
promise.status === "fulfilled" &&
|
|
134
|
-
(promise.value as DeletedApp).state !== AppState.INVALID
|
|
135
|
-
)
|
|
129
|
+
.filter(promise => promise.status === "fulfilled")
|
|
136
130
|
.map(promise => (promise as PromiseFulfilledResult<App>).value)
|
|
137
131
|
}
|
|
138
132
|
|
package/src/db/views.ts
CHANGED
|
@@ -105,6 +105,16 @@ export const createApiKeyView = async () => {
|
|
|
105
105
|
await createView(db, viewJs, ViewName.BY_API_KEY)
|
|
106
106
|
}
|
|
107
107
|
|
|
108
|
+
export const createUserBuildersView = async () => {
|
|
109
|
+
const db = getGlobalDB()
|
|
110
|
+
const viewJs = `function(doc) {
|
|
111
|
+
if (doc.builder && doc.builder.global === true) {
|
|
112
|
+
emit(doc._id, doc._id)
|
|
113
|
+
}
|
|
114
|
+
}`
|
|
115
|
+
await createView(db, viewJs, ViewName.USER_BY_BUILDERS)
|
|
116
|
+
}
|
|
117
|
+
|
|
108
118
|
export interface QueryViewOptions {
|
|
109
119
|
arrayResponse?: boolean
|
|
110
120
|
}
|
|
@@ -213,6 +223,7 @@ export const queryPlatformView = async <T>(
|
|
|
213
223
|
const CreateFuncByName: any = {
|
|
214
224
|
[ViewName.USER_BY_EMAIL]: createNewUserEmailView,
|
|
215
225
|
[ViewName.BY_API_KEY]: createApiKeyView,
|
|
226
|
+
[ViewName.USER_BY_BUILDERS]: createUserBuildersView,
|
|
216
227
|
[ViewName.USER_BY_APP]: createUserAppView,
|
|
217
228
|
}
|
|
218
229
|
|
package/src/environment.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from "fs"
|
|
2
|
-
import { ServiceType } from "@budibase/types"
|
|
3
2
|
|
|
4
3
|
function isTest() {
|
|
5
4
|
return isCypress() || isJest()
|
|
@@ -48,10 +47,7 @@ function httpLogging() {
|
|
|
48
47
|
return process.env.HTTP_LOGGING
|
|
49
48
|
}
|
|
50
49
|
|
|
51
|
-
function
|
|
52
|
-
VERSION: string
|
|
53
|
-
SERVICE_NAME: string
|
|
54
|
-
} {
|
|
50
|
+
function findVersion() {
|
|
55
51
|
function findFileInAncestors(
|
|
56
52
|
fileName: string,
|
|
57
53
|
currentDir: string
|
|
@@ -73,31 +69,17 @@ function getPackageJsonFields(): {
|
|
|
73
69
|
try {
|
|
74
70
|
const packageJsonFile = findFileInAncestors("package.json", process.cwd())
|
|
75
71
|
const content = readFileSync(packageJsonFile!, "utf-8")
|
|
76
|
-
|
|
77
|
-
return {
|
|
78
|
-
VERSION: parsedContent.version,
|
|
79
|
-
SERVICE_NAME: parsedContent.name,
|
|
80
|
-
}
|
|
72
|
+
return JSON.parse(content).version
|
|
81
73
|
} catch {
|
|
82
74
|
// throwing an error here is confusing/causes backend-core to be hard to import
|
|
83
|
-
return
|
|
75
|
+
return undefined
|
|
84
76
|
}
|
|
85
77
|
}
|
|
86
78
|
|
|
87
|
-
function isWorker() {
|
|
88
|
-
return environment.SERVICE_TYPE === ServiceType.WORKER
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
function isApps() {
|
|
92
|
-
return environment.SERVICE_TYPE === ServiceType.APPS
|
|
93
|
-
}
|
|
94
|
-
|
|
95
79
|
const environment = {
|
|
96
80
|
isTest,
|
|
97
81
|
isJest,
|
|
98
82
|
isDev,
|
|
99
|
-
isWorker,
|
|
100
|
-
isApps,
|
|
101
83
|
isProd: () => {
|
|
102
84
|
return !isDev()
|
|
103
85
|
},
|
|
@@ -164,7 +146,6 @@ const environment = {
|
|
|
164
146
|
SMTP_FROM_ADDRESS: process.env.SMTP_FROM_ADDRESS,
|
|
165
147
|
DISABLE_JWT_WARNING: process.env.DISABLE_JWT_WARNING,
|
|
166
148
|
BLACKLIST_IPS: process.env.BLACKLIST_IPS,
|
|
167
|
-
SERVICE_TYPE: "unknown",
|
|
168
149
|
/**
|
|
169
150
|
* Enable to allow an admin user to login using a password.
|
|
170
151
|
* This can be useful to prevent lockout when configuring SSO.
|
|
@@ -173,7 +154,7 @@ const environment = {
|
|
|
173
154
|
ENABLE_SSO_MAINTENANCE_MODE: selfHosted
|
|
174
155
|
? process.env.ENABLE_SSO_MAINTENANCE_MODE
|
|
175
156
|
: false,
|
|
176
|
-
|
|
157
|
+
VERSION: findVersion(),
|
|
177
158
|
DISABLE_PINO_LOGGER: process.env.DISABLE_PINO_LOGGER,
|
|
178
159
|
OFFLINE_MODE: process.env.OFFLINE_MODE,
|
|
179
160
|
_set(key: any, value: any) {
|
|
@@ -181,7 +162,6 @@ const environment = {
|
|
|
181
162
|
// @ts-ignore
|
|
182
163
|
environment[key] = value
|
|
183
164
|
},
|
|
184
|
-
ROLLING_LOG_MAX_SIZE: process.env.ROLLING_LOG_MAX_SIZE || "10M",
|
|
185
165
|
}
|
|
186
166
|
|
|
187
167
|
// clean up any environment variable edge cases
|
|
@@ -21,7 +21,6 @@ import { processors } from "./processors"
|
|
|
21
21
|
import { newid } from "../utils"
|
|
22
22
|
import * as installation from "../installation"
|
|
23
23
|
import * as configs from "../configs"
|
|
24
|
-
import * as users from "../users"
|
|
25
24
|
import { withCache, TTL, CacheKey } from "../cache/generic"
|
|
26
25
|
|
|
27
26
|
/**
|
|
@@ -165,8 +164,8 @@ const identifyUser = async (
|
|
|
165
164
|
const id = user._id as string
|
|
166
165
|
const tenantId = await getEventTenantId(user.tenantId)
|
|
167
166
|
const type = IdentityType.USER
|
|
168
|
-
let builder =
|
|
169
|
-
let admin =
|
|
167
|
+
let builder = user.builder?.global || false
|
|
168
|
+
let admin = user.admin?.global || false
|
|
170
169
|
let providerType
|
|
171
170
|
if (isSSOUser(user)) {
|
|
172
171
|
providerType = user.providerType
|
package/src/logging/index.ts
CHANGED
|
@@ -1,60 +1,37 @@
|
|
|
1
|
-
import pino, { LoggerOptions } from "pino"
|
|
2
|
-
import pinoPretty from "pino-pretty"
|
|
3
|
-
|
|
4
|
-
import { IdentityType } from "@budibase/types"
|
|
5
1
|
import env from "../../environment"
|
|
2
|
+
import pino, { LoggerOptions } from "pino"
|
|
6
3
|
import * as context from "../../context"
|
|
7
4
|
import * as correlation from "../correlation"
|
|
8
|
-
|
|
9
|
-
import {
|
|
5
|
+
import { IdentityType } from "@budibase/types"
|
|
6
|
+
import { LOG_CONTEXT } from "../index"
|
|
10
7
|
|
|
11
8
|
// LOGGER
|
|
12
9
|
|
|
13
10
|
let pinoInstance: pino.Logger | undefined
|
|
14
11
|
if (!env.DISABLE_PINO_LOGGER) {
|
|
15
|
-
const level = env.LOG_LEVEL
|
|
16
12
|
const pinoOptions: LoggerOptions = {
|
|
17
|
-
level,
|
|
13
|
+
level: env.LOG_LEVEL,
|
|
18
14
|
formatters: {
|
|
19
|
-
level:
|
|
20
|
-
return { level:
|
|
15
|
+
level: label => {
|
|
16
|
+
return { level: label.toUpperCase() }
|
|
21
17
|
},
|
|
22
18
|
bindings: () => {
|
|
23
|
-
|
|
24
|
-
// "service" is being injected in datadog using the pod names,
|
|
25
|
-
// so we should leave it blank to allow the default behaviour if it's not running self-hosted
|
|
26
|
-
return {
|
|
27
|
-
service: env.SERVICE_NAME,
|
|
28
|
-
}
|
|
29
|
-
} else {
|
|
30
|
-
return {}
|
|
31
|
-
}
|
|
19
|
+
return {}
|
|
32
20
|
},
|
|
33
21
|
},
|
|
34
22
|
timestamp: () => `,"timestamp":"${new Date(Date.now()).toISOString()}"`,
|
|
35
23
|
}
|
|
36
24
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
}
|
|
45
|
-
: { stream: process.stdout, level: level as pino.Level }
|
|
46
|
-
)
|
|
47
|
-
|
|
48
|
-
if (env.SELF_HOSTED) {
|
|
49
|
-
destinations.push({
|
|
50
|
-
stream: localFileDestination(),
|
|
51
|
-
level: level as pino.Level,
|
|
52
|
-
})
|
|
25
|
+
if (env.isDev()) {
|
|
26
|
+
pinoOptions.transport = {
|
|
27
|
+
target: "pino-pretty",
|
|
28
|
+
options: {
|
|
29
|
+
singleLine: true,
|
|
30
|
+
},
|
|
31
|
+
}
|
|
53
32
|
}
|
|
54
33
|
|
|
55
|
-
pinoInstance =
|
|
56
|
-
? pino(pinoOptions, pino.multistream(destinations))
|
|
57
|
-
: pino(pinoOptions)
|
|
34
|
+
pinoInstance = pino(pinoOptions)
|
|
58
35
|
|
|
59
36
|
// CONSOLE OVERRIDES
|
|
60
37
|
|
|
@@ -106,13 +83,15 @@ if (!env.DISABLE_PINO_LOGGER) {
|
|
|
106
83
|
|
|
107
84
|
let contextObject = {}
|
|
108
85
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
86
|
+
if (LOG_CONTEXT) {
|
|
87
|
+
contextObject = {
|
|
88
|
+
tenantId: getTenantId(),
|
|
89
|
+
appId: getAppId(),
|
|
90
|
+
automationId: getAutomationId(),
|
|
91
|
+
identityId: identity?._id,
|
|
92
|
+
identityType: identity?.type,
|
|
93
|
+
correlationId: correlation.getId(),
|
|
94
|
+
}
|
|
116
95
|
}
|
|
117
96
|
|
|
118
97
|
const mergingObject: any = {
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { isAdmin } from "../users"
|
|
1
|
+
import { BBContext } from "@budibase/types"
|
|
3
2
|
|
|
4
|
-
export default async (ctx:
|
|
5
|
-
if (
|
|
3
|
+
export default async (ctx: BBContext, next: any) => {
|
|
4
|
+
if (
|
|
5
|
+
!ctx.internal &&
|
|
6
|
+
(!ctx.user || !ctx.user.admin || !ctx.user.admin.global)
|
|
7
|
+
) {
|
|
6
8
|
ctx.throw(403, "Admin user only endpoint.")
|
|
7
9
|
}
|
|
8
10
|
return next()
|
|
@@ -1,19 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { isBuilder, hasBuilderPermissions } from "../users"
|
|
3
|
-
import { getAppId } from "../context"
|
|
4
|
-
import env from "../environment"
|
|
1
|
+
import { BBContext } from "@budibase/types"
|
|
5
2
|
|
|
6
|
-
export default async (ctx:
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
? isBuilder
|
|
12
|
-
: undefined
|
|
13
|
-
if (!builderFn) {
|
|
14
|
-
throw new Error("Service name unknown - middleware inactive.")
|
|
15
|
-
}
|
|
16
|
-
if (!ctx.internal && !builderFn(ctx.user, appId)) {
|
|
3
|
+
export default async (ctx: BBContext, next: any) => {
|
|
4
|
+
if (
|
|
5
|
+
!ctx.internal &&
|
|
6
|
+
(!ctx.user || !ctx.user.builder || !ctx.user.builder.global)
|
|
7
|
+
) {
|
|
17
8
|
ctx.throw(403, "Builder user only endpoint.")
|
|
18
9
|
}
|
|
19
10
|
return next()
|
|
@@ -1,20 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { isBuilder, isAdmin, hasBuilderPermissions } from "../users"
|
|
3
|
-
import { getAppId } from "../context"
|
|
4
|
-
import env from "../environment"
|
|
1
|
+
import { BBContext } from "@budibase/types"
|
|
5
2
|
|
|
6
|
-
export default async (ctx:
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
if (!builderFn) {
|
|
14
|
-
throw new Error("Service name unknown - middleware inactive.")
|
|
15
|
-
}
|
|
16
|
-
if (!ctx.internal && !builderFn(ctx.user, appId) && !isAdmin(ctx.user)) {
|
|
17
|
-
ctx.throw(403, "Admin/Builder user only endpoint.")
|
|
3
|
+
export default async (ctx: BBContext, next: any) => {
|
|
4
|
+
if (
|
|
5
|
+
!ctx.internal &&
|
|
6
|
+
(!ctx.user || !ctx.user.builder || !ctx.user.builder.global) &&
|
|
7
|
+
(!ctx.user || !ctx.user.admin || !ctx.user.admin.global)
|
|
8
|
+
) {
|
|
9
|
+
ctx.throw(403, "Builder user only endpoint.")
|
|
18
10
|
}
|
|
19
11
|
return next()
|
|
20
12
|
}
|