@budibase/server 1.1.27 → 1.1.29-alpha.1
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/builder/assets/{index.5cf5be06.css → index.39026912.css} +2 -2
- package/builder/assets/index.6d12ed96.js +978 -0
- package/builder/assets/{vendor.7f11b0ca.js → vendor.b0c43a06.js} +1 -1
- package/builder/index.html +3 -3
- package/coverage/clover.xml +253 -234
- package/coverage/coverage-final.json +9 -9
- package/coverage/lcov-report/api/controllers/apikeys.js.html +1 -1
- package/coverage/lcov-report/api/controllers/auth.js.html +1 -1
- package/coverage/lcov-report/api/controllers/automation.js.html +1 -1
- package/coverage/lcov-report/api/controllers/backup.js.html +1 -1
- package/coverage/lcov-report/api/controllers/cloud.js.html +1 -1
- package/coverage/lcov-report/api/controllers/component.js.html +1 -1
- package/coverage/lcov-report/api/controllers/datasource.js.html +1 -1
- package/coverage/lcov-report/api/controllers/dev.js.html +1 -1
- package/coverage/lcov-report/api/controllers/index.html +1 -1
- package/coverage/lcov-report/api/controllers/integration.js.html +1 -1
- package/coverage/lcov-report/api/controllers/layout.js.html +1 -1
- package/coverage/lcov-report/api/controllers/metadata.js.html +1 -1
- package/coverage/lcov-report/api/controllers/migrations.js.html +1 -1
- package/coverage/lcov-report/api/controllers/permission.js.html +1 -1
- package/coverage/lcov-report/api/controllers/query/index.html +1 -1
- package/coverage/lcov-report/api/controllers/query/validation.js.html +2 -2
- package/coverage/lcov-report/api/controllers/role.js.html +1 -1
- package/coverage/lcov-report/api/controllers/routing.js.html +1 -1
- package/coverage/lcov-report/api/controllers/row/external.js.html +1 -1
- package/coverage/lcov-report/api/controllers/row/index.html +18 -18
- package/coverage/lcov-report/api/controllers/row/internal.js.html +1 -1
- package/coverage/lcov-report/api/controllers/row/internalSearch.js.html +94 -49
- package/coverage/lcov-report/api/controllers/row/staticFormula.js.html +1 -1
- package/coverage/lcov-report/api/controllers/row/utils.js.html +1 -1
- package/coverage/lcov-report/api/controllers/screen.js.html +1 -1
- package/coverage/lcov-report/api/controllers/script.js.html +1 -1
- package/coverage/lcov-report/api/controllers/table/bulkFormula.js.html +1 -1
- package/coverage/lcov-report/api/controllers/table/external.js.html +1 -1
- package/coverage/lcov-report/api/controllers/table/index.html +1 -1
- package/coverage/lcov-report/api/controllers/table/index.js.html +1 -1
- package/coverage/lcov-report/api/controllers/templates.js.html +1 -1
- package/coverage/lcov-report/api/controllers/user.js.html +1 -1
- package/coverage/lcov-report/api/controllers/view/exporters.js.html +1 -1
- package/coverage/lcov-report/api/controllers/view/index.html +1 -1
- package/coverage/lcov-report/api/controllers/view/index.js.html +1 -1
- package/coverage/lcov-report/api/controllers/view/utils.js.html +1 -1
- package/coverage/lcov-report/api/controllers/view/viewBuilder.js.html +1 -1
- package/coverage/lcov-report/api/controllers/webhook.js.html +1 -1
- package/coverage/lcov-report/api/index.html +1 -1
- package/coverage/lcov-report/api/index.js.html +1 -1
- package/coverage/lcov-report/api/routes/analytics.js.html +1 -1
- package/coverage/lcov-report/api/routes/apikeys.js.html +1 -1
- package/coverage/lcov-report/api/routes/auth.js.html +1 -1
- package/coverage/lcov-report/api/routes/automation.js.html +1 -1
- package/coverage/lcov-report/api/routes/backup.js.html +1 -1
- package/coverage/lcov-report/api/routes/cloud.js.html +1 -1
- package/coverage/lcov-report/api/routes/component.js.html +1 -1
- package/coverage/lcov-report/api/routes/datasource.js.html +1 -1
- package/coverage/lcov-report/api/routes/deploy.js.html +1 -1
- package/coverage/lcov-report/api/routes/dev.js.html +1 -1
- package/coverage/lcov-report/api/routes/index.html +1 -1
- package/coverage/lcov-report/api/routes/integration.js.html +1 -1
- package/coverage/lcov-report/api/routes/layout.js.html +1 -1
- package/coverage/lcov-report/api/routes/metadata.js.html +1 -1
- package/coverage/lcov-report/api/routes/migrations.js.html +1 -1
- package/coverage/lcov-report/api/routes/permission.js.html +1 -1
- package/coverage/lcov-report/api/routes/query.js.html +1 -1
- package/coverage/lcov-report/api/routes/role.js.html +1 -1
- package/coverage/lcov-report/api/routes/routing.js.html +1 -1
- package/coverage/lcov-report/api/routes/screen.js.html +1 -1
- package/coverage/lcov-report/api/routes/script.js.html +1 -1
- package/coverage/lcov-report/api/routes/table.js.html +1 -1
- package/coverage/lcov-report/api/routes/templates.js.html +1 -1
- package/coverage/lcov-report/api/routes/user.js.html +1 -1
- package/coverage/lcov-report/api/routes/utils/index.html +1 -1
- package/coverage/lcov-report/api/routes/utils/validators.js.html +2 -2
- package/coverage/lcov-report/api/routes/view.js.html +1 -1
- package/coverage/lcov-report/api/routes/webhook.js.html +1 -1
- package/coverage/lcov-report/automations/actions.js.html +1 -1
- package/coverage/lcov-report/automations/automationUtils.js.html +1 -1
- package/coverage/lcov-report/automations/bullboard.js.html +1 -1
- package/coverage/lcov-report/automations/index.html +1 -1
- package/coverage/lcov-report/automations/index.js.html +1 -1
- package/coverage/lcov-report/automations/steps/bash.js.html +1 -1
- package/coverage/lcov-report/automations/steps/delay.js.html +1 -1
- package/coverage/lcov-report/automations/steps/discord.js.html +1 -1
- package/coverage/lcov-report/automations/steps/executeQuery.js.html +5 -2
- package/coverage/lcov-report/automations/steps/executeScript.js.html +1 -1
- package/coverage/lcov-report/automations/steps/filter.js.html +1 -1
- package/coverage/lcov-report/automations/steps/index.html +17 -17
- package/coverage/lcov-report/automations/steps/integromat.js.html +1 -1
- package/coverage/lcov-report/automations/steps/loop.js.html +1 -1
- package/coverage/lcov-report/automations/steps/outgoingWebhook.js.html +1 -1
- package/coverage/lcov-report/automations/steps/queryRows.js.html +12 -6
- package/coverage/lcov-report/automations/steps/sendSmtpEmail.js.html +1 -1
- package/coverage/lcov-report/automations/steps/serverLog.js.html +1 -1
- package/coverage/lcov-report/automations/steps/slack.js.html +1 -1
- package/coverage/lcov-report/automations/steps/updateRow.js.html +1 -1
- package/coverage/lcov-report/automations/steps/utils.js.html +25 -13
- package/coverage/lcov-report/automations/steps/zapier.js.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/app.js.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/cron.js.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/index.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/index.js.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/rowDeleted.js.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/rowSaved.js.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/rowUpdated.js.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/webhook.js.html +1 -1
- package/coverage/lcov-report/automations/triggers.js.html +1 -1
- package/coverage/lcov-report/constants/index.html +1 -1
- package/coverage/lcov-report/constants/index.js.html +1 -1
- package/coverage/lcov-report/constants/layouts.js.html +1 -1
- package/coverage/lcov-report/constants/screens.js.html +1 -1
- package/coverage/lcov-report/db/inMemoryView.js.html +1 -1
- package/coverage/lcov-report/db/index.html +1 -1
- package/coverage/lcov-report/db/index.js.html +1 -1
- package/coverage/lcov-report/db/linkedRows/LinkController.js.html +1 -1
- package/coverage/lcov-report/db/linkedRows/index.html +1 -1
- package/coverage/lcov-report/db/linkedRows/index.js.html +1 -1
- package/coverage/lcov-report/db/linkedRows/linkUtils.js.html +1 -1
- package/coverage/lcov-report/db/newid.js.html +1 -1
- package/coverage/lcov-report/db/utils.js.html +1 -1
- package/coverage/lcov-report/events/AutomationEmitter.js.html +1 -1
- package/coverage/lcov-report/events/index.html +1 -1
- package/coverage/lcov-report/events/index.js.html +1 -1
- package/coverage/lcov-report/events/utils.js.html +1 -1
- package/coverage/lcov-report/index.html +46 -46
- package/coverage/lcov-report/integrations/tests/TestConfiguration.js.html +1 -1
- package/coverage/lcov-report/integrations/tests/index.html +1 -1
- package/coverage/lcov-report/middleware/appInfo.js.html +1 -1
- package/coverage/lcov-report/middleware/builder.js.html +1 -1
- package/coverage/lcov-report/middleware/currentapp.js.html +1 -1
- package/coverage/lcov-report/middleware/index.html +21 -21
- package/coverage/lcov-report/middleware/joi-validator.js.html +43 -43
- package/coverage/lcov-report/middleware/publicApi.js.html +1 -1
- package/coverage/lcov-report/middleware/resourceId.js.html +1 -1
- package/coverage/lcov-report/middleware/selfhost.js.html +1 -1
- package/coverage/lcov-report/middleware/utils.js.html +1 -1
- package/coverage/lcov-report/threads/automation.js.html +1 -1
- package/coverage/lcov-report/threads/index.html +1 -1
- package/coverage/lcov-report/threads/query.js.html +1 -1
- package/coverage/lcov-report/threads/utils.js.html +1 -1
- package/coverage/lcov-report/utilities/budibaseDir.js.html +1 -1
- package/coverage/lcov-report/utilities/centralPath.js.html +1 -1
- package/coverage/lcov-report/utilities/csvParser.js.html +1 -1
- package/coverage/lcov-report/utilities/global.js.html +67 -13
- package/coverage/lcov-report/utilities/index.html +20 -20
- package/coverage/lcov-report/utilities/index.js.html +1 -1
- package/coverage/lcov-report/utilities/queue/inMemoryQueue.js.html +1 -1
- package/coverage/lcov-report/utilities/queue/index.html +1 -1
- package/coverage/lcov-report/utilities/routing/index.html +1 -1
- package/coverage/lcov-report/utilities/routing/index.js.html +1 -1
- package/coverage/lcov-report/utilities/rowProcessor/index.html +1 -1
- package/coverage/lcov-report/utilities/rowProcessor/index.js.html +1 -1
- package/coverage/lcov-report/utilities/rowProcessor/utils.js.html +1 -1
- package/coverage/lcov-report/utilities/scriptRunner.js.html +1 -1
- package/coverage/lcov-report/utilities/security.js.html +2 -2
- package/coverage/lcov-report/utilities/statusCodes.js.html +1 -1
- package/coverage/lcov-report/utilities/usageQuota/index.html +1 -1
- package/coverage/lcov-report/utilities/usageQuota/rows.js.html +1 -1
- package/coverage/lcov-report/utilities/usageQuota/usageQuoteReset.js.html +1 -1
- package/coverage/lcov-report/utilities/users.js.html +1 -1
- package/coverage/lcov-report/utilities/workerRequests.js.html +1 -1
- package/coverage/lcov.info +485 -445
- package/dist/api/controllers/query/index.js +1 -1
- package/dist/api/controllers/query/validation.js +1 -1
- package/dist/api/controllers/row/internalSearch.js +30 -16
- package/dist/api/routes/utils/validators.js +1 -1
- package/dist/automations/steps/queryRows.js +4 -2
- package/dist/automations/steps/utils.js +9 -5
- package/dist/integrations/base/sql.js +43 -14
- package/dist/package.json +8 -8
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/utilities/global.js +21 -4
- package/package.json +9 -9
- package/src/api/controllers/query/index.ts +1 -1
- package/src/api/controllers/query/validation.js +1 -1
- package/src/api/controllers/row/internalSearch.js +35 -20
- package/src/api/routes/tests/user.spec.js +2 -0
- package/src/api/routes/utils/validators.js +1 -1
- package/src/automations/steps/executeQuery.js +1 -0
- package/src/automations/steps/queryRows.js +4 -2
- package/src/automations/steps/utils.js +9 -5
- package/src/definitions/datasource.ts +3 -0
- package/src/integrations/base/sql.ts +44 -13
- package/src/integrations/tests/sql.spec.js +50 -4
- package/src/middleware/tests/currentapp.spec.js +11 -0
- package/src/utilities/global.js +20 -2
- package/builder/assets/index.e96881ab.js +0 -979
package/dist/utilities/global.js
CHANGED
|
@@ -16,6 +16,7 @@ const { user: userCache } = require("@budibase/backend-core/cache");
|
|
|
16
16
|
const { getGlobalDB, isUserInAppTenant, } = require("@budibase/backend-core/tenancy");
|
|
17
17
|
const env = require("../environment");
|
|
18
18
|
const { getAppId } = require("@budibase/backend-core/context");
|
|
19
|
+
const { groups } = require("@budibase/pro");
|
|
19
20
|
exports.updateAppRole = (user, { appId } = {}) => {
|
|
20
21
|
appId = appId || getAppId();
|
|
21
22
|
if (!user || !user.roles) {
|
|
@@ -40,11 +41,27 @@ exports.updateAppRole = (user, { appId } = {}) => {
|
|
|
40
41
|
delete user.roles;
|
|
41
42
|
return user;
|
|
42
43
|
};
|
|
44
|
+
function checkGroupRoles(user, { appId } = {}) {
|
|
45
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
46
|
+
if (!user.roleId) {
|
|
47
|
+
let roleId = yield groups.getGroupRoleId(user, appId);
|
|
48
|
+
user.roleId = roleId;
|
|
49
|
+
}
|
|
50
|
+
return user;
|
|
51
|
+
});
|
|
52
|
+
}
|
|
43
53
|
function processUser(user, { appId } = {}) {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
54
|
+
var _a;
|
|
55
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
56
|
+
if (user) {
|
|
57
|
+
delete user.password;
|
|
58
|
+
}
|
|
59
|
+
user = yield exports.updateAppRole(user, { appId });
|
|
60
|
+
if ((_a = user === null || user === void 0 ? void 0 : user.userGroups) === null || _a === void 0 ? void 0 : _a.length) {
|
|
61
|
+
user = yield checkGroupRoles(user, { appId });
|
|
62
|
+
}
|
|
63
|
+
return user;
|
|
64
|
+
});
|
|
48
65
|
}
|
|
49
66
|
exports.getCachedSelf = (ctx, appId) => __awaiter(void 0, void 0, void 0, function* () {
|
|
50
67
|
// this has to be tenant aware, can't depend on the context to find it out
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@budibase/server",
|
|
3
3
|
"email": "hi@budibase.com",
|
|
4
|
-
"version": "1.1.
|
|
4
|
+
"version": "1.1.29-alpha.1",
|
|
5
5
|
"description": "Budibase Web Server",
|
|
6
6
|
"main": "src/index.ts",
|
|
7
7
|
"repository": {
|
|
@@ -77,11 +77,11 @@
|
|
|
77
77
|
"license": "GPL-3.0",
|
|
78
78
|
"dependencies": {
|
|
79
79
|
"@apidevtools/swagger-parser": "10.0.3",
|
|
80
|
-
"@budibase/backend-core": "^1.1.
|
|
81
|
-
"@budibase/client": "^1.1.
|
|
82
|
-
"@budibase/pro": "1.1.
|
|
83
|
-
"@budibase/string-templates": "^1.1.
|
|
84
|
-
"@budibase/types": "^1.1.
|
|
80
|
+
"@budibase/backend-core": "^1.1.29-alpha.1",
|
|
81
|
+
"@budibase/client": "^1.1.29-alpha.1",
|
|
82
|
+
"@budibase/pro": "1.1.29-alpha.0",
|
|
83
|
+
"@budibase/string-templates": "^1.1.29-alpha.1",
|
|
84
|
+
"@budibase/types": "^1.1.29-alpha.1",
|
|
85
85
|
"@bull-board/api": "3.7.0",
|
|
86
86
|
"@bull-board/koa": "3.9.4",
|
|
87
87
|
"@elastic/elasticsearch": "7.10.0",
|
|
@@ -118,7 +118,7 @@
|
|
|
118
118
|
"koa-send": "5.0.0",
|
|
119
119
|
"koa-session": "5.12.0",
|
|
120
120
|
"koa-static": "5.0.0",
|
|
121
|
-
"koa2-ratelimit": "1.1.
|
|
121
|
+
"koa2-ratelimit": "1.1.1",
|
|
122
122
|
"lodash": "4.17.21",
|
|
123
123
|
"memorystream": "0.3.1",
|
|
124
124
|
"mongodb": "3.6.3",
|
|
@@ -137,7 +137,7 @@
|
|
|
137
137
|
"redis": "4",
|
|
138
138
|
"server-destroy": "1.0.1",
|
|
139
139
|
"snowflake-promise": "^4.5.0",
|
|
140
|
-
"svelte": "3.
|
|
140
|
+
"svelte": "3.49.0",
|
|
141
141
|
"swagger-parser": "10.0.3",
|
|
142
142
|
"to-json-schema": "0.2.5",
|
|
143
143
|
"uuid": "3.3.2",
|
|
@@ -195,5 +195,5 @@
|
|
|
195
195
|
"optionalDependencies": {
|
|
196
196
|
"oracledb": "5.3.0"
|
|
197
197
|
},
|
|
198
|
-
"gitHead": "
|
|
198
|
+
"gitHead": "f00000b82e47fffa6341c813cfce59f76384b3a5"
|
|
199
199
|
}
|
|
@@ -19,6 +19,7 @@ class QueryBuilder {
|
|
|
19
19
|
empty: {},
|
|
20
20
|
notEmpty: {},
|
|
21
21
|
oneOf: {},
|
|
22
|
+
contains: {},
|
|
22
23
|
...base,
|
|
23
24
|
}
|
|
24
25
|
this.limit = 50
|
|
@@ -119,6 +120,11 @@ class QueryBuilder {
|
|
|
119
120
|
return this
|
|
120
121
|
}
|
|
121
122
|
|
|
123
|
+
addContains(key, value) {
|
|
124
|
+
this.query.contains[key] = value
|
|
125
|
+
return this
|
|
126
|
+
}
|
|
127
|
+
|
|
122
128
|
/**
|
|
123
129
|
* Preprocesses a value before going into a lucene search.
|
|
124
130
|
* Transforms strings to lowercase and wraps strings and bools in quotes.
|
|
@@ -164,6 +170,31 @@ class QueryBuilder {
|
|
|
164
170
|
return `${key}:${builder.preprocess(value, allPreProcessingOpts)}`
|
|
165
171
|
}
|
|
166
172
|
|
|
173
|
+
const contains = (key, value) => {
|
|
174
|
+
if (!value && value !== 0) {
|
|
175
|
+
return null
|
|
176
|
+
}
|
|
177
|
+
return `${key}:${builder.preprocess(value, { escape: true })}`
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
const oneOf = (key, value) => {
|
|
181
|
+
if (!Array.isArray(value)) {
|
|
182
|
+
if (typeof value === "string") {
|
|
183
|
+
value = value.split(",")
|
|
184
|
+
} else {
|
|
185
|
+
return ""
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
let orStatement = `${builder.preprocess(value[0], allPreProcessingOpts)}`
|
|
189
|
+
for (let i = 1; i < value.length; i++) {
|
|
190
|
+
orStatement += ` OR ${builder.preprocess(
|
|
191
|
+
value[i],
|
|
192
|
+
allPreProcessingOpts
|
|
193
|
+
)}`
|
|
194
|
+
}
|
|
195
|
+
return `${key}:(${orStatement})`
|
|
196
|
+
}
|
|
197
|
+
|
|
167
198
|
function build(structure, queryFn) {
|
|
168
199
|
for (let [key, value] of Object.entries(structure)) {
|
|
169
200
|
key = builder.preprocess(key.replace(/ /g, "_"), {
|
|
@@ -239,26 +270,10 @@ class QueryBuilder {
|
|
|
239
270
|
build(this.query.notEmpty, key => `${key}:["" TO *]`)
|
|
240
271
|
}
|
|
241
272
|
if (this.query.oneOf) {
|
|
242
|
-
build(this.query.oneOf,
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
} else {
|
|
247
|
-
return ""
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
let orStatement = `${builder.preprocess(
|
|
251
|
-
value[0],
|
|
252
|
-
allPreProcessingOpts
|
|
253
|
-
)}`
|
|
254
|
-
for (let i = 1; i < value.length; i++) {
|
|
255
|
-
orStatement += ` OR ${builder.preprocess(
|
|
256
|
-
value[i],
|
|
257
|
-
allPreProcessingOpts
|
|
258
|
-
)}`
|
|
259
|
-
}
|
|
260
|
-
return `${key}:(${orStatement})`
|
|
261
|
-
})
|
|
273
|
+
build(this.query.oneOf, oneOf)
|
|
274
|
+
}
|
|
275
|
+
if (this.query.contains) {
|
|
276
|
+
build(this.query.contains, contains)
|
|
262
277
|
}
|
|
263
278
|
// make sure table ID is always added as an AND
|
|
264
279
|
if (tableId) {
|
|
@@ -23,6 +23,7 @@ describe("/users", () => {
|
|
|
23
23
|
})
|
|
24
24
|
|
|
25
25
|
describe("fetch", () => {
|
|
26
|
+
|
|
26
27
|
it("returns a list of users from an instance db", async () => {
|
|
27
28
|
await config.createUser("uuidx")
|
|
28
29
|
await config.createUser("uuidy")
|
|
@@ -37,6 +38,7 @@ describe("/users", () => {
|
|
|
37
38
|
expect(res.body.find(u => u._id === `ro_ta_users_us_uuidy`)).toBeDefined()
|
|
38
39
|
})
|
|
39
40
|
|
|
41
|
+
|
|
40
42
|
it("should apply authorization to endpoint", async () => {
|
|
41
43
|
await config.createUser()
|
|
42
44
|
await checkPermissionsEndpoint({
|
|
@@ -96,12 +96,14 @@ exports.run = async function ({ inputs, appId }) {
|
|
|
96
96
|
tableId,
|
|
97
97
|
},
|
|
98
98
|
body: {
|
|
99
|
-
sortOrder,
|
|
100
99
|
sortType,
|
|
100
|
+
limit,
|
|
101
101
|
sort: sortColumn,
|
|
102
102
|
query: filters || {},
|
|
103
|
-
|
|
103
|
+
// default to ascending, like data tab
|
|
104
|
+
sortOrder: sortOrder || SortOrders.ASCENDING,
|
|
104
105
|
},
|
|
106
|
+
version: "1",
|
|
105
107
|
})
|
|
106
108
|
try {
|
|
107
109
|
await rowController.search(ctx)
|
|
@@ -17,7 +17,8 @@ exports.getFetchResponse = async fetched => {
|
|
|
17
17
|
// need to make sure all ctx structures have the
|
|
18
18
|
// throw added to them, so that controllers don't
|
|
19
19
|
// throw a ctx.throw undefined when error occurs
|
|
20
|
-
|
|
20
|
+
// opts can contain, body, params and version
|
|
21
|
+
exports.buildCtx = (appId, emitter, opts = {}) => {
|
|
21
22
|
const ctx = {
|
|
22
23
|
appId,
|
|
23
24
|
user: { appId },
|
|
@@ -26,11 +27,14 @@ exports.buildCtx = (appId, emitter, { body, params } = {}) => {
|
|
|
26
27
|
throw error
|
|
27
28
|
},
|
|
28
29
|
}
|
|
29
|
-
if (body) {
|
|
30
|
-
ctx.request = { body }
|
|
30
|
+
if (opts.body) {
|
|
31
|
+
ctx.request = { body: opts.body }
|
|
31
32
|
}
|
|
32
|
-
if (params) {
|
|
33
|
-
ctx.params = params
|
|
33
|
+
if (opts.params) {
|
|
34
|
+
ctx.params = opts.params
|
|
35
|
+
}
|
|
36
|
+
if (opts.version) {
|
|
37
|
+
ctx.version = opts.version
|
|
34
38
|
}
|
|
35
39
|
return ctx
|
|
36
40
|
}
|
|
@@ -142,6 +142,21 @@ class InternalBuilder {
|
|
|
142
142
|
}
|
|
143
143
|
}
|
|
144
144
|
}
|
|
145
|
+
|
|
146
|
+
const like = (key: string, value: any) => {
|
|
147
|
+
const fnc = allOr ? "orWhere" : "where"
|
|
148
|
+
// postgres supports ilike, nothing else does
|
|
149
|
+
if (this.client === SqlClients.POSTGRES) {
|
|
150
|
+
query = query[fnc](key, "ilike", `%${value}%`)
|
|
151
|
+
} else {
|
|
152
|
+
const rawFnc = `${fnc}Raw`
|
|
153
|
+
// @ts-ignore
|
|
154
|
+
query = query[rawFnc](`LOWER(${likeKey(this.client, key)}) LIKE ?`, [
|
|
155
|
+
`%${value}%`,
|
|
156
|
+
])
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
145
160
|
if (!filters) {
|
|
146
161
|
return query
|
|
147
162
|
}
|
|
@@ -168,19 +183,7 @@ class InternalBuilder {
|
|
|
168
183
|
})
|
|
169
184
|
}
|
|
170
185
|
if (filters.fuzzy) {
|
|
171
|
-
iterate(filters.fuzzy,
|
|
172
|
-
const fnc = allOr ? "orWhere" : "where"
|
|
173
|
-
// postgres supports ilike, nothing else does
|
|
174
|
-
if (this.client === SqlClients.POSTGRES) {
|
|
175
|
-
query = query[fnc](key, "ilike", `%${value}%`)
|
|
176
|
-
} else {
|
|
177
|
-
const rawFnc = `${fnc}Raw`
|
|
178
|
-
// @ts-ignore
|
|
179
|
-
query = query[rawFnc](`LOWER(${likeKey(this.client, key)}) LIKE ?`, [
|
|
180
|
-
`%${value}%`,
|
|
181
|
-
])
|
|
182
|
-
}
|
|
183
|
-
})
|
|
186
|
+
iterate(filters.fuzzy, like)
|
|
184
187
|
}
|
|
185
188
|
if (filters.range) {
|
|
186
189
|
iterate(filters.range, (key, value) => {
|
|
@@ -223,6 +226,34 @@ class InternalBuilder {
|
|
|
223
226
|
query = query[fnc](key)
|
|
224
227
|
})
|
|
225
228
|
}
|
|
229
|
+
if (filters.contains) {
|
|
230
|
+
const fnc = allOr ? "orWhere" : "where"
|
|
231
|
+
const rawFnc = `${fnc}Raw`
|
|
232
|
+
if (this.client === SqlClients.POSTGRES) {
|
|
233
|
+
iterate(filters.contains, (key: string, value: any) => {
|
|
234
|
+
const fieldNames = key.split(/\./g)
|
|
235
|
+
const tableName = fieldNames[0]
|
|
236
|
+
const columnName = fieldNames[1]
|
|
237
|
+
if (typeof value === "string") {
|
|
238
|
+
value = `"${value}"`
|
|
239
|
+
}
|
|
240
|
+
// @ts-ignore
|
|
241
|
+
query = query[rawFnc](
|
|
242
|
+
`"${tableName}"."${columnName}"::jsonb @> '[${value}]'`
|
|
243
|
+
)
|
|
244
|
+
})
|
|
245
|
+
} else if (this.client === SqlClients.MY_SQL) {
|
|
246
|
+
iterate(filters.contains, (key: string, value: any) => {
|
|
247
|
+
if (typeof value === "string") {
|
|
248
|
+
value = `"${value}"`
|
|
249
|
+
}
|
|
250
|
+
// @ts-ignore
|
|
251
|
+
query = query[rawFnc](`JSON_CONTAINS(${key}, '${value}')`)
|
|
252
|
+
})
|
|
253
|
+
} else {
|
|
254
|
+
iterate(filters.contains, like)
|
|
255
|
+
}
|
|
256
|
+
}
|
|
226
257
|
return query
|
|
227
258
|
}
|
|
228
259
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const Sql = require("../base/sql")
|
|
2
|
+
const { SqlClients } = require("../utils")
|
|
2
3
|
|
|
3
4
|
const TABLE_NAME = "test"
|
|
4
5
|
|
|
@@ -46,7 +47,7 @@ function generateDeleteJson(table = TABLE_NAME, filters = {}) {
|
|
|
46
47
|
|
|
47
48
|
describe("SQL query builder", () => {
|
|
48
49
|
const limit = 500
|
|
49
|
-
const client =
|
|
50
|
+
const client = SqlClients.POSTGRES
|
|
50
51
|
let sql
|
|
51
52
|
|
|
52
53
|
beforeEach(() => {
|
|
@@ -173,15 +174,15 @@ describe("SQL query builder", () => {
|
|
|
173
174
|
})
|
|
174
175
|
|
|
175
176
|
it("should work with MS-SQL", () => {
|
|
176
|
-
const query = new Sql(
|
|
177
|
+
const query = new Sql(SqlClients.MS_SQL, 10)._query(generateReadJson())
|
|
177
178
|
expect(query).toEqual({
|
|
178
179
|
bindings: [10],
|
|
179
180
|
sql: `select * from (select top (@p0) * from [${TABLE_NAME}]) as [${TABLE_NAME}]`
|
|
180
181
|
})
|
|
181
182
|
})
|
|
182
183
|
|
|
183
|
-
it("should work with
|
|
184
|
-
const query = new Sql(
|
|
184
|
+
it("should work with MySQL", () => {
|
|
185
|
+
const query = new Sql(SqlClients.MY_SQL, 10)._query(generateReadJson())
|
|
185
186
|
expect(query).toEqual({
|
|
186
187
|
bindings: [10],
|
|
187
188
|
sql: `select * from (select * from \`${TABLE_NAME}\` limit ?) as \`${TABLE_NAME}\``
|
|
@@ -238,4 +239,49 @@ describe("SQL query builder", () => {
|
|
|
238
239
|
sql: `select * from (select * from "${TABLE_NAME}" where "${TABLE_NAME}"."property" > $1 limit $2) as "${TABLE_NAME}"`
|
|
239
240
|
})
|
|
240
241
|
})
|
|
242
|
+
|
|
243
|
+
it("should use like expression for MS-SQL when filter is contains", () => {
|
|
244
|
+
const query = new Sql(SqlClients.MS_SQL, 10)._query(generateReadJson({
|
|
245
|
+
filters: {
|
|
246
|
+
contains: {
|
|
247
|
+
age: 20,
|
|
248
|
+
name: "John"
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}))
|
|
252
|
+
expect(query).toEqual({
|
|
253
|
+
bindings: [10, "%20%", "%John%"],
|
|
254
|
+
sql: `select * from (select top (@p0) * from [${TABLE_NAME}] where LOWER(${TABLE_NAME}.age) LIKE @p1 and LOWER(${TABLE_NAME}.name) LIKE @p2) as [${TABLE_NAME}]`
|
|
255
|
+
})
|
|
256
|
+
})
|
|
257
|
+
|
|
258
|
+
it("should use JSON_CONTAINS expression for MySQL when filter is contains", () => {
|
|
259
|
+
const query = new Sql(SqlClients.MY_SQL, 10)._query(generateReadJson({
|
|
260
|
+
filters: {
|
|
261
|
+
contains: {
|
|
262
|
+
age: 20,
|
|
263
|
+
name: "John"
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}))
|
|
267
|
+
expect(query).toEqual({
|
|
268
|
+
bindings: [10],
|
|
269
|
+
sql: `select * from (select * from \`${TABLE_NAME}\` where JSON_CONTAINS(${TABLE_NAME}.age, '20') and JSON_CONTAINS(${TABLE_NAME}.name, '"John"') limit ?) as \`${TABLE_NAME}\``
|
|
270
|
+
})
|
|
271
|
+
})
|
|
272
|
+
|
|
273
|
+
it("should use jsonb operator expression for PostgreSQL when filter is contains", () => {
|
|
274
|
+
const query = new Sql(SqlClients.POSTGRES, 10)._query(generateReadJson({
|
|
275
|
+
filters: {
|
|
276
|
+
contains: {
|
|
277
|
+
age: 20,
|
|
278
|
+
name: "John"
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}))
|
|
282
|
+
expect(query).toEqual({
|
|
283
|
+
bindings: [10],
|
|
284
|
+
sql: `select * from (select * from \"${TABLE_NAME}\" where \"${TABLE_NAME}\".\"age\"::jsonb @> '[20]' and \"${TABLE_NAME}\".\"name\"::jsonb @> '["John"]' limit $1) as \"${TABLE_NAME}\"`
|
|
285
|
+
})
|
|
286
|
+
})
|
|
241
287
|
})
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
mockAuthWithNoCookie()
|
|
2
2
|
mockWorker()
|
|
3
|
+
mockUserGroups()
|
|
3
4
|
|
|
4
5
|
jest.mock("@budibase/backend-core/db", () => {
|
|
5
6
|
const coreDb = jest.requireActual("@budibase/backend-core/db")
|
|
@@ -29,6 +30,16 @@ function mockReset() {
|
|
|
29
30
|
mockWorker()
|
|
30
31
|
}
|
|
31
32
|
|
|
33
|
+
function mockUserGroups() {
|
|
34
|
+
jest.mock("@budibase/pro", () => ({
|
|
35
|
+
groups: {
|
|
36
|
+
getGroupRoleId: () => {
|
|
37
|
+
return "BASIC"
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
}))
|
|
41
|
+
}
|
|
42
|
+
|
|
32
43
|
function mockAuthWithNoCookie() {
|
|
33
44
|
jest.resetModules()
|
|
34
45
|
mockWorker()
|
package/src/utilities/global.js
CHANGED
|
@@ -12,9 +12,11 @@ const {
|
|
|
12
12
|
} = require("@budibase/backend-core/tenancy")
|
|
13
13
|
const env = require("../environment")
|
|
14
14
|
const { getAppId } = require("@budibase/backend-core/context")
|
|
15
|
+
const { groups } = require("@budibase/pro")
|
|
15
16
|
|
|
16
17
|
exports.updateAppRole = (user, { appId } = {}) => {
|
|
17
18
|
appId = appId || getAppId()
|
|
19
|
+
|
|
18
20
|
if (!user || !user.roles) {
|
|
19
21
|
return user
|
|
20
22
|
}
|
|
@@ -33,15 +35,30 @@ exports.updateAppRole = (user, { appId } = {}) => {
|
|
|
33
35
|
} else if (!user.roleId) {
|
|
34
36
|
user.roleId = BUILTIN_ROLE_IDS.PUBLIC
|
|
35
37
|
}
|
|
38
|
+
|
|
36
39
|
delete user.roles
|
|
37
40
|
return user
|
|
38
41
|
}
|
|
39
42
|
|
|
40
|
-
function
|
|
43
|
+
async function checkGroupRoles(user, { appId } = {}) {
|
|
44
|
+
if (!user.roleId) {
|
|
45
|
+
let roleId = await groups.getGroupRoleId(user, appId)
|
|
46
|
+
user.roleId = roleId
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return user
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
async function processUser(user, { appId } = {}) {
|
|
41
53
|
if (user) {
|
|
42
54
|
delete user.password
|
|
43
55
|
}
|
|
44
|
-
|
|
56
|
+
user = await exports.updateAppRole(user, { appId })
|
|
57
|
+
if (user?.userGroups?.length) {
|
|
58
|
+
user = await checkGroupRoles(user, { appId })
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return user
|
|
45
62
|
}
|
|
46
63
|
|
|
47
64
|
exports.getCachedSelf = async (ctx, appId) => {
|
|
@@ -89,6 +106,7 @@ exports.getGlobalUsers = async (users = null) => {
|
|
|
89
106
|
if (!appId) {
|
|
90
107
|
return globalUsers
|
|
91
108
|
}
|
|
109
|
+
|
|
92
110
|
return globalUsers.map(user => exports.updateAppRole(user))
|
|
93
111
|
}
|
|
94
112
|
|