@budibase/backend-core 2.32.12 → 2.32.14
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/index.js +129 -52
- package/dist/index.js.map +4 -4
- package/dist/index.js.meta.json +1 -1
- package/dist/package.json +4 -4
- package/dist/plugins.js.meta.json +1 -1
- package/dist/src/db/couch/DatabaseImpl.d.ts +1 -0
- package/dist/src/db/couch/DatabaseImpl.js +15 -5
- package/dist/src/db/couch/DatabaseImpl.js.map +1 -1
- package/dist/src/features/features.d.ts +47 -0
- package/dist/src/features/features.js +269 -0
- package/dist/src/features/features.js.map +1 -0
- package/dist/src/features/index.d.ts +2 -39
- package/dist/src/features/index.js +6 -235
- package/dist/src/features/index.js.map +1 -1
- package/dist/src/features/tests/utils.d.ts +3 -0
- package/dist/src/features/tests/utils.js +56 -0
- package/dist/src/features/tests/utils.js.map +1 -0
- package/dist/src/middleware/passport/sso/sso.js +0 -25
- package/dist/src/middleware/passport/sso/sso.js.map +1 -1
- package/dist/src/users/users.js +8 -1
- package/dist/src/users/users.js.map +1 -1
- package/dist/tests/core/utilities/structures/accounts.js +2 -2
- package/dist/tests/core/utilities/structures/accounts.js.map +1 -1
- package/dist/tests/core/utilities/structures/users.js +2 -5
- package/dist/tests/core/utilities/structures/users.js.map +1 -1
- package/package.json +4 -4
- package/src/db/couch/DatabaseImpl.ts +20 -6
- package/src/features/features.ts +300 -0
- package/src/features/index.ts +2 -281
- package/src/features/tests/utils.ts +64 -0
- package/src/middleware/passport/sso/sso.ts +0 -24
- package/src/users/users.ts +10 -2
- package/tests/core/utilities/structures/accounts.ts +0 -4
- package/tests/core/utilities/structures/users.ts +0 -5
package/dist/index.js
CHANGED
|
@@ -61260,7 +61260,7 @@ __export(src_exports, {
|
|
|
61260
61260
|
sql: () => sql_exports,
|
|
61261
61261
|
tenancy: () => tenancy,
|
|
61262
61262
|
timers: () => timers_exports,
|
|
61263
|
-
userUtils: () =>
|
|
61263
|
+
userUtils: () => utils_exports6,
|
|
61264
61264
|
users: () => users_exports3,
|
|
61265
61265
|
utils: () => utils_exports4,
|
|
61266
61266
|
withEnv: () => withEnv
|
|
@@ -61995,10 +61995,18 @@ function isSupportedUserSearch(query) {
|
|
|
61995
61995
|
{ op: "equal" /* EQUAL */, key: "_id" },
|
|
61996
61996
|
{ op: "oneOf" /* ONE_OF */, key: "_id" }
|
|
61997
61997
|
];
|
|
61998
|
-
for (
|
|
61998
|
+
for (const [key, operation] of Object.entries(query)) {
|
|
61999
61999
|
if (typeof operation !== "object") {
|
|
62000
62000
|
return false;
|
|
62001
62001
|
}
|
|
62002
|
+
if (isLogicalSearchOperator(key)) {
|
|
62003
|
+
for (const condition of query[key].conditions) {
|
|
62004
|
+
if (!isSupportedUserSearch(condition)) {
|
|
62005
|
+
return false;
|
|
62006
|
+
}
|
|
62007
|
+
}
|
|
62008
|
+
return true;
|
|
62009
|
+
}
|
|
62002
62010
|
const fields = Object.keys(operation || {});
|
|
62003
62011
|
if (fields.length === 0) {
|
|
62004
62012
|
continue;
|
|
@@ -62281,6 +62289,7 @@ var views_exports = {};
|
|
|
62281
62289
|
__export(views_exports, {
|
|
62282
62290
|
basicFields: () => basicFields,
|
|
62283
62291
|
calculationFields: () => calculationFields,
|
|
62292
|
+
hasCalculationFields: () => hasCalculationFields,
|
|
62284
62293
|
isBasicViewField: () => isBasicViewField,
|
|
62285
62294
|
isCalculationField: () => isCalculationField,
|
|
62286
62295
|
isCalculationView: () => isCalculationView
|
|
@@ -62293,6 +62302,9 @@ function isBasicViewField(field) {
|
|
|
62293
62302
|
return !isCalculationField(field);
|
|
62294
62303
|
}
|
|
62295
62304
|
function isCalculationView(view) {
|
|
62305
|
+
return view.type === "calculation" /* CALCULATION */;
|
|
62306
|
+
}
|
|
62307
|
+
function hasCalculationFields(view) {
|
|
62296
62308
|
return Object.values(view.schema || {}).some(isCalculationField);
|
|
62297
62309
|
}
|
|
62298
62310
|
function calculationFields(view) {
|
|
@@ -62726,7 +62738,7 @@ function search(docs, query) {
|
|
|
62726
62738
|
if (query.sort) {
|
|
62727
62739
|
result = sort(result, query.sort, query.sortOrder || "ascending" /* ASCENDING */);
|
|
62728
62740
|
}
|
|
62729
|
-
|
|
62741
|
+
const totalRows = result.length;
|
|
62730
62742
|
if (query.limit) {
|
|
62731
62743
|
result = limit(result, query.limit.toString());
|
|
62732
62744
|
}
|
|
@@ -67116,8 +67128,12 @@ __export(features_exports, {
|
|
|
67116
67128
|
FlagSet: () => FlagSet,
|
|
67117
67129
|
flags: () => flags,
|
|
67118
67130
|
init: () => init4,
|
|
67119
|
-
|
|
67131
|
+
parseEnvFlags: () => parseEnvFlags,
|
|
67132
|
+
shutdown: () => shutdown2,
|
|
67133
|
+
testutils: () => utils_exports5
|
|
67120
67134
|
});
|
|
67135
|
+
|
|
67136
|
+
// src/features/features.ts
|
|
67121
67137
|
var import_posthog_node = require("posthog-node");
|
|
67122
67138
|
var import_dd_trace3 = __toESM(require("dd-trace"));
|
|
67123
67139
|
|
|
@@ -67498,7 +67514,7 @@ var Duration = class _Duration {
|
|
|
67498
67514
|
}
|
|
67499
67515
|
};
|
|
67500
67516
|
|
|
67501
|
-
// src/features/
|
|
67517
|
+
// src/features/features.ts
|
|
67502
67518
|
var posthog;
|
|
67503
67519
|
function init4(opts) {
|
|
67504
67520
|
if (environment_default.POSTHOG_TOKEN && environment_default.POSTHOG_API_HOST && !environment_default.SELF_HOSTED && environment_default.POSTHOG_FEATURE_FLAGS_ENABLED) {
|
|
@@ -67563,6 +67579,21 @@ var NumberFlag = class extends Flag {
|
|
|
67563
67579
|
throw new Error(`could not parse value "${value}" as number`);
|
|
67564
67580
|
}
|
|
67565
67581
|
};
|
|
67582
|
+
function parseEnvFlags(flags2) {
|
|
67583
|
+
const split = flags2.split(",").map((x) => x.split(":"));
|
|
67584
|
+
const result = [];
|
|
67585
|
+
for (const [tenantId, ...features] of split) {
|
|
67586
|
+
for (let feature of features) {
|
|
67587
|
+
let value = true;
|
|
67588
|
+
if (feature.startsWith("!")) {
|
|
67589
|
+
feature = feature.slice(1);
|
|
67590
|
+
value = false;
|
|
67591
|
+
}
|
|
67592
|
+
result.push({ tenantId, key: feature, value });
|
|
67593
|
+
}
|
|
67594
|
+
}
|
|
67595
|
+
return result;
|
|
67596
|
+
}
|
|
67566
67597
|
var FlagSet = class {
|
|
67567
67598
|
constructor(flagSchema) {
|
|
67568
67599
|
this.flagSchema = flagSchema;
|
|
@@ -67597,28 +67628,24 @@ var FlagSet = class {
|
|
|
67597
67628
|
const flagValues = this.defaults();
|
|
67598
67629
|
const currentTenantId = getTenantId();
|
|
67599
67630
|
const specificallySetFalse = /* @__PURE__ */ new Set();
|
|
67600
|
-
const
|
|
67601
|
-
|
|
67631
|
+
for (const { tenantId, key, value } of parseEnvFlags(
|
|
67632
|
+
environment_default.TENANT_FEATURE_FLAGS || ""
|
|
67633
|
+
)) {
|
|
67602
67634
|
if (!tenantId || tenantId !== "*" && tenantId !== currentTenantId) {
|
|
67603
67635
|
continue;
|
|
67604
67636
|
}
|
|
67605
67637
|
tags[`readFromEnvironmentVars`] = true;
|
|
67606
|
-
|
|
67607
|
-
|
|
67608
|
-
|
|
67609
|
-
|
|
67610
|
-
|
|
67611
|
-
|
|
67612
|
-
|
|
67613
|
-
|
|
67614
|
-
continue;
|
|
67615
|
-
}
|
|
67616
|
-
if (typeof flagValues[feature] !== "boolean") {
|
|
67617
|
-
throw new Error(`Feature: ${feature} is not a boolean`);
|
|
67618
|
-
}
|
|
67619
|
-
flagValues[feature] = value;
|
|
67620
|
-
tags[`flags.${feature}.source`] = "environment";
|
|
67638
|
+
if (value === false) {
|
|
67639
|
+
specificallySetFalse.add(key);
|
|
67640
|
+
}
|
|
67641
|
+
if (!this.isFlagName(key)) {
|
|
67642
|
+
continue;
|
|
67643
|
+
}
|
|
67644
|
+
if (typeof flagValues[key] !== "boolean") {
|
|
67645
|
+
throw new Error(`Feature: ${key} is not a boolean`);
|
|
67621
67646
|
}
|
|
67647
|
+
flagValues[key] = value;
|
|
67648
|
+
tags[`flags.${key}.source`] = "environment";
|
|
67622
67649
|
}
|
|
67623
67650
|
const license = ctx?.user?.license;
|
|
67624
67651
|
if (license) {
|
|
@@ -67685,6 +67712,60 @@ var flags = new FlagSet({
|
|
|
67685
67712
|
["ENRICHED_RELATIONSHIPS" /* ENRICHED_RELATIONSHIPS */]: Flag.boolean(environment_default.isDev())
|
|
67686
67713
|
});
|
|
67687
67714
|
|
|
67715
|
+
// src/features/tests/utils.ts
|
|
67716
|
+
var utils_exports5 = {};
|
|
67717
|
+
__export(utils_exports5, {
|
|
67718
|
+
setFeatureFlags: () => setFeatureFlags2,
|
|
67719
|
+
withFeatureFlags: () => withFeatureFlags
|
|
67720
|
+
});
|
|
67721
|
+
function getCurrentFlags() {
|
|
67722
|
+
const result = {};
|
|
67723
|
+
for (const { tenantId, key, value } of parseEnvFlags(
|
|
67724
|
+
process.env.TENANT_FEATURE_FLAGS || ""
|
|
67725
|
+
)) {
|
|
67726
|
+
const tenantFlags = result[tenantId] || {};
|
|
67727
|
+
if (tenantFlags[key] === false) {
|
|
67728
|
+
continue;
|
|
67729
|
+
}
|
|
67730
|
+
tenantFlags[key] = value;
|
|
67731
|
+
result[tenantId] = tenantFlags;
|
|
67732
|
+
}
|
|
67733
|
+
return result;
|
|
67734
|
+
}
|
|
67735
|
+
function buildFlagString(flags2) {
|
|
67736
|
+
const parts = [];
|
|
67737
|
+
for (const [tenantId, tenantFlags] of Object.entries(flags2)) {
|
|
67738
|
+
for (const [key, value] of Object.entries(tenantFlags)) {
|
|
67739
|
+
if (value === false) {
|
|
67740
|
+
parts.push(`${tenantId}:!${key}`);
|
|
67741
|
+
} else {
|
|
67742
|
+
parts.push(`${tenantId}:${key}`);
|
|
67743
|
+
}
|
|
67744
|
+
}
|
|
67745
|
+
}
|
|
67746
|
+
return parts.join(",");
|
|
67747
|
+
}
|
|
67748
|
+
function setFeatureFlags2(tenantId, flags2) {
|
|
67749
|
+
const current = getCurrentFlags();
|
|
67750
|
+
for (const [key, value] of Object.entries(flags2)) {
|
|
67751
|
+
const tenantFlags = current[tenantId] || {};
|
|
67752
|
+
tenantFlags[key] = value;
|
|
67753
|
+
current[tenantId] = tenantFlags;
|
|
67754
|
+
}
|
|
67755
|
+
const flagString = buildFlagString(current);
|
|
67756
|
+
return setEnv({ TENANT_FEATURE_FLAGS: flagString });
|
|
67757
|
+
}
|
|
67758
|
+
function withFeatureFlags(tenantId, flags2, f) {
|
|
67759
|
+
const cleanup3 = setFeatureFlags2(tenantId, flags2);
|
|
67760
|
+
const result = f();
|
|
67761
|
+
if (result instanceof Promise) {
|
|
67762
|
+
return result.finally(cleanup3);
|
|
67763
|
+
} else {
|
|
67764
|
+
cleanup3();
|
|
67765
|
+
return result;
|
|
67766
|
+
}
|
|
67767
|
+
}
|
|
67768
|
+
|
|
67688
67769
|
// src/db/couch/DatabaseImpl.ts
|
|
67689
67770
|
var DATABASE_NOT_FOUND = "Database does not exist.";
|
|
67690
67771
|
function buildNano(couchInfo) {
|
|
@@ -67815,12 +67896,13 @@ var DatabaseImpl = class _DatabaseImpl {
|
|
|
67815
67896
|
}
|
|
67816
67897
|
async getMultiple(ids, opts) {
|
|
67817
67898
|
ids = [...new Set(ids)];
|
|
67899
|
+
const includeDocs = !opts?.excludeDocs;
|
|
67818
67900
|
const response = await this.allDocs({
|
|
67819
67901
|
keys: ids,
|
|
67820
|
-
include_docs:
|
|
67902
|
+
include_docs: includeDocs
|
|
67821
67903
|
});
|
|
67822
67904
|
const rowUnavailable = (row) => {
|
|
67823
|
-
if (row.doc == null || "deleted" in row.value && row.value.deleted) {
|
|
67905
|
+
if (includeDocs && row.doc == null || row.value && "deleted" in row.value && row.value.deleted) {
|
|
67824
67906
|
return true;
|
|
67825
67907
|
}
|
|
67826
67908
|
return row.error === "not_found";
|
|
@@ -67832,7 +67914,7 @@ var DatabaseImpl = class _DatabaseImpl {
|
|
|
67832
67914
|
const missingIds = missing.map((row) => row.key).join(", ");
|
|
67833
67915
|
throw new Error(`Unable to get documents: ${missingIds}`);
|
|
67834
67916
|
}
|
|
67835
|
-
return rows.map((row) => row.doc);
|
|
67917
|
+
return rows.map((row) => includeDocs ? row.doc : row.value);
|
|
67836
67918
|
}
|
|
67837
67919
|
async remove(idOrDoc, rev) {
|
|
67838
67920
|
return this.performCall((db) => {
|
|
@@ -67948,11 +68030,21 @@ var DatabaseImpl = class _DatabaseImpl {
|
|
|
67948
68030
|
return this.performCall(() => {
|
|
67949
68031
|
return async () => {
|
|
67950
68032
|
const response = await directCouchUrlCall(args);
|
|
67951
|
-
const
|
|
68033
|
+
const text = await response.text();
|
|
67952
68034
|
if (response.status > 300) {
|
|
68035
|
+
let json;
|
|
68036
|
+
try {
|
|
68037
|
+
json = JSON.parse(text);
|
|
68038
|
+
} catch (err) {
|
|
68039
|
+
console.error(`SQS error: ${text}`);
|
|
68040
|
+
throw new CouchDBError(
|
|
68041
|
+
"error while running SQS query, please try again later",
|
|
68042
|
+
{ name: "sqs_error", status: response.status }
|
|
68043
|
+
);
|
|
68044
|
+
}
|
|
67953
68045
|
throw json;
|
|
67954
68046
|
}
|
|
67955
|
-
return
|
|
68047
|
+
return JSON.parse(text);
|
|
67956
68048
|
};
|
|
67957
68049
|
});
|
|
67958
68050
|
}
|
|
@@ -68965,8 +69057,8 @@ __export(users_exports3, {
|
|
|
68965
69057
|
});
|
|
68966
69058
|
|
|
68967
69059
|
// src/users/utils.ts
|
|
68968
|
-
var
|
|
68969
|
-
__export(
|
|
69060
|
+
var utils_exports6 = {};
|
|
69061
|
+
__export(utils_exports6, {
|
|
68970
69062
|
getAccountHolderFromUserIds: () => getAccountHolderFromUserIds,
|
|
68971
69063
|
hasAdminPermissions: () => hasAdminPermissions2,
|
|
68972
69064
|
hasAppBuilderPermissions: () => hasAppBuilderPermissions2,
|
|
@@ -72991,6 +73083,12 @@ async function paginatedUsers({
|
|
|
72991
73083
|
userList = await bulkGetGlobalUsersById(query?.oneOf?._id, {
|
|
72992
73084
|
cleanup: true
|
|
72993
73085
|
});
|
|
73086
|
+
} else if (query) {
|
|
73087
|
+
const response = await db.allDocs(
|
|
73088
|
+
getGlobalUserParams(null, { ...opts, limit: void 0 })
|
|
73089
|
+
);
|
|
73090
|
+
userList = response.rows.map((row) => row.doc);
|
|
73091
|
+
userList = filters_exports.search(userList, { query, limit: opts.limit }).rows;
|
|
72994
73092
|
} else {
|
|
72995
73093
|
const response = await db.allDocs(getGlobalUserParams(null, opts));
|
|
72996
73094
|
userList = response.rows.map((row) => row.doc);
|
|
@@ -73808,7 +73906,6 @@ __export(google_exports, {
|
|
|
73808
73906
|
});
|
|
73809
73907
|
|
|
73810
73908
|
// src/middleware/passport/sso/sso.ts
|
|
73811
|
-
var import_node_fetch5 = __toESM(require("node-fetch"));
|
|
73812
73909
|
var ssoSaveUserNoOp = (user) => Promise.resolve(user);
|
|
73813
73910
|
async function authenticate2(details, requireLocalAccount = true, done, saveUserFn) {
|
|
73814
73911
|
if (!saveUserFn) {
|
|
@@ -73863,24 +73960,10 @@ async function authenticate2(details, requireLocalAccount = true, done, saveUser
|
|
|
73863
73960
|
}
|
|
73864
73961
|
return done(null, ssoUser);
|
|
73865
73962
|
}
|
|
73866
|
-
async function getProfilePictureUrl(user, details) {
|
|
73867
|
-
const pictureUrl = details.profile?._json.picture;
|
|
73868
|
-
if (pictureUrl) {
|
|
73869
|
-
const response = await (0, import_node_fetch5.default)(pictureUrl);
|
|
73870
|
-
if (response.status === 200) {
|
|
73871
|
-
const type = response.headers.get("content-type");
|
|
73872
|
-
if (type.startsWith("image/")) {
|
|
73873
|
-
return pictureUrl;
|
|
73874
|
-
}
|
|
73875
|
-
}
|
|
73876
|
-
}
|
|
73877
|
-
}
|
|
73878
73963
|
async function syncUser(user, details) {
|
|
73879
73964
|
let firstName;
|
|
73880
73965
|
let lastName;
|
|
73881
|
-
let pictureUrl;
|
|
73882
73966
|
let oauth2;
|
|
73883
|
-
let thirdPartyProfile;
|
|
73884
73967
|
if (details.profile) {
|
|
73885
73968
|
const profile = details.profile;
|
|
73886
73969
|
if (profile.name) {
|
|
@@ -73892,10 +73975,6 @@ async function syncUser(user, details) {
|
|
|
73892
73975
|
lastName = name.familyName;
|
|
73893
73976
|
}
|
|
73894
73977
|
}
|
|
73895
|
-
pictureUrl = await getProfilePictureUrl(user, details);
|
|
73896
|
-
thirdPartyProfile = {
|
|
73897
|
-
...profile._json
|
|
73898
|
-
};
|
|
73899
73978
|
}
|
|
73900
73979
|
if (details.oauth2) {
|
|
73901
73980
|
oauth2 = {
|
|
@@ -73908,8 +73987,6 @@ async function syncUser(user, details) {
|
|
|
73908
73987
|
providerType: details.providerType,
|
|
73909
73988
|
firstName,
|
|
73910
73989
|
lastName,
|
|
73911
|
-
thirdPartyProfile,
|
|
73912
|
-
pictureUrl,
|
|
73913
73990
|
oauth2
|
|
73914
73991
|
};
|
|
73915
73992
|
}
|
|
@@ -73971,7 +74048,7 @@ __export(oidc_exports, {
|
|
|
73971
74048
|
getCallbackUrl: () => getCallbackUrl2,
|
|
73972
74049
|
strategyFactory: () => strategyFactory2
|
|
73973
74050
|
});
|
|
73974
|
-
var
|
|
74051
|
+
var import_node_fetch5 = __toESM(require("node-fetch"));
|
|
73975
74052
|
var OIDCStrategy = require_lib9().Strategy;
|
|
73976
74053
|
function buildVerifyFn2(saveUserFn) {
|
|
73977
74054
|
return async (issuer, sub, profile, jwtClaims, accessToken, refreshToken, idToken, params2, done) => {
|
|
@@ -74031,7 +74108,7 @@ async function fetchStrategyConfig(oidcConfig, callbackUrl) {
|
|
|
74031
74108
|
"Configuration invalid. Must contain clientID, clientSecret, callbackUrl and configUrl"
|
|
74032
74109
|
);
|
|
74033
74110
|
}
|
|
74034
|
-
const response = await (0,
|
|
74111
|
+
const response = await (0, import_node_fetch5.default)(configUrl);
|
|
74035
74112
|
if (!response.ok) {
|
|
74036
74113
|
throw new Error(
|
|
74037
74114
|
`Unexpected response when fetching openid-configuration: ${response.statusText}`
|