@budibase/backend-core 2.32.7 → 2.32.9
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 +729 -615
- 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/cache/appMetadata.js +3 -3
- package/dist/src/cache/appMetadata.js.map +1 -1
- package/dist/src/context/mainContext.d.ts +3 -1
- package/dist/src/context/mainContext.js +19 -0
- package/dist/src/context/mainContext.js.map +1 -1
- package/dist/src/context/types.d.ts +2 -1
- package/dist/src/db/couch/DatabaseImpl.d.ts +1 -0
- package/dist/src/db/couch/DatabaseImpl.js +35 -5
- package/dist/src/db/couch/DatabaseImpl.js.map +1 -1
- package/dist/src/db/lucene.js +0 -1
- package/dist/src/db/lucene.js.map +1 -1
- package/dist/src/docIds/params.d.ts +2 -3
- package/dist/src/docIds/params.js +6 -3
- package/dist/src/docIds/params.js.map +1 -1
- package/dist/src/features/index.js +3 -2
- package/dist/src/features/index.js.map +1 -1
- package/dist/src/index.d.ts +2 -0
- package/dist/src/sql/sql.js +45 -9
- package/dist/src/sql/sql.js.map +1 -1
- package/dist/src/users/users.d.ts +1 -2
- package/dist/src/users/users.js +0 -24
- package/dist/src/users/users.js.map +1 -1
- package/package.json +4 -4
- package/src/cache/appMetadata.ts +3 -3
- package/src/context/mainContext.ts +18 -1
- package/src/context/types.ts +2 -1
- package/src/db/couch/DatabaseImpl.ts +35 -6
- package/src/db/lucene.ts +0 -1
- package/src/docIds/params.ts +8 -6
- package/src/features/index.ts +3 -1
- package/src/sql/sql.ts +46 -6
- package/src/users/users.ts +0 -29
package/dist/index.js
CHANGED
|
@@ -54894,6 +54894,7 @@ __export(helpers_exports, {
|
|
|
54894
54894
|
isGoogleSheets: () => isGoogleSheets,
|
|
54895
54895
|
isSQL: () => isSQL,
|
|
54896
54896
|
schema: () => schema_exports,
|
|
54897
|
+
views: () => views_exports,
|
|
54897
54898
|
withTimeout: () => withTimeout
|
|
54898
54899
|
});
|
|
54899
54900
|
|
|
@@ -55044,6 +55045,7 @@ __export(schema_exports, {
|
|
|
55044
55045
|
decodeNonAscii: () => decodeNonAscii,
|
|
55045
55046
|
encodeNonAscii: () => encodeNonAscii,
|
|
55046
55047
|
isDeprecatedSingleUserColumn: () => isDeprecatedSingleUserColumn,
|
|
55048
|
+
isNumeric: () => isNumeric,
|
|
55047
55049
|
isRequired: () => isRequired
|
|
55048
55050
|
});
|
|
55049
55051
|
function isDeprecatedSingleUserColumn(schema) {
|
|
@@ -55065,9 +55067,38 @@ function decodeNonAscii(str) {
|
|
|
55065
55067
|
(match, p1) => String.fromCharCode(parseInt(p1, 16))
|
|
55066
55068
|
);
|
|
55067
55069
|
}
|
|
55070
|
+
function isNumeric(field) {
|
|
55071
|
+
return field.type === "number" /* NUMBER */ || field.type === "bigint" /* BIGINT */;
|
|
55072
|
+
}
|
|
55068
55073
|
|
|
55069
|
-
// ../shared-core/src/
|
|
55074
|
+
// ../shared-core/src/helpers/views.ts
|
|
55075
|
+
var views_exports = {};
|
|
55076
|
+
__export(views_exports, {
|
|
55077
|
+
basicFields: () => basicFields,
|
|
55078
|
+
calculationFields: () => calculationFields,
|
|
55079
|
+
isBasicViewField: () => isBasicViewField,
|
|
55080
|
+
isCalculationField: () => isCalculationField,
|
|
55081
|
+
isCalculationView: () => isCalculationView
|
|
55082
|
+
});
|
|
55070
55083
|
var import_lodash = require("lodash");
|
|
55084
|
+
function isCalculationField(field) {
|
|
55085
|
+
return "calculationType" in field;
|
|
55086
|
+
}
|
|
55087
|
+
function isBasicViewField(field) {
|
|
55088
|
+
return !isCalculationField(field);
|
|
55089
|
+
}
|
|
55090
|
+
function isCalculationView(view) {
|
|
55091
|
+
return Object.values(view.schema || {}).some(isCalculationField);
|
|
55092
|
+
}
|
|
55093
|
+
function calculationFields(view) {
|
|
55094
|
+
return (0, import_lodash.pickBy)(view.schema || {}, isCalculationField);
|
|
55095
|
+
}
|
|
55096
|
+
function basicFields(view) {
|
|
55097
|
+
return (0, import_lodash.pickBy)(view.schema || {}, (field) => !isCalculationField(field));
|
|
55098
|
+
}
|
|
55099
|
+
|
|
55100
|
+
// ../shared-core/src/filters.ts
|
|
55101
|
+
var import_lodash2 = require("lodash");
|
|
55071
55102
|
var HBS_REGEX = /{{([^{].*?)}}/g;
|
|
55072
55103
|
var LOGICAL_OPERATORS = Object.values(LogicalOperator);
|
|
55073
55104
|
var SEARCH_OPERATORS = [
|
|
@@ -55136,7 +55167,7 @@ var NoEmptyFilterStrings = [
|
|
|
55136
55167
|
];
|
|
55137
55168
|
function recurseLogicalOperators(filters, fn) {
|
|
55138
55169
|
for (const logical of LOGICAL_OPERATORS) {
|
|
55139
|
-
if (filters[logical]) {
|
|
55170
|
+
if (filters?.[logical]) {
|
|
55140
55171
|
filters[logical].conditions = filters[logical].conditions.map(
|
|
55141
55172
|
(condition) => fn(condition)
|
|
55142
55173
|
);
|
|
@@ -55345,7 +55376,7 @@ var buildQuery = (filter) => {
|
|
|
55345
55376
|
function fixupFilterArrays(filters) {
|
|
55346
55377
|
for (const searchField of Object.values(ArrayOperator)) {
|
|
55347
55378
|
const field = filters[searchField];
|
|
55348
|
-
if (field == null || !(0,
|
|
55379
|
+
if (field == null || !(0, import_lodash2.isPlainObject)(field)) {
|
|
55349
55380
|
continue;
|
|
55350
55381
|
}
|
|
55351
55382
|
for (const key of Object.keys(field)) {
|
|
@@ -55432,10 +55463,10 @@ function runQuery(docs, query) {
|
|
|
55432
55463
|
if (docValue == null || docValue === "") {
|
|
55433
55464
|
return false;
|
|
55434
55465
|
}
|
|
55435
|
-
if ((0,
|
|
55466
|
+
if ((0, import_lodash2.isPlainObject)(testValue.low) && (0, import_lodash2.isEmpty)(testValue.low)) {
|
|
55436
55467
|
testValue.low = void 0;
|
|
55437
55468
|
}
|
|
55438
|
-
if ((0,
|
|
55469
|
+
if ((0, import_lodash2.isPlainObject)(testValue.high) && (0, import_lodash2.isEmpty)(testValue.high)) {
|
|
55439
55470
|
testValue.high = void 0;
|
|
55440
55471
|
}
|
|
55441
55472
|
if (testValue.low == null && testValue.high == null) {
|
|
@@ -55687,6 +55718,7 @@ var utils_exports = {};
|
|
|
55687
55718
|
__export(utils_exports, {
|
|
55688
55719
|
filterValueToLabel: () => filterValueToLabel,
|
|
55689
55720
|
hasSchema: () => hasSchema,
|
|
55721
|
+
isSupportedUserSearch: () => isSupportedUserSearch,
|
|
55690
55722
|
parallelForeach: () => parallelForeach,
|
|
55691
55723
|
trimOtherProps: () => trimOtherProps,
|
|
55692
55724
|
unreachable: () => unreachable
|
|
@@ -55742,6 +55774,29 @@ function trimOtherProps(object, allowedProps) {
|
|
|
55742
55774
|
);
|
|
55743
55775
|
return result;
|
|
55744
55776
|
}
|
|
55777
|
+
function isSupportedUserSearch(query) {
|
|
55778
|
+
const allowed = [
|
|
55779
|
+
{ op: "string" /* STRING */, key: "email" },
|
|
55780
|
+
{ op: "equal" /* EQUAL */, key: "_id" },
|
|
55781
|
+
{ op: "oneOf" /* ONE_OF */, key: "_id" }
|
|
55782
|
+
];
|
|
55783
|
+
for (let [key, operation] of Object.entries(query)) {
|
|
55784
|
+
if (typeof operation !== "object") {
|
|
55785
|
+
return false;
|
|
55786
|
+
}
|
|
55787
|
+
const fields = Object.keys(operation || {});
|
|
55788
|
+
if (fields.length === 0) {
|
|
55789
|
+
continue;
|
|
55790
|
+
}
|
|
55791
|
+
const allowedOperation = allowed.find(
|
|
55792
|
+
(allow) => allow.op === key && fields.length === 1 && fields[0] === allow.key
|
|
55793
|
+
);
|
|
55794
|
+
if (!allowedOperation) {
|
|
55795
|
+
return false;
|
|
55796
|
+
}
|
|
55797
|
+
}
|
|
55798
|
+
return true;
|
|
55799
|
+
}
|
|
55745
55800
|
|
|
55746
55801
|
// ../shared-core/src/sdk/index.ts
|
|
55747
55802
|
var sdk_exports = {};
|
|
@@ -56132,6 +56187,7 @@ __export(context_exports, {
|
|
|
56132
56187
|
getProdAppDB: () => getProdAppDB,
|
|
56133
56188
|
getProdAppId: () => getProdAppId,
|
|
56134
56189
|
getScimDBName: () => getScimDBName,
|
|
56190
|
+
getTableForView: () => getTableForView,
|
|
56135
56191
|
getTenantIDFromAppID: () => getTenantIDFromAppID,
|
|
56136
56192
|
getTenantId: () => getTenantId,
|
|
56137
56193
|
identity: () => identity_exports,
|
|
@@ -56139,7 +56195,8 @@ __export(context_exports, {
|
|
|
56139
56195
|
isScim: () => isScim,
|
|
56140
56196
|
isTenancyEnabled: () => isTenancyEnabled,
|
|
56141
56197
|
isTenantIdSet: () => isTenantIdSet,
|
|
56142
|
-
setFeatureFlags: () => setFeatureFlags
|
|
56198
|
+
setFeatureFlags: () => setFeatureFlags,
|
|
56199
|
+
setTableForView: () => setTableForView
|
|
56143
56200
|
});
|
|
56144
56201
|
|
|
56145
56202
|
// src/context/identity.ts
|
|
@@ -56193,7 +56250,7 @@ function getAccountUserId(account) {
|
|
|
56193
56250
|
|
|
56194
56251
|
// src/environment.ts
|
|
56195
56252
|
var import_fs = require("fs");
|
|
56196
|
-
var
|
|
56253
|
+
var import_lodash3 = require("lodash");
|
|
56197
56254
|
function isTest() {
|
|
56198
56255
|
return isJest();
|
|
56199
56256
|
}
|
|
@@ -56361,7 +56418,7 @@ var environment = {
|
|
|
56361
56418
|
OPENAI_API_KEY: process.env.OPENAI_API_KEY
|
|
56362
56419
|
};
|
|
56363
56420
|
function setEnv(newEnvVars) {
|
|
56364
|
-
const oldEnv = (0,
|
|
56421
|
+
const oldEnv = (0, import_lodash3.cloneDeep)(environment);
|
|
56365
56422
|
let key;
|
|
56366
56423
|
for (key in newEnvVars) {
|
|
56367
56424
|
environment._set(key, newEnvVars[key]);
|
|
@@ -56913,6 +56970,7 @@ __export(db_exports, {
|
|
|
56913
56970
|
isProdAppID: () => isProdAppID,
|
|
56914
56971
|
isSameAppID: () => isSameAppID,
|
|
56915
56972
|
isTableId: () => isTableId,
|
|
56973
|
+
isViewId: () => isViewId,
|
|
56916
56974
|
paginatedSearch: () => paginatedSearch,
|
|
56917
56975
|
pagination: () => pagination,
|
|
56918
56976
|
prefixRoleID: () => prefixRoleID,
|
|
@@ -58453,6 +58511,7 @@ var AppState = /* @__PURE__ */ ((AppState2) => {
|
|
|
58453
58511
|
return AppState2;
|
|
58454
58512
|
})(AppState || {});
|
|
58455
58513
|
var EXPIRY_SECONDS = 3600;
|
|
58514
|
+
var INVALID_EXPIRY_SECONDS = 60;
|
|
58456
58515
|
async function populateFromDB(appId) {
|
|
58457
58516
|
return doWithDB(
|
|
58458
58517
|
appId,
|
|
@@ -58475,7 +58534,7 @@ async function getAppMetadata(appId) {
|
|
|
58475
58534
|
} catch (err) {
|
|
58476
58535
|
if (err && err.status === 404) {
|
|
58477
58536
|
metadata = { state: "invalid" /* INVALID */ };
|
|
58478
|
-
expiry =
|
|
58537
|
+
expiry = INVALID_EXPIRY_SECONDS;
|
|
58479
58538
|
} else {
|
|
58480
58539
|
throw err;
|
|
58481
58540
|
}
|
|
@@ -58530,6 +58589,7 @@ __export(docIds_exports, {
|
|
|
58530
58589
|
isDatasourceId: () => isDatasourceId,
|
|
58531
58590
|
isGlobalUserID: () => isGlobalUserID,
|
|
58532
58591
|
isTableId: () => isTableId,
|
|
58592
|
+
isViewId: () => isViewId,
|
|
58533
58593
|
prefixRoleID: () => prefixRoleID
|
|
58534
58594
|
});
|
|
58535
58595
|
|
|
@@ -58615,8 +58675,11 @@ function getQueryIndex(viewName) {
|
|
|
58615
58675
|
var isTableId = (id) => {
|
|
58616
58676
|
return !!id && (id.startsWith(`${"ta" /* TABLE */}${SEPARATOR}`) || id.startsWith(`${"datasource_plus" /* DATASOURCE_PLUS */}${SEPARATOR}`));
|
|
58617
58677
|
};
|
|
58678
|
+
function isViewId(id) {
|
|
58679
|
+
return !!id && id.startsWith(`${"view" /* VIEW */}${SEPARATOR}`);
|
|
58680
|
+
}
|
|
58618
58681
|
var isDatasourceId = (id) => {
|
|
58619
|
-
return id && id.startsWith(`${"datasource" /* DATASOURCE */}${SEPARATOR}`);
|
|
58682
|
+
return !!id && id.startsWith(`${"datasource" /* DATASOURCE */}${SEPARATOR}`);
|
|
58620
58683
|
};
|
|
58621
58684
|
function getWorkspaceParams(id = "", otherProps = {}) {
|
|
58622
58685
|
return {
|
|
@@ -59815,87 +59878,467 @@ __export(features_exports, {
|
|
|
59815
59878
|
});
|
|
59816
59879
|
var import_posthog_node = require("posthog-node");
|
|
59817
59880
|
var import_dd_trace3 = __toESM(require("dd-trace"));
|
|
59818
|
-
|
|
59819
|
-
|
|
59820
|
-
|
|
59821
|
-
|
|
59822
|
-
|
|
59823
|
-
|
|
59824
|
-
|
|
59825
|
-
|
|
59826
|
-
|
|
59827
|
-
|
|
59828
|
-
|
|
59881
|
+
|
|
59882
|
+
// src/utils/index.ts
|
|
59883
|
+
var utils_exports4 = {};
|
|
59884
|
+
__export(utils_exports4, {
|
|
59885
|
+
Duration: () => Duration,
|
|
59886
|
+
DurationType: () => DurationType,
|
|
59887
|
+
clearCookie: () => clearCookie,
|
|
59888
|
+
compare: () => compare,
|
|
59889
|
+
getAppIdFromCtx: () => getAppIdFromCtx,
|
|
59890
|
+
getCookie: () => getCookie,
|
|
59891
|
+
hasCircularStructure: () => hasCircularStructure,
|
|
59892
|
+
hash: () => hash,
|
|
59893
|
+
isAudited: () => isAudited,
|
|
59894
|
+
isClient: () => isClient,
|
|
59895
|
+
isPublicApiRequest: () => isPublicApiRequest,
|
|
59896
|
+
isServingApp: () => isServingApp,
|
|
59897
|
+
isServingBuilder: () => isServingBuilder,
|
|
59898
|
+
isServingBuilderPreview: () => isServingBuilderPreview,
|
|
59899
|
+
isValidInternalAPIKey: () => isValidInternalAPIKey,
|
|
59900
|
+
newid: () => newid,
|
|
59901
|
+
openJwt: () => openJwt,
|
|
59902
|
+
resolveAppUrl: () => resolveAppUrl,
|
|
59903
|
+
setCookie: () => setCookie,
|
|
59904
|
+
timeout: () => timeout,
|
|
59905
|
+
validEmail: () => validEmail
|
|
59906
|
+
});
|
|
59907
|
+
|
|
59908
|
+
// src/utils/hashing.ts
|
|
59909
|
+
var bcrypt = environment_default.JS_BCRYPT ? require("bcryptjs") : require("bcrypt");
|
|
59910
|
+
var SALT_ROUNDS = environment_default.SALT_ROUNDS || 10;
|
|
59911
|
+
async function hash(data) {
|
|
59912
|
+
const salt = await bcrypt.genSalt(SALT_ROUNDS);
|
|
59913
|
+
return bcrypt.hash(data, salt);
|
|
59914
|
+
}
|
|
59915
|
+
async function compare(data, encrypted) {
|
|
59916
|
+
return bcrypt.compare(data, encrypted);
|
|
59917
|
+
}
|
|
59918
|
+
|
|
59919
|
+
// src/tenancy/index.ts
|
|
59920
|
+
var tenancy_exports = {};
|
|
59921
|
+
__export(tenancy_exports, {
|
|
59922
|
+
addTenantToUrl: () => addTenantToUrl,
|
|
59923
|
+
getTenantDB: () => getTenantDB,
|
|
59924
|
+
getTenantIDFromCtx: () => getTenantIDFromCtx,
|
|
59925
|
+
getTenantInfo: () => getTenantInfo,
|
|
59926
|
+
isUserInAppTenant: () => isUserInAppTenant,
|
|
59927
|
+
saveTenantInfo: () => saveTenantInfo
|
|
59928
|
+
});
|
|
59929
|
+
|
|
59930
|
+
// src/tenancy/db.ts
|
|
59931
|
+
function getTenantDB(tenantId) {
|
|
59932
|
+
return getDB(getGlobalDBName(tenantId));
|
|
59933
|
+
}
|
|
59934
|
+
async function saveTenantInfo(tenantInfo) {
|
|
59935
|
+
const db = getTenantDB(tenantInfo.tenantId);
|
|
59936
|
+
return db.put({
|
|
59937
|
+
_id: "tenant_info",
|
|
59938
|
+
...tenantInfo
|
|
59939
|
+
});
|
|
59940
|
+
}
|
|
59941
|
+
async function getTenantInfo(tenantId) {
|
|
59942
|
+
try {
|
|
59943
|
+
const db = getTenantDB(tenantId);
|
|
59944
|
+
const tenantInfo = await db.get("tenant_info");
|
|
59945
|
+
delete tenantInfo.owner.password;
|
|
59946
|
+
return tenantInfo;
|
|
59947
|
+
} catch {
|
|
59948
|
+
return void 0;
|
|
59829
59949
|
}
|
|
59830
59950
|
}
|
|
59831
|
-
|
|
59832
|
-
|
|
59951
|
+
|
|
59952
|
+
// src/tenancy/tenancy.ts
|
|
59953
|
+
function addTenantToUrl(url) {
|
|
59954
|
+
const tenantId = getTenantId();
|
|
59955
|
+
if (isMultiTenant()) {
|
|
59956
|
+
const char = url.indexOf("?") === -1 ? "?" : "&";
|
|
59957
|
+
url += `${char}tenantId=${tenantId}`;
|
|
59958
|
+
}
|
|
59959
|
+
return url;
|
|
59833
59960
|
}
|
|
59834
|
-
var
|
|
59835
|
-
|
|
59836
|
-
|
|
59961
|
+
var isUserInAppTenant = (appId, user) => {
|
|
59962
|
+
let userTenantId;
|
|
59963
|
+
if (user) {
|
|
59964
|
+
userTenantId = user.tenantId || DEFAULT_TENANT_ID;
|
|
59965
|
+
} else {
|
|
59966
|
+
userTenantId = getTenantId();
|
|
59837
59967
|
}
|
|
59838
|
-
|
|
59839
|
-
|
|
59968
|
+
const tenantId = getTenantIDFromAppID(appId) || DEFAULT_TENANT_ID;
|
|
59969
|
+
return tenantId === userTenantId;
|
|
59970
|
+
};
|
|
59971
|
+
var ALL_STRATEGIES = Object.values(TenantResolutionStrategy);
|
|
59972
|
+
var getTenantIDFromCtx = (ctx, opts) => {
|
|
59973
|
+
if (!isMultiTenant()) {
|
|
59974
|
+
return DEFAULT_TENANT_ID;
|
|
59840
59975
|
}
|
|
59841
|
-
|
|
59842
|
-
|
|
59976
|
+
if (opts.allowNoTenant === void 0) {
|
|
59977
|
+
opts.allowNoTenant = false;
|
|
59843
59978
|
}
|
|
59844
|
-
|
|
59845
|
-
|
|
59979
|
+
if (!opts.includeStrategies) {
|
|
59980
|
+
opts.includeStrategies = ALL_STRATEGIES;
|
|
59846
59981
|
}
|
|
59847
|
-
|
|
59848
|
-
|
|
59849
|
-
|
|
59850
|
-
|
|
59851
|
-
|
|
59982
|
+
if (!opts.excludeStrategies) {
|
|
59983
|
+
opts.excludeStrategies = [];
|
|
59984
|
+
}
|
|
59985
|
+
const isAllowed = (strategy) => {
|
|
59986
|
+
if (opts.excludeStrategies?.includes(strategy)) {
|
|
59987
|
+
return false;
|
|
59852
59988
|
}
|
|
59853
|
-
if (
|
|
59854
|
-
return
|
|
59989
|
+
if (opts.includeStrategies?.includes(strategy)) {
|
|
59990
|
+
return true;
|
|
59991
|
+
}
|
|
59992
|
+
};
|
|
59993
|
+
if (isAllowed("user" /* USER */)) {
|
|
59994
|
+
const userTenantId = ctx.user?.tenantId;
|
|
59995
|
+
if (userTenantId) {
|
|
59996
|
+
return userTenantId;
|
|
59855
59997
|
}
|
|
59856
|
-
throw new Error(`could not parse value "${value}" as boolean`);
|
|
59857
59998
|
}
|
|
59858
|
-
|
|
59859
|
-
|
|
59860
|
-
|
|
59861
|
-
|
|
59862
|
-
return value;
|
|
59999
|
+
if (isAllowed("header" /* HEADER */)) {
|
|
60000
|
+
const headerTenantId = ctx.request.headers["x-budibase-tenant-id" /* TENANT_ID */];
|
|
60001
|
+
if (headerTenantId) {
|
|
60002
|
+
return headerTenantId;
|
|
59863
60003
|
}
|
|
59864
|
-
throw new Error(`could not parse value "${value}" as string`);
|
|
59865
60004
|
}
|
|
59866
|
-
|
|
59867
|
-
|
|
59868
|
-
|
|
59869
|
-
|
|
59870
|
-
return value;
|
|
60005
|
+
if (isAllowed("query" /* QUERY */)) {
|
|
60006
|
+
const queryTenantId = ctx.request.query.tenantId;
|
|
60007
|
+
if (queryTenantId) {
|
|
60008
|
+
return queryTenantId;
|
|
59871
60009
|
}
|
|
59872
|
-
|
|
59873
|
-
|
|
59874
|
-
|
|
59875
|
-
|
|
60010
|
+
}
|
|
60011
|
+
if (isAllowed("subdomain" /* SUBDOMAIN */)) {
|
|
60012
|
+
let platformHost;
|
|
60013
|
+
try {
|
|
60014
|
+
platformHost = new URL(getPlatformURL()).host.split(":")[0];
|
|
60015
|
+
} catch (err) {
|
|
60016
|
+
if (err.code !== "ERR_INVALID_URL") {
|
|
60017
|
+
throw err;
|
|
60018
|
+
}
|
|
60019
|
+
}
|
|
60020
|
+
const requestHost = ctx.host;
|
|
60021
|
+
if (platformHost && requestHost.includes(platformHost)) {
|
|
60022
|
+
const tenantId = requestHost.substring(
|
|
60023
|
+
0,
|
|
60024
|
+
requestHost.indexOf(`.${platformHost}`)
|
|
60025
|
+
);
|
|
60026
|
+
if (tenantId) {
|
|
60027
|
+
return tenantId;
|
|
59876
60028
|
}
|
|
59877
60029
|
}
|
|
59878
|
-
throw new Error(`could not parse value "${value}" as number`);
|
|
59879
|
-
}
|
|
59880
|
-
};
|
|
59881
|
-
var FlagSet = class {
|
|
59882
|
-
constructor(flagSchema) {
|
|
59883
|
-
this.flagSchema = flagSchema;
|
|
59884
|
-
this.setId = crypto.randomUUID();
|
|
59885
|
-
}
|
|
59886
|
-
defaults() {
|
|
59887
|
-
return Object.keys(this.flagSchema).reduce((acc, key) => {
|
|
59888
|
-
const typedKey = key;
|
|
59889
|
-
acc[typedKey] = this.flagSchema[key].defaultValue;
|
|
59890
|
-
return acc;
|
|
59891
|
-
}, {});
|
|
59892
60030
|
}
|
|
59893
|
-
|
|
59894
|
-
|
|
60031
|
+
if (isAllowed("path" /* PATH */)) {
|
|
60032
|
+
const match = ctx.matched.find(
|
|
60033
|
+
(m) => !!m.paramNames.find((p) => p.name === "tenantId")
|
|
60034
|
+
);
|
|
60035
|
+
const ctxUrl = ctx.originalUrl;
|
|
60036
|
+
let url;
|
|
60037
|
+
if (ctxUrl.includes("?")) {
|
|
60038
|
+
url = ctxUrl.split("?")[0];
|
|
60039
|
+
} else {
|
|
60040
|
+
url = ctxUrl;
|
|
60041
|
+
}
|
|
60042
|
+
if (match) {
|
|
60043
|
+
const params2 = match.params(url, match.captures(url), {});
|
|
60044
|
+
if (params2.tenantId) {
|
|
60045
|
+
return params2.tenantId;
|
|
60046
|
+
}
|
|
60047
|
+
}
|
|
59895
60048
|
}
|
|
59896
|
-
|
|
59897
|
-
|
|
59898
|
-
|
|
60049
|
+
if (!opts.allowNoTenant) {
|
|
60050
|
+
ctx.throw(403, "Tenant id not set");
|
|
60051
|
+
}
|
|
60052
|
+
return void 0;
|
|
60053
|
+
};
|
|
60054
|
+
|
|
60055
|
+
// src/utils/utils.ts
|
|
60056
|
+
var import_jsonwebtoken = __toESM(require("jsonwebtoken"));
|
|
60057
|
+
var APP_PREFIX3 = "app" /* APP */ + SEPARATOR;
|
|
60058
|
+
var PROD_APP_PREFIX = "/app/";
|
|
60059
|
+
var BUILDER_PREVIEW_PATH = "/app/preview";
|
|
60060
|
+
var BUILDER_PREFIX = "/builder";
|
|
60061
|
+
var BUILDER_APP_PREFIX = `${BUILDER_PREFIX}/app/`;
|
|
60062
|
+
var PUBLIC_API_PREFIX = "/api/public/v";
|
|
60063
|
+
function confirmAppId(possibleAppId) {
|
|
60064
|
+
return possibleAppId && possibleAppId.startsWith(APP_PREFIX3) ? possibleAppId : void 0;
|
|
60065
|
+
}
|
|
60066
|
+
async function resolveAppUrl(ctx) {
|
|
60067
|
+
const appUrl = ctx.path.split("/")[2];
|
|
60068
|
+
let possibleAppUrl = `/${appUrl.toLowerCase()}`;
|
|
60069
|
+
let tenantId = getTenantId();
|
|
60070
|
+
if (!environment_default.isDev() && environment_default.MULTI_TENANCY) {
|
|
60071
|
+
tenantId = getTenantIDFromCtx(ctx, {
|
|
60072
|
+
includeStrategies: ["subdomain" /* SUBDOMAIN */]
|
|
60073
|
+
});
|
|
60074
|
+
}
|
|
60075
|
+
const apps = await doInTenant(
|
|
60076
|
+
tenantId,
|
|
60077
|
+
() => getAllApps({ dev: false })
|
|
60078
|
+
);
|
|
60079
|
+
const app = apps.filter(
|
|
60080
|
+
(a) => a.url && a.url.toLowerCase() === possibleAppUrl
|
|
60081
|
+
)[0];
|
|
60082
|
+
return app && app.appId ? app.appId : void 0;
|
|
60083
|
+
}
|
|
60084
|
+
function isServingApp(ctx) {
|
|
60085
|
+
if (ctx.path.startsWith(`/${APP_PREFIX3}`)) {
|
|
60086
|
+
return true;
|
|
60087
|
+
}
|
|
60088
|
+
return ctx.path.startsWith(PROD_APP_PREFIX);
|
|
60089
|
+
}
|
|
60090
|
+
function isServingBuilder(ctx) {
|
|
60091
|
+
return ctx.path.startsWith(BUILDER_APP_PREFIX);
|
|
60092
|
+
}
|
|
60093
|
+
function isServingBuilderPreview(ctx) {
|
|
60094
|
+
return ctx.path.startsWith(BUILDER_PREVIEW_PATH);
|
|
60095
|
+
}
|
|
60096
|
+
function isPublicApiRequest(ctx) {
|
|
60097
|
+
return ctx.path.startsWith(PUBLIC_API_PREFIX);
|
|
60098
|
+
}
|
|
60099
|
+
async function getAppIdFromCtx(ctx) {
|
|
60100
|
+
const options2 = [ctx.request.headers["x-budibase-app-id" /* APP_ID */]];
|
|
60101
|
+
let appId;
|
|
60102
|
+
for (let option of options2) {
|
|
60103
|
+
appId = confirmAppId(option);
|
|
60104
|
+
if (appId) {
|
|
60105
|
+
break;
|
|
60106
|
+
}
|
|
60107
|
+
}
|
|
60108
|
+
if (!appId && ctx.request.body && ctx.request.body.appId) {
|
|
60109
|
+
appId = confirmAppId(ctx.request.body.appId);
|
|
60110
|
+
}
|
|
60111
|
+
const pathId = parseAppIdFromUrlPath(ctx.path);
|
|
60112
|
+
if (!appId && pathId) {
|
|
60113
|
+
appId = confirmAppId(pathId);
|
|
60114
|
+
}
|
|
60115
|
+
const isBuilderPreview = ctx.path.startsWith(BUILDER_PREVIEW_PATH);
|
|
60116
|
+
const isViewingProdApp = ctx.path.startsWith(PROD_APP_PREFIX) && !isBuilderPreview;
|
|
60117
|
+
if (!appId && isViewingProdApp) {
|
|
60118
|
+
appId = confirmAppId(await resolveAppUrl(ctx));
|
|
60119
|
+
}
|
|
60120
|
+
const referer = ctx.request.headers.referer;
|
|
60121
|
+
if (!appId && referer?.includes(BUILDER_APP_PREFIX)) {
|
|
60122
|
+
const refererId = parseAppIdFromUrlPath(ctx.request.headers.referer);
|
|
60123
|
+
appId = confirmAppId(refererId);
|
|
60124
|
+
}
|
|
60125
|
+
return appId;
|
|
60126
|
+
}
|
|
60127
|
+
function parseAppIdFromUrlPath(url) {
|
|
60128
|
+
if (!url) {
|
|
60129
|
+
return;
|
|
60130
|
+
}
|
|
60131
|
+
return url.split("?")[0].split("/").find((subPath) => subPath.startsWith(APP_PREFIX3));
|
|
60132
|
+
}
|
|
60133
|
+
function openJwt(token) {
|
|
60134
|
+
if (!token) {
|
|
60135
|
+
return void 0;
|
|
60136
|
+
}
|
|
60137
|
+
try {
|
|
60138
|
+
return import_jsonwebtoken.default.verify(token, environment_default.JWT_SECRET);
|
|
60139
|
+
} catch (e) {
|
|
60140
|
+
if (environment_default.JWT_SECRET_FALLBACK) {
|
|
60141
|
+
return import_jsonwebtoken.default.verify(token, environment_default.JWT_SECRET_FALLBACK);
|
|
60142
|
+
} else {
|
|
60143
|
+
throw e;
|
|
60144
|
+
}
|
|
60145
|
+
}
|
|
60146
|
+
}
|
|
60147
|
+
function isValidInternalAPIKey(apiKey) {
|
|
60148
|
+
if (environment_default.INTERNAL_API_KEY && environment_default.INTERNAL_API_KEY === apiKey) {
|
|
60149
|
+
return true;
|
|
60150
|
+
}
|
|
60151
|
+
return !!(environment_default.INTERNAL_API_KEY_FALLBACK && environment_default.INTERNAL_API_KEY_FALLBACK === apiKey);
|
|
60152
|
+
}
|
|
60153
|
+
function getCookie(ctx, name) {
|
|
60154
|
+
const cookie = ctx.cookies.get(name);
|
|
60155
|
+
if (!cookie) {
|
|
60156
|
+
return void 0;
|
|
60157
|
+
}
|
|
60158
|
+
return openJwt(cookie);
|
|
60159
|
+
}
|
|
60160
|
+
function setCookie(ctx, value, name = "builder", opts = { sign: true }) {
|
|
60161
|
+
if (value && opts && opts.sign) {
|
|
60162
|
+
value = import_jsonwebtoken.default.sign(value, environment_default.JWT_SECRET);
|
|
60163
|
+
}
|
|
60164
|
+
const config = {
|
|
60165
|
+
expires: MAX_VALID_DATE,
|
|
60166
|
+
path: "/",
|
|
60167
|
+
httpOnly: false,
|
|
60168
|
+
overwrite: true
|
|
60169
|
+
};
|
|
60170
|
+
if (environment_default.COOKIE_DOMAIN) {
|
|
60171
|
+
config.domain = environment_default.COOKIE_DOMAIN;
|
|
60172
|
+
}
|
|
60173
|
+
ctx.cookies.set(name, value, config);
|
|
60174
|
+
}
|
|
60175
|
+
function clearCookie(ctx, name) {
|
|
60176
|
+
setCookie(ctx, null, name);
|
|
60177
|
+
}
|
|
60178
|
+
function isClient(ctx) {
|
|
60179
|
+
return ctx.headers["x-budibase-type" /* TYPE */] === "client";
|
|
60180
|
+
}
|
|
60181
|
+
function timeout(timeMs) {
|
|
60182
|
+
return new Promise((resolve) => setTimeout(resolve, timeMs));
|
|
60183
|
+
}
|
|
60184
|
+
function isAudited(event) {
|
|
60185
|
+
return !!AuditedEventFriendlyName[event];
|
|
60186
|
+
}
|
|
60187
|
+
function hasCircularStructure(json) {
|
|
60188
|
+
if (typeof json !== "object") {
|
|
60189
|
+
return false;
|
|
60190
|
+
}
|
|
60191
|
+
try {
|
|
60192
|
+
JSON.stringify(json);
|
|
60193
|
+
} catch (err) {
|
|
60194
|
+
if (err instanceof Error && err?.message.includes("circular structure")) {
|
|
60195
|
+
return true;
|
|
60196
|
+
}
|
|
60197
|
+
}
|
|
60198
|
+
return false;
|
|
60199
|
+
}
|
|
60200
|
+
|
|
60201
|
+
// src/utils/stringUtils.ts
|
|
60202
|
+
function validEmail(value) {
|
|
60203
|
+
return value && !!value.match(
|
|
60204
|
+
/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
|
|
60205
|
+
);
|
|
60206
|
+
}
|
|
60207
|
+
|
|
60208
|
+
// src/utils/Duration.ts
|
|
60209
|
+
var DurationType = /* @__PURE__ */ ((DurationType2) => {
|
|
60210
|
+
DurationType2["MILLISECONDS"] = "milliseconds";
|
|
60211
|
+
DurationType2["SECONDS"] = "seconds";
|
|
60212
|
+
DurationType2["MINUTES"] = "minutes";
|
|
60213
|
+
DurationType2["HOURS"] = "hours";
|
|
60214
|
+
DurationType2["DAYS"] = "days";
|
|
60215
|
+
return DurationType2;
|
|
60216
|
+
})(DurationType || {});
|
|
60217
|
+
var conversion = {
|
|
60218
|
+
milliseconds: 1,
|
|
60219
|
+
seconds: 1e3,
|
|
60220
|
+
minutes: 60 * 1e3,
|
|
60221
|
+
hours: 60 * 60 * 1e3,
|
|
60222
|
+
days: 24 * 60 * 60 * 1e3
|
|
60223
|
+
};
|
|
60224
|
+
var Duration = class _Duration {
|
|
60225
|
+
static convert(from, to, duration) {
|
|
60226
|
+
const milliseconds = duration * conversion[from];
|
|
60227
|
+
return milliseconds / conversion[to];
|
|
60228
|
+
}
|
|
60229
|
+
static from(from, duration) {
|
|
60230
|
+
return {
|
|
60231
|
+
to: (to) => {
|
|
60232
|
+
return _Duration.convert(from, to, duration);
|
|
60233
|
+
},
|
|
60234
|
+
toMs: () => {
|
|
60235
|
+
return _Duration.convert(from, "milliseconds" /* MILLISECONDS */, duration);
|
|
60236
|
+
},
|
|
60237
|
+
toSeconds: () => {
|
|
60238
|
+
return _Duration.convert(from, "seconds" /* SECONDS */, duration);
|
|
60239
|
+
}
|
|
60240
|
+
};
|
|
60241
|
+
}
|
|
60242
|
+
static fromSeconds(duration) {
|
|
60243
|
+
return _Duration.from("seconds" /* SECONDS */, duration);
|
|
60244
|
+
}
|
|
60245
|
+
static fromMinutes(duration) {
|
|
60246
|
+
return _Duration.from("minutes" /* MINUTES */, duration);
|
|
60247
|
+
}
|
|
60248
|
+
static fromHours(duration) {
|
|
60249
|
+
return _Duration.from("hours" /* HOURS */, duration);
|
|
60250
|
+
}
|
|
60251
|
+
static fromDays(duration) {
|
|
60252
|
+
return _Duration.from("days" /* DAYS */, duration);
|
|
60253
|
+
}
|
|
60254
|
+
static fromMilliseconds(duration) {
|
|
60255
|
+
return _Duration.from("milliseconds" /* MILLISECONDS */, duration);
|
|
60256
|
+
}
|
|
60257
|
+
};
|
|
60258
|
+
|
|
60259
|
+
// src/features/index.ts
|
|
60260
|
+
var posthog;
|
|
60261
|
+
function init4(opts) {
|
|
60262
|
+
if (environment_default.POSTHOG_TOKEN && environment_default.POSTHOG_API_HOST && !environment_default.SELF_HOSTED && environment_default.POSTHOG_FEATURE_FLAGS_ENABLED) {
|
|
60263
|
+
console.log("initializing posthog client...");
|
|
60264
|
+
posthog = new import_posthog_node.PostHog(environment_default.POSTHOG_TOKEN, {
|
|
60265
|
+
host: environment_default.POSTHOG_API_HOST,
|
|
60266
|
+
personalApiKey: environment_default.POSTHOG_PERSONAL_TOKEN,
|
|
60267
|
+
featureFlagsPollingInterval: Duration.fromMinutes(3).toMs(),
|
|
60268
|
+
...opts
|
|
60269
|
+
});
|
|
60270
|
+
} else {
|
|
60271
|
+
console.log("posthog disabled");
|
|
60272
|
+
}
|
|
60273
|
+
}
|
|
60274
|
+
function shutdown2() {
|
|
60275
|
+
posthog?.shutdown();
|
|
60276
|
+
}
|
|
60277
|
+
var Flag = class {
|
|
60278
|
+
constructor(defaultValue) {
|
|
60279
|
+
this.defaultValue = defaultValue;
|
|
60280
|
+
}
|
|
60281
|
+
static boolean(defaultValue) {
|
|
60282
|
+
return new BooleanFlag(defaultValue);
|
|
60283
|
+
}
|
|
60284
|
+
static string(defaultValue) {
|
|
60285
|
+
return new StringFlag(defaultValue);
|
|
60286
|
+
}
|
|
60287
|
+
static number(defaultValue) {
|
|
60288
|
+
return new NumberFlag(defaultValue);
|
|
60289
|
+
}
|
|
60290
|
+
};
|
|
60291
|
+
var BooleanFlag = class extends Flag {
|
|
60292
|
+
parse(value) {
|
|
60293
|
+
if (typeof value === "string") {
|
|
60294
|
+
return ["true", "t", "1"].includes(value.toLowerCase());
|
|
60295
|
+
}
|
|
60296
|
+
if (typeof value === "boolean") {
|
|
60297
|
+
return value;
|
|
60298
|
+
}
|
|
60299
|
+
throw new Error(`could not parse value "${value}" as boolean`);
|
|
60300
|
+
}
|
|
60301
|
+
};
|
|
60302
|
+
var StringFlag = class extends Flag {
|
|
60303
|
+
parse(value) {
|
|
60304
|
+
if (typeof value === "string") {
|
|
60305
|
+
return value;
|
|
60306
|
+
}
|
|
60307
|
+
throw new Error(`could not parse value "${value}" as string`);
|
|
60308
|
+
}
|
|
60309
|
+
};
|
|
60310
|
+
var NumberFlag = class extends Flag {
|
|
60311
|
+
parse(value) {
|
|
60312
|
+
if (typeof value === "number") {
|
|
60313
|
+
return value;
|
|
60314
|
+
}
|
|
60315
|
+
if (typeof value === "string") {
|
|
60316
|
+
const parsed = parseFloat(value);
|
|
60317
|
+
if (!isNaN(parsed)) {
|
|
60318
|
+
return parsed;
|
|
60319
|
+
}
|
|
60320
|
+
}
|
|
60321
|
+
throw new Error(`could not parse value "${value}" as number`);
|
|
60322
|
+
}
|
|
60323
|
+
};
|
|
60324
|
+
var FlagSet = class {
|
|
60325
|
+
constructor(flagSchema) {
|
|
60326
|
+
this.flagSchema = flagSchema;
|
|
60327
|
+
this.setId = crypto.randomUUID();
|
|
60328
|
+
}
|
|
60329
|
+
defaults() {
|
|
60330
|
+
return Object.keys(this.flagSchema).reduce((acc, key) => {
|
|
60331
|
+
const typedKey = key;
|
|
60332
|
+
acc[typedKey] = this.flagSchema[key].defaultValue;
|
|
60333
|
+
return acc;
|
|
60334
|
+
}, {});
|
|
60335
|
+
}
|
|
60336
|
+
isFlagName(name) {
|
|
60337
|
+
return this.flagSchema[name] !== void 0;
|
|
60338
|
+
}
|
|
60339
|
+
async get(key, ctx) {
|
|
60340
|
+
const flags2 = await this.fetch(ctx);
|
|
60341
|
+
return flags2[key];
|
|
59899
60342
|
}
|
|
59900
60343
|
async isEnabled(key, ctx) {
|
|
59901
60344
|
const flags2 = await this.fetch(ctx);
|
|
@@ -59997,7 +60440,7 @@ var flags = new FlagSet({
|
|
|
59997
60440
|
AUTOMATION_BRANCHING: Flag.boolean(environment_default.isDev()),
|
|
59998
60441
|
SQS: Flag.boolean(environment_default.isDev()),
|
|
59999
60442
|
["AI_CUSTOM_CONFIGS" /* AI_CUSTOM_CONFIGS */]: Flag.boolean(environment_default.isDev()),
|
|
60000
|
-
["ENRICHED_RELATIONSHIPS" /* ENRICHED_RELATIONSHIPS */]: Flag.boolean(
|
|
60443
|
+
["ENRICHED_RELATIONSHIPS" /* ENRICHED_RELATIONSHIPS */]: Flag.boolean(environment_default.isDev())
|
|
60001
60444
|
});
|
|
60002
60445
|
|
|
60003
60446
|
// src/db/couch/DatabaseImpl.ts
|
|
@@ -60098,7 +60541,7 @@ var DatabaseImpl = class _DatabaseImpl {
|
|
|
60098
60541
|
return this.getDb();
|
|
60099
60542
|
}
|
|
60100
60543
|
// this function fetches the DB and handles if DB creation is needed
|
|
60101
|
-
async
|
|
60544
|
+
async performCallWithDBCreation(call) {
|
|
60102
60545
|
const db = this.getDb();
|
|
60103
60546
|
const fnc = await call(db);
|
|
60104
60547
|
try {
|
|
@@ -60106,11 +60549,20 @@ var DatabaseImpl = class _DatabaseImpl {
|
|
|
60106
60549
|
} catch (err) {
|
|
60107
60550
|
if (err.statusCode === 404 && err.reason === DATABASE_NOT_FOUND) {
|
|
60108
60551
|
await this.checkAndCreateDb();
|
|
60109
|
-
return await this.
|
|
60552
|
+
return await this.performCallWithDBCreation(call);
|
|
60110
60553
|
}
|
|
60111
60554
|
throw new CouchDBError(`CouchDB error: ${err.message}`, err);
|
|
60112
60555
|
}
|
|
60113
60556
|
}
|
|
60557
|
+
async performCall(call) {
|
|
60558
|
+
const db = this.getDb();
|
|
60559
|
+
const fnc = await call(db);
|
|
60560
|
+
try {
|
|
60561
|
+
return await fnc();
|
|
60562
|
+
} catch (err) {
|
|
60563
|
+
throw new CouchDBError(`CouchDB error: ${err.message}`, err);
|
|
60564
|
+
}
|
|
60565
|
+
}
|
|
60114
60566
|
async get(id) {
|
|
60115
60567
|
return this.performCall((db) => {
|
|
60116
60568
|
if (!id) {
|
|
@@ -60194,7 +60646,7 @@ var DatabaseImpl = class _DatabaseImpl {
|
|
|
60194
60646
|
if (!document._id) {
|
|
60195
60647
|
throw new Error("Cannot store document without _id field.");
|
|
60196
60648
|
}
|
|
60197
|
-
return this.
|
|
60649
|
+
return this.performCallWithDBCreation(async (db) => {
|
|
60198
60650
|
if (!document.createdAt) {
|
|
60199
60651
|
document.createdAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
60200
60652
|
}
|
|
@@ -60216,7 +60668,7 @@ var DatabaseImpl = class _DatabaseImpl {
|
|
|
60216
60668
|
}
|
|
60217
60669
|
async bulkDocs(documents) {
|
|
60218
60670
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
60219
|
-
return this.
|
|
60671
|
+
return this.performCallWithDBCreation((db) => {
|
|
60220
60672
|
return () => db.bulk({
|
|
60221
60673
|
docs: documents.map((d) => ({ createdAt: now, ...d, updatedAt: now }))
|
|
60222
60674
|
});
|
|
@@ -60224,7 +60676,21 @@ var DatabaseImpl = class _DatabaseImpl {
|
|
|
60224
60676
|
}
|
|
60225
60677
|
async allDocs(params2) {
|
|
60226
60678
|
return this.performCall((db) => {
|
|
60227
|
-
return () =>
|
|
60679
|
+
return async () => {
|
|
60680
|
+
try {
|
|
60681
|
+
return await db.list(params2);
|
|
60682
|
+
} catch (err) {
|
|
60683
|
+
if (err.reason === DATABASE_NOT_FOUND) {
|
|
60684
|
+
return {
|
|
60685
|
+
offset: 0,
|
|
60686
|
+
total_rows: 0,
|
|
60687
|
+
rows: []
|
|
60688
|
+
};
|
|
60689
|
+
} else {
|
|
60690
|
+
throw err;
|
|
60691
|
+
}
|
|
60692
|
+
}
|
|
60693
|
+
};
|
|
60228
60694
|
});
|
|
60229
60695
|
}
|
|
60230
60696
|
async _sqlQuery(url, method, body2) {
|
|
@@ -60638,6 +61104,21 @@ function setFeatureFlags(key, value) {
|
|
|
60638
61104
|
context.featureFlagCache ??= {};
|
|
60639
61105
|
context.featureFlagCache[key] = value;
|
|
60640
61106
|
}
|
|
61107
|
+
function getTableForView(viewId) {
|
|
61108
|
+
const context = getCurrentContext();
|
|
61109
|
+
if (!context) {
|
|
61110
|
+
return;
|
|
61111
|
+
}
|
|
61112
|
+
return context.viewToTableCache?.[viewId];
|
|
61113
|
+
}
|
|
61114
|
+
function setTableForView(viewId, table) {
|
|
61115
|
+
const context = getCurrentContext();
|
|
61116
|
+
if (!context) {
|
|
61117
|
+
return;
|
|
61118
|
+
}
|
|
61119
|
+
context.viewToTableCache ??= {};
|
|
61120
|
+
context.viewToTableCache[viewId] = table;
|
|
61121
|
+
}
|
|
60641
61122
|
|
|
60642
61123
|
// src/cache/base/index.ts
|
|
60643
61124
|
function generateTenantKey(key) {
|
|
@@ -60720,209 +61201,73 @@ var BaseCache = class {
|
|
|
60720
61201
|
}
|
|
60721
61202
|
/**
|
|
60722
61203
|
* Read from the cache. Write to the cache if not exists.
|
|
60723
|
-
*/
|
|
60724
|
-
async withCache(key, ttl = null, fetchFn, opts = { useTenancy: true }) {
|
|
60725
|
-
const cachedValue = await this.get(key, opts);
|
|
60726
|
-
if (cachedValue) {
|
|
60727
|
-
return cachedValue;
|
|
60728
|
-
}
|
|
60729
|
-
try {
|
|
60730
|
-
const fetchedValue = await fetchFn();
|
|
60731
|
-
await this.store(key, fetchedValue, ttl, opts);
|
|
60732
|
-
return fetchedValue;
|
|
60733
|
-
} catch (err) {
|
|
60734
|
-
console.error("Error fetching before cache - ", err);
|
|
60735
|
-
throw err;
|
|
60736
|
-
}
|
|
60737
|
-
}
|
|
60738
|
-
async bustCache(key) {
|
|
60739
|
-
const client = await this.getClient();
|
|
60740
|
-
try {
|
|
60741
|
-
await client.delete(generateTenantKey(key));
|
|
60742
|
-
} catch (err) {
|
|
60743
|
-
console.error("Error busting cache - ", err);
|
|
60744
|
-
throw err;
|
|
60745
|
-
}
|
|
60746
|
-
}
|
|
60747
|
-
/**
|
|
60748
|
-
* Delete the entry if the provided value matches the stored one.
|
|
60749
|
-
*/
|
|
60750
|
-
async deleteIfValue(key, value, opts = { useTenancy: true }) {
|
|
60751
|
-
key = opts.useTenancy ? generateTenantKey(key) : key;
|
|
60752
|
-
const client = await this.getClient();
|
|
60753
|
-
await client.deleteIfValue(key, value);
|
|
60754
|
-
}
|
|
60755
|
-
};
|
|
60756
|
-
|
|
60757
|
-
// src/cache/generic.ts
|
|
60758
|
-
var GENERIC = new BaseCache();
|
|
60759
|
-
var CacheKey = /* @__PURE__ */ ((CacheKey2) => {
|
|
60760
|
-
CacheKey2["CHECKLIST"] = "checklist";
|
|
60761
|
-
CacheKey2["INSTALLATION"] = "installation";
|
|
60762
|
-
CacheKey2["ANALYTICS_ENABLED"] = "analyticsEnabled";
|
|
60763
|
-
CacheKey2["UNIQUE_TENANT_ID"] = "uniqueTenantId";
|
|
60764
|
-
CacheKey2["EVENTS"] = "events";
|
|
60765
|
-
CacheKey2["BACKFILL_METADATA"] = "backfillMetadata";
|
|
60766
|
-
CacheKey2["EVENTS_RATE_LIMIT"] = "eventsRateLimit";
|
|
60767
|
-
return CacheKey2;
|
|
60768
|
-
})(CacheKey || {});
|
|
60769
|
-
var TTL = /* @__PURE__ */ ((TTL2) => {
|
|
60770
|
-
TTL2[TTL2["ONE_MINUTE"] = 600] = "ONE_MINUTE";
|
|
60771
|
-
TTL2[TTL2["ONE_HOUR"] = 3600] = "ONE_HOUR";
|
|
60772
|
-
TTL2[TTL2["ONE_DAY"] = 86400] = "ONE_DAY";
|
|
60773
|
-
return TTL2;
|
|
60774
|
-
})(TTL || {});
|
|
60775
|
-
var keys = (...args) => GENERIC.keys(...args);
|
|
60776
|
-
var get2 = (...args) => GENERIC.get(...args);
|
|
60777
|
-
var store = (...args) => GENERIC.store(...args);
|
|
60778
|
-
var destroy = (...args) => GENERIC.delete(...args);
|
|
60779
|
-
var withCache = (...args) => GENERIC.withCache(...args);
|
|
60780
|
-
var bustCache = (...args) => GENERIC.bustCache(...args);
|
|
60781
|
-
|
|
60782
|
-
// src/cache/user.ts
|
|
60783
|
-
var user_exports = {};
|
|
60784
|
-
__export(user_exports, {
|
|
60785
|
-
getUser: () => getUser,
|
|
60786
|
-
getUsers: () => getUsers,
|
|
60787
|
-
invalidateUser: () => invalidateUser
|
|
60788
|
-
});
|
|
60789
|
-
|
|
60790
|
-
// src/tenancy/index.ts
|
|
60791
|
-
var tenancy_exports = {};
|
|
60792
|
-
__export(tenancy_exports, {
|
|
60793
|
-
addTenantToUrl: () => addTenantToUrl,
|
|
60794
|
-
getTenantDB: () => getTenantDB,
|
|
60795
|
-
getTenantIDFromCtx: () => getTenantIDFromCtx,
|
|
60796
|
-
getTenantInfo: () => getTenantInfo,
|
|
60797
|
-
isUserInAppTenant: () => isUserInAppTenant,
|
|
60798
|
-
saveTenantInfo: () => saveTenantInfo
|
|
60799
|
-
});
|
|
60800
|
-
|
|
60801
|
-
// src/tenancy/db.ts
|
|
60802
|
-
function getTenantDB(tenantId) {
|
|
60803
|
-
return getDB(getGlobalDBName(tenantId));
|
|
60804
|
-
}
|
|
60805
|
-
async function saveTenantInfo(tenantInfo) {
|
|
60806
|
-
const db = getTenantDB(tenantInfo.tenantId);
|
|
60807
|
-
return db.put({
|
|
60808
|
-
_id: "tenant_info",
|
|
60809
|
-
...tenantInfo
|
|
60810
|
-
});
|
|
60811
|
-
}
|
|
60812
|
-
async function getTenantInfo(tenantId) {
|
|
60813
|
-
try {
|
|
60814
|
-
const db = getTenantDB(tenantId);
|
|
60815
|
-
const tenantInfo = await db.get("tenant_info");
|
|
60816
|
-
delete tenantInfo.owner.password;
|
|
60817
|
-
return tenantInfo;
|
|
60818
|
-
} catch {
|
|
60819
|
-
return void 0;
|
|
60820
|
-
}
|
|
60821
|
-
}
|
|
60822
|
-
|
|
60823
|
-
// src/tenancy/tenancy.ts
|
|
60824
|
-
function addTenantToUrl(url) {
|
|
60825
|
-
const tenantId = getTenantId();
|
|
60826
|
-
if (isMultiTenant()) {
|
|
60827
|
-
const char = url.indexOf("?") === -1 ? "?" : "&";
|
|
60828
|
-
url += `${char}tenantId=${tenantId}`;
|
|
60829
|
-
}
|
|
60830
|
-
return url;
|
|
60831
|
-
}
|
|
60832
|
-
var isUserInAppTenant = (appId, user) => {
|
|
60833
|
-
let userTenantId;
|
|
60834
|
-
if (user) {
|
|
60835
|
-
userTenantId = user.tenantId || DEFAULT_TENANT_ID;
|
|
60836
|
-
} else {
|
|
60837
|
-
userTenantId = getTenantId();
|
|
60838
|
-
}
|
|
60839
|
-
const tenantId = getTenantIDFromAppID(appId) || DEFAULT_TENANT_ID;
|
|
60840
|
-
return tenantId === userTenantId;
|
|
60841
|
-
};
|
|
60842
|
-
var ALL_STRATEGIES = Object.values(TenantResolutionStrategy);
|
|
60843
|
-
var getTenantIDFromCtx = (ctx, opts) => {
|
|
60844
|
-
if (!isMultiTenant()) {
|
|
60845
|
-
return DEFAULT_TENANT_ID;
|
|
60846
|
-
}
|
|
60847
|
-
if (opts.allowNoTenant === void 0) {
|
|
60848
|
-
opts.allowNoTenant = false;
|
|
60849
|
-
}
|
|
60850
|
-
if (!opts.includeStrategies) {
|
|
60851
|
-
opts.includeStrategies = ALL_STRATEGIES;
|
|
60852
|
-
}
|
|
60853
|
-
if (!opts.excludeStrategies) {
|
|
60854
|
-
opts.excludeStrategies = [];
|
|
60855
|
-
}
|
|
60856
|
-
const isAllowed = (strategy) => {
|
|
60857
|
-
if (opts.excludeStrategies?.includes(strategy)) {
|
|
60858
|
-
return false;
|
|
60859
|
-
}
|
|
60860
|
-
if (opts.includeStrategies?.includes(strategy)) {
|
|
60861
|
-
return true;
|
|
60862
|
-
}
|
|
60863
|
-
};
|
|
60864
|
-
if (isAllowed("user" /* USER */)) {
|
|
60865
|
-
const userTenantId = ctx.user?.tenantId;
|
|
60866
|
-
if (userTenantId) {
|
|
60867
|
-
return userTenantId;
|
|
60868
|
-
}
|
|
60869
|
-
}
|
|
60870
|
-
if (isAllowed("header" /* HEADER */)) {
|
|
60871
|
-
const headerTenantId = ctx.request.headers["x-budibase-tenant-id" /* TENANT_ID */];
|
|
60872
|
-
if (headerTenantId) {
|
|
60873
|
-
return headerTenantId;
|
|
60874
|
-
}
|
|
60875
|
-
}
|
|
60876
|
-
if (isAllowed("query" /* QUERY */)) {
|
|
60877
|
-
const queryTenantId = ctx.request.query.tenantId;
|
|
60878
|
-
if (queryTenantId) {
|
|
60879
|
-
return queryTenantId;
|
|
61204
|
+
*/
|
|
61205
|
+
async withCache(key, ttl = null, fetchFn, opts = { useTenancy: true }) {
|
|
61206
|
+
const cachedValue = await this.get(key, opts);
|
|
61207
|
+
if (cachedValue) {
|
|
61208
|
+
return cachedValue;
|
|
60880
61209
|
}
|
|
60881
|
-
}
|
|
60882
|
-
if (isAllowed("subdomain" /* SUBDOMAIN */)) {
|
|
60883
|
-
let platformHost;
|
|
60884
61210
|
try {
|
|
60885
|
-
|
|
61211
|
+
const fetchedValue = await fetchFn();
|
|
61212
|
+
await this.store(key, fetchedValue, ttl, opts);
|
|
61213
|
+
return fetchedValue;
|
|
60886
61214
|
} catch (err) {
|
|
60887
|
-
|
|
60888
|
-
|
|
60889
|
-
}
|
|
60890
|
-
}
|
|
60891
|
-
const requestHost = ctx.host;
|
|
60892
|
-
if (platformHost && requestHost.includes(platformHost)) {
|
|
60893
|
-
const tenantId = requestHost.substring(
|
|
60894
|
-
0,
|
|
60895
|
-
requestHost.indexOf(`.${platformHost}`)
|
|
60896
|
-
);
|
|
60897
|
-
if (tenantId) {
|
|
60898
|
-
return tenantId;
|
|
60899
|
-
}
|
|
61215
|
+
console.error("Error fetching before cache - ", err);
|
|
61216
|
+
throw err;
|
|
60900
61217
|
}
|
|
60901
61218
|
}
|
|
60902
|
-
|
|
60903
|
-
const
|
|
60904
|
-
|
|
60905
|
-
|
|
60906
|
-
|
|
60907
|
-
|
|
60908
|
-
|
|
60909
|
-
url = ctxUrl.split("?")[0];
|
|
60910
|
-
} else {
|
|
60911
|
-
url = ctxUrl;
|
|
60912
|
-
}
|
|
60913
|
-
if (match) {
|
|
60914
|
-
const params2 = match.params(url, match.captures(url), {});
|
|
60915
|
-
if (params2.tenantId) {
|
|
60916
|
-
return params2.tenantId;
|
|
60917
|
-
}
|
|
61219
|
+
async bustCache(key) {
|
|
61220
|
+
const client = await this.getClient();
|
|
61221
|
+
try {
|
|
61222
|
+
await client.delete(generateTenantKey(key));
|
|
61223
|
+
} catch (err) {
|
|
61224
|
+
console.error("Error busting cache - ", err);
|
|
61225
|
+
throw err;
|
|
60918
61226
|
}
|
|
60919
61227
|
}
|
|
60920
|
-
|
|
60921
|
-
|
|
61228
|
+
/**
|
|
61229
|
+
* Delete the entry if the provided value matches the stored one.
|
|
61230
|
+
*/
|
|
61231
|
+
async deleteIfValue(key, value, opts = { useTenancy: true }) {
|
|
61232
|
+
key = opts.useTenancy ? generateTenantKey(key) : key;
|
|
61233
|
+
const client = await this.getClient();
|
|
61234
|
+
await client.deleteIfValue(key, value);
|
|
60922
61235
|
}
|
|
60923
|
-
return void 0;
|
|
60924
61236
|
};
|
|
60925
61237
|
|
|
61238
|
+
// src/cache/generic.ts
|
|
61239
|
+
var GENERIC = new BaseCache();
|
|
61240
|
+
var CacheKey = /* @__PURE__ */ ((CacheKey2) => {
|
|
61241
|
+
CacheKey2["CHECKLIST"] = "checklist";
|
|
61242
|
+
CacheKey2["INSTALLATION"] = "installation";
|
|
61243
|
+
CacheKey2["ANALYTICS_ENABLED"] = "analyticsEnabled";
|
|
61244
|
+
CacheKey2["UNIQUE_TENANT_ID"] = "uniqueTenantId";
|
|
61245
|
+
CacheKey2["EVENTS"] = "events";
|
|
61246
|
+
CacheKey2["BACKFILL_METADATA"] = "backfillMetadata";
|
|
61247
|
+
CacheKey2["EVENTS_RATE_LIMIT"] = "eventsRateLimit";
|
|
61248
|
+
return CacheKey2;
|
|
61249
|
+
})(CacheKey || {});
|
|
61250
|
+
var TTL = /* @__PURE__ */ ((TTL2) => {
|
|
61251
|
+
TTL2[TTL2["ONE_MINUTE"] = 600] = "ONE_MINUTE";
|
|
61252
|
+
TTL2[TTL2["ONE_HOUR"] = 3600] = "ONE_HOUR";
|
|
61253
|
+
TTL2[TTL2["ONE_DAY"] = 86400] = "ONE_DAY";
|
|
61254
|
+
return TTL2;
|
|
61255
|
+
})(TTL || {});
|
|
61256
|
+
var keys = (...args) => GENERIC.keys(...args);
|
|
61257
|
+
var get2 = (...args) => GENERIC.get(...args);
|
|
61258
|
+
var store = (...args) => GENERIC.store(...args);
|
|
61259
|
+
var destroy = (...args) => GENERIC.delete(...args);
|
|
61260
|
+
var withCache = (...args) => GENERIC.withCache(...args);
|
|
61261
|
+
var bustCache = (...args) => GENERIC.bustCache(...args);
|
|
61262
|
+
|
|
61263
|
+
// src/cache/user.ts
|
|
61264
|
+
var user_exports = {};
|
|
61265
|
+
__export(user_exports, {
|
|
61266
|
+
getUser: () => getUser,
|
|
61267
|
+
getUsers: () => getUsers,
|
|
61268
|
+
invalidateUser: () => invalidateUser
|
|
61269
|
+
});
|
|
61270
|
+
|
|
60926
61271
|
// src/platform/index.ts
|
|
60927
61272
|
var platform_exports = {};
|
|
60928
61273
|
__export(platform_exports, {
|
|
@@ -60955,339 +61300,96 @@ async function lookupTenantId(userId) {
|
|
|
60955
61300
|
const user = await getUserDoc(userId);
|
|
60956
61301
|
return user.tenantId;
|
|
60957
61302
|
}
|
|
60958
|
-
async function getUserDoc(emailOrId) {
|
|
60959
|
-
const db = getPlatformDB();
|
|
60960
|
-
return db.get(emailOrId);
|
|
60961
|
-
}
|
|
60962
|
-
async function updateUserDoc(platformUser) {
|
|
60963
|
-
const db = getPlatformDB();
|
|
60964
|
-
await db.put(platformUser);
|
|
60965
|
-
}
|
|
60966
|
-
function newUserIdDoc(id, tenantId) {
|
|
60967
|
-
return {
|
|
60968
|
-
_id: id,
|
|
60969
|
-
tenantId
|
|
60970
|
-
};
|
|
60971
|
-
}
|
|
60972
|
-
function newUserEmailDoc(userId, email, tenantId) {
|
|
60973
|
-
return {
|
|
60974
|
-
_id: email,
|
|
60975
|
-
userId,
|
|
60976
|
-
tenantId
|
|
60977
|
-
};
|
|
60978
|
-
}
|
|
60979
|
-
function newUserSsoIdDoc(ssoId, email, userId, tenantId) {
|
|
60980
|
-
return {
|
|
60981
|
-
_id: ssoId,
|
|
60982
|
-
userId,
|
|
60983
|
-
email,
|
|
60984
|
-
tenantId
|
|
60985
|
-
};
|
|
60986
|
-
}
|
|
60987
|
-
async function addUserDoc(emailOrId, newDocFn) {
|
|
60988
|
-
const db = getPlatformDB();
|
|
60989
|
-
let user;
|
|
60990
|
-
try {
|
|
60991
|
-
await db.get(emailOrId);
|
|
60992
|
-
} catch (e) {
|
|
60993
|
-
if (e.status === 404) {
|
|
60994
|
-
user = newDocFn();
|
|
60995
|
-
await db.put(user);
|
|
60996
|
-
} else {
|
|
60997
|
-
throw e;
|
|
60998
|
-
}
|
|
60999
|
-
}
|
|
61000
|
-
}
|
|
61001
|
-
async function addSsoUser(ssoId, email, userId, tenantId) {
|
|
61002
|
-
return addUserDoc(
|
|
61003
|
-
ssoId,
|
|
61004
|
-
() => newUserSsoIdDoc(ssoId, email, userId, tenantId)
|
|
61005
|
-
);
|
|
61006
|
-
}
|
|
61007
|
-
async function addUser(tenantId, userId, email, ssoId) {
|
|
61008
|
-
const promises = [
|
|
61009
|
-
addUserDoc(userId, () => newUserIdDoc(userId, tenantId)),
|
|
61010
|
-
addUserDoc(email, () => newUserEmailDoc(userId, email, tenantId))
|
|
61011
|
-
];
|
|
61012
|
-
if (ssoId) {
|
|
61013
|
-
promises.push(addSsoUser(ssoId, email, userId, tenantId));
|
|
61014
|
-
}
|
|
61015
|
-
await Promise.all(promises);
|
|
61016
|
-
}
|
|
61017
|
-
async function removeUser(user) {
|
|
61018
|
-
const db = getPlatformDB();
|
|
61019
|
-
const keys2 = [user._id, user.email];
|
|
61020
|
-
const userDocs = await db.allDocs({
|
|
61021
|
-
keys: keys2,
|
|
61022
|
-
include_docs: true
|
|
61023
|
-
});
|
|
61024
|
-
await db.bulkRemove(
|
|
61025
|
-
userDocs.rows.map((row) => row.doc),
|
|
61026
|
-
{ silenceErrors: true }
|
|
61027
|
-
);
|
|
61028
|
-
}
|
|
61029
|
-
|
|
61030
|
-
// src/platform/tenants.ts
|
|
61031
|
-
var tenants_exports = {};
|
|
61032
|
-
__export(tenants_exports, {
|
|
61033
|
-
addTenant: () => addTenant,
|
|
61034
|
-
exists: () => exists,
|
|
61035
|
-
getTenantIds: () => getTenantIds,
|
|
61036
|
-
removeTenant: () => removeTenant,
|
|
61037
|
-
tenacyLockOptions: () => tenacyLockOptions
|
|
61038
|
-
});
|
|
61039
|
-
|
|
61040
|
-
// src/redis/redlockImpl.ts
|
|
61041
|
-
var redlockImpl_exports = {};
|
|
61042
|
-
__export(redlockImpl_exports, {
|
|
61043
|
-
AUTO_EXTEND_POLLING_MS: () => AUTO_EXTEND_POLLING_MS,
|
|
61044
|
-
doWithLock: () => doWithLock,
|
|
61045
|
-
newRedlock: () => newRedlock
|
|
61046
|
-
});
|
|
61047
|
-
var import_redlock = __toESM(require("redlock"));
|
|
61048
|
-
|
|
61049
|
-
// src/utils/index.ts
|
|
61050
|
-
var utils_exports4 = {};
|
|
61051
|
-
__export(utils_exports4, {
|
|
61052
|
-
Duration: () => Duration,
|
|
61053
|
-
DurationType: () => DurationType,
|
|
61054
|
-
clearCookie: () => clearCookie,
|
|
61055
|
-
compare: () => compare,
|
|
61056
|
-
getAppIdFromCtx: () => getAppIdFromCtx,
|
|
61057
|
-
getCookie: () => getCookie,
|
|
61058
|
-
hasCircularStructure: () => hasCircularStructure,
|
|
61059
|
-
hash: () => hash,
|
|
61060
|
-
isAudited: () => isAudited,
|
|
61061
|
-
isClient: () => isClient,
|
|
61062
|
-
isPublicApiRequest: () => isPublicApiRequest,
|
|
61063
|
-
isServingApp: () => isServingApp,
|
|
61064
|
-
isServingBuilder: () => isServingBuilder,
|
|
61065
|
-
isServingBuilderPreview: () => isServingBuilderPreview,
|
|
61066
|
-
isValidInternalAPIKey: () => isValidInternalAPIKey,
|
|
61067
|
-
newid: () => newid,
|
|
61068
|
-
openJwt: () => openJwt,
|
|
61069
|
-
resolveAppUrl: () => resolveAppUrl,
|
|
61070
|
-
setCookie: () => setCookie,
|
|
61071
|
-
timeout: () => timeout,
|
|
61072
|
-
validEmail: () => validEmail
|
|
61073
|
-
});
|
|
61074
|
-
|
|
61075
|
-
// src/utils/hashing.ts
|
|
61076
|
-
var bcrypt = environment_default.JS_BCRYPT ? require("bcryptjs") : require("bcrypt");
|
|
61077
|
-
var SALT_ROUNDS = environment_default.SALT_ROUNDS || 10;
|
|
61078
|
-
async function hash(data) {
|
|
61079
|
-
const salt = await bcrypt.genSalt(SALT_ROUNDS);
|
|
61080
|
-
return bcrypt.hash(data, salt);
|
|
61081
|
-
}
|
|
61082
|
-
async function compare(data, encrypted) {
|
|
61083
|
-
return bcrypt.compare(data, encrypted);
|
|
61084
|
-
}
|
|
61085
|
-
|
|
61086
|
-
// src/utils/utils.ts
|
|
61087
|
-
var import_jsonwebtoken = __toESM(require("jsonwebtoken"));
|
|
61088
|
-
var APP_PREFIX3 = "app" /* APP */ + SEPARATOR;
|
|
61089
|
-
var PROD_APP_PREFIX = "/app/";
|
|
61090
|
-
var BUILDER_PREVIEW_PATH = "/app/preview";
|
|
61091
|
-
var BUILDER_PREFIX = "/builder";
|
|
61092
|
-
var BUILDER_APP_PREFIX = `${BUILDER_PREFIX}/app/`;
|
|
61093
|
-
var PUBLIC_API_PREFIX = "/api/public/v";
|
|
61094
|
-
function confirmAppId(possibleAppId) {
|
|
61095
|
-
return possibleAppId && possibleAppId.startsWith(APP_PREFIX3) ? possibleAppId : void 0;
|
|
61096
|
-
}
|
|
61097
|
-
async function resolveAppUrl(ctx) {
|
|
61098
|
-
const appUrl = ctx.path.split("/")[2];
|
|
61099
|
-
let possibleAppUrl = `/${appUrl.toLowerCase()}`;
|
|
61100
|
-
let tenantId = getTenantId();
|
|
61101
|
-
if (!environment_default.isDev() && environment_default.MULTI_TENANCY) {
|
|
61102
|
-
tenantId = getTenantIDFromCtx(ctx, {
|
|
61103
|
-
includeStrategies: ["subdomain" /* SUBDOMAIN */]
|
|
61104
|
-
});
|
|
61105
|
-
}
|
|
61106
|
-
const apps = await doInTenant(
|
|
61107
|
-
tenantId,
|
|
61108
|
-
() => getAllApps({ dev: false })
|
|
61109
|
-
);
|
|
61110
|
-
const app = apps.filter(
|
|
61111
|
-
(a) => a.url && a.url.toLowerCase() === possibleAppUrl
|
|
61112
|
-
)[0];
|
|
61113
|
-
return app && app.appId ? app.appId : void 0;
|
|
61114
|
-
}
|
|
61115
|
-
function isServingApp(ctx) {
|
|
61116
|
-
if (ctx.path.startsWith(`/${APP_PREFIX3}`)) {
|
|
61117
|
-
return true;
|
|
61118
|
-
}
|
|
61119
|
-
return ctx.path.startsWith(PROD_APP_PREFIX);
|
|
61120
|
-
}
|
|
61121
|
-
function isServingBuilder(ctx) {
|
|
61122
|
-
return ctx.path.startsWith(BUILDER_APP_PREFIX);
|
|
61303
|
+
async function getUserDoc(emailOrId) {
|
|
61304
|
+
const db = getPlatformDB();
|
|
61305
|
+
return db.get(emailOrId);
|
|
61123
61306
|
}
|
|
61124
|
-
function
|
|
61125
|
-
|
|
61307
|
+
async function updateUserDoc(platformUser) {
|
|
61308
|
+
const db = getPlatformDB();
|
|
61309
|
+
await db.put(platformUser);
|
|
61126
61310
|
}
|
|
61127
|
-
function
|
|
61128
|
-
return
|
|
61311
|
+
function newUserIdDoc(id, tenantId) {
|
|
61312
|
+
return {
|
|
61313
|
+
_id: id,
|
|
61314
|
+
tenantId
|
|
61315
|
+
};
|
|
61129
61316
|
}
|
|
61130
|
-
|
|
61131
|
-
|
|
61132
|
-
|
|
61133
|
-
|
|
61134
|
-
|
|
61135
|
-
|
|
61136
|
-
break;
|
|
61137
|
-
}
|
|
61138
|
-
}
|
|
61139
|
-
if (!appId && ctx.request.body && ctx.request.body.appId) {
|
|
61140
|
-
appId = confirmAppId(ctx.request.body.appId);
|
|
61141
|
-
}
|
|
61142
|
-
const pathId = parseAppIdFromUrlPath(ctx.path);
|
|
61143
|
-
if (!appId && pathId) {
|
|
61144
|
-
appId = confirmAppId(pathId);
|
|
61145
|
-
}
|
|
61146
|
-
const isBuilderPreview = ctx.path.startsWith(BUILDER_PREVIEW_PATH);
|
|
61147
|
-
const isViewingProdApp = ctx.path.startsWith(PROD_APP_PREFIX) && !isBuilderPreview;
|
|
61148
|
-
if (!appId && isViewingProdApp) {
|
|
61149
|
-
appId = confirmAppId(await resolveAppUrl(ctx));
|
|
61150
|
-
}
|
|
61151
|
-
const referer = ctx.request.headers.referer;
|
|
61152
|
-
if (!appId && referer?.includes(BUILDER_APP_PREFIX)) {
|
|
61153
|
-
const refererId = parseAppIdFromUrlPath(ctx.request.headers.referer);
|
|
61154
|
-
appId = confirmAppId(refererId);
|
|
61155
|
-
}
|
|
61156
|
-
return appId;
|
|
61317
|
+
function newUserEmailDoc(userId, email, tenantId) {
|
|
61318
|
+
return {
|
|
61319
|
+
_id: email,
|
|
61320
|
+
userId,
|
|
61321
|
+
tenantId
|
|
61322
|
+
};
|
|
61157
61323
|
}
|
|
61158
|
-
function
|
|
61159
|
-
|
|
61160
|
-
|
|
61161
|
-
|
|
61162
|
-
|
|
61324
|
+
function newUserSsoIdDoc(ssoId, email, userId, tenantId) {
|
|
61325
|
+
return {
|
|
61326
|
+
_id: ssoId,
|
|
61327
|
+
userId,
|
|
61328
|
+
email,
|
|
61329
|
+
tenantId
|
|
61330
|
+
};
|
|
61163
61331
|
}
|
|
61164
|
-
function
|
|
61165
|
-
|
|
61166
|
-
|
|
61167
|
-
}
|
|
61332
|
+
async function addUserDoc(emailOrId, newDocFn) {
|
|
61333
|
+
const db = getPlatformDB();
|
|
61334
|
+
let user;
|
|
61168
61335
|
try {
|
|
61169
|
-
|
|
61336
|
+
await db.get(emailOrId);
|
|
61170
61337
|
} catch (e) {
|
|
61171
|
-
if (
|
|
61172
|
-
|
|
61338
|
+
if (e.status === 404) {
|
|
61339
|
+
user = newDocFn();
|
|
61340
|
+
await db.put(user);
|
|
61173
61341
|
} else {
|
|
61174
61342
|
throw e;
|
|
61175
61343
|
}
|
|
61176
61344
|
}
|
|
61177
61345
|
}
|
|
61178
|
-
function
|
|
61179
|
-
|
|
61180
|
-
|
|
61181
|
-
|
|
61182
|
-
|
|
61183
|
-
}
|
|
61184
|
-
function getCookie(ctx, name) {
|
|
61185
|
-
const cookie = ctx.cookies.get(name);
|
|
61186
|
-
if (!cookie) {
|
|
61187
|
-
return void 0;
|
|
61188
|
-
}
|
|
61189
|
-
return openJwt(cookie);
|
|
61190
|
-
}
|
|
61191
|
-
function setCookie(ctx, value, name = "builder", opts = { sign: true }) {
|
|
61192
|
-
if (value && opts && opts.sign) {
|
|
61193
|
-
value = import_jsonwebtoken.default.sign(value, environment_default.JWT_SECRET);
|
|
61194
|
-
}
|
|
61195
|
-
const config = {
|
|
61196
|
-
expires: MAX_VALID_DATE,
|
|
61197
|
-
path: "/",
|
|
61198
|
-
httpOnly: false,
|
|
61199
|
-
overwrite: true
|
|
61200
|
-
};
|
|
61201
|
-
if (environment_default.COOKIE_DOMAIN) {
|
|
61202
|
-
config.domain = environment_default.COOKIE_DOMAIN;
|
|
61203
|
-
}
|
|
61204
|
-
ctx.cookies.set(name, value, config);
|
|
61205
|
-
}
|
|
61206
|
-
function clearCookie(ctx, name) {
|
|
61207
|
-
setCookie(ctx, null, name);
|
|
61208
|
-
}
|
|
61209
|
-
function isClient(ctx) {
|
|
61210
|
-
return ctx.headers["x-budibase-type" /* TYPE */] === "client";
|
|
61211
|
-
}
|
|
61212
|
-
function timeout(timeMs) {
|
|
61213
|
-
return new Promise((resolve) => setTimeout(resolve, timeMs));
|
|
61214
|
-
}
|
|
61215
|
-
function isAudited(event) {
|
|
61216
|
-
return !!AuditedEventFriendlyName[event];
|
|
61346
|
+
async function addSsoUser(ssoId, email, userId, tenantId) {
|
|
61347
|
+
return addUserDoc(
|
|
61348
|
+
ssoId,
|
|
61349
|
+
() => newUserSsoIdDoc(ssoId, email, userId, tenantId)
|
|
61350
|
+
);
|
|
61217
61351
|
}
|
|
61218
|
-
function
|
|
61219
|
-
|
|
61220
|
-
|
|
61221
|
-
|
|
61222
|
-
|
|
61223
|
-
|
|
61224
|
-
|
|
61225
|
-
if (err instanceof Error && err?.message.includes("circular structure")) {
|
|
61226
|
-
return true;
|
|
61227
|
-
}
|
|
61352
|
+
async function addUser(tenantId, userId, email, ssoId) {
|
|
61353
|
+
const promises = [
|
|
61354
|
+
addUserDoc(userId, () => newUserIdDoc(userId, tenantId)),
|
|
61355
|
+
addUserDoc(email, () => newUserEmailDoc(userId, email, tenantId))
|
|
61356
|
+
];
|
|
61357
|
+
if (ssoId) {
|
|
61358
|
+
promises.push(addSsoUser(ssoId, email, userId, tenantId));
|
|
61228
61359
|
}
|
|
61229
|
-
|
|
61360
|
+
await Promise.all(promises);
|
|
61230
61361
|
}
|
|
61231
|
-
|
|
61232
|
-
|
|
61233
|
-
|
|
61234
|
-
|
|
61235
|
-
|
|
61362
|
+
async function removeUser(user) {
|
|
61363
|
+
const db = getPlatformDB();
|
|
61364
|
+
const keys2 = [user._id, user.email];
|
|
61365
|
+
const userDocs = await db.allDocs({
|
|
61366
|
+
keys: keys2,
|
|
61367
|
+
include_docs: true
|
|
61368
|
+
});
|
|
61369
|
+
await db.bulkRemove(
|
|
61370
|
+
userDocs.rows.map((row) => row.doc),
|
|
61371
|
+
{ silenceErrors: true }
|
|
61236
61372
|
);
|
|
61237
61373
|
}
|
|
61238
61374
|
|
|
61239
|
-
// src/
|
|
61240
|
-
var
|
|
61241
|
-
|
|
61242
|
-
|
|
61243
|
-
|
|
61244
|
-
|
|
61245
|
-
|
|
61246
|
-
|
|
61247
|
-
})
|
|
61248
|
-
var conversion = {
|
|
61249
|
-
milliseconds: 1,
|
|
61250
|
-
seconds: 1e3,
|
|
61251
|
-
minutes: 60 * 1e3,
|
|
61252
|
-
hours: 60 * 60 * 1e3,
|
|
61253
|
-
days: 24 * 60 * 60 * 1e3
|
|
61254
|
-
};
|
|
61255
|
-
var Duration = class _Duration {
|
|
61256
|
-
static convert(from, to, duration) {
|
|
61257
|
-
const milliseconds = duration * conversion[from];
|
|
61258
|
-
return milliseconds / conversion[to];
|
|
61259
|
-
}
|
|
61260
|
-
static from(from, duration) {
|
|
61261
|
-
return {
|
|
61262
|
-
to: (to) => {
|
|
61263
|
-
return _Duration.convert(from, to, duration);
|
|
61264
|
-
},
|
|
61265
|
-
toMs: () => {
|
|
61266
|
-
return _Duration.convert(from, "milliseconds" /* MILLISECONDS */, duration);
|
|
61267
|
-
},
|
|
61268
|
-
toSeconds: () => {
|
|
61269
|
-
return _Duration.convert(from, "seconds" /* SECONDS */, duration);
|
|
61270
|
-
}
|
|
61271
|
-
};
|
|
61272
|
-
}
|
|
61273
|
-
static fromSeconds(duration) {
|
|
61274
|
-
return _Duration.from("seconds" /* SECONDS */, duration);
|
|
61275
|
-
}
|
|
61276
|
-
static fromMinutes(duration) {
|
|
61277
|
-
return _Duration.from("minutes" /* MINUTES */, duration);
|
|
61278
|
-
}
|
|
61279
|
-
static fromHours(duration) {
|
|
61280
|
-
return _Duration.from("hours" /* HOURS */, duration);
|
|
61281
|
-
}
|
|
61282
|
-
static fromDays(duration) {
|
|
61283
|
-
return _Duration.from("days" /* DAYS */, duration);
|
|
61284
|
-
}
|
|
61285
|
-
static fromMilliseconds(duration) {
|
|
61286
|
-
return _Duration.from("milliseconds" /* MILLISECONDS */, duration);
|
|
61287
|
-
}
|
|
61288
|
-
};
|
|
61375
|
+
// src/platform/tenants.ts
|
|
61376
|
+
var tenants_exports = {};
|
|
61377
|
+
__export(tenants_exports, {
|
|
61378
|
+
addTenant: () => addTenant,
|
|
61379
|
+
exists: () => exists,
|
|
61380
|
+
getTenantIds: () => getTenantIds,
|
|
61381
|
+
removeTenant: () => removeTenant,
|
|
61382
|
+
tenacyLockOptions: () => tenacyLockOptions
|
|
61383
|
+
});
|
|
61289
61384
|
|
|
61290
61385
|
// src/redis/redlockImpl.ts
|
|
61386
|
+
var redlockImpl_exports = {};
|
|
61387
|
+
__export(redlockImpl_exports, {
|
|
61388
|
+
AUTO_EXTEND_POLLING_MS: () => AUTO_EXTEND_POLLING_MS,
|
|
61389
|
+
doWithLock: () => doWithLock,
|
|
61390
|
+
newRedlock: () => newRedlock
|
|
61391
|
+
});
|
|
61392
|
+
var import_redlock = __toESM(require("redlock"));
|
|
61291
61393
|
async function getClient(type, opts) {
|
|
61292
61394
|
if (type === "custom" /* CUSTOM */) {
|
|
61293
61395
|
return newRedlock(opts);
|
|
@@ -61610,7 +61712,6 @@ __export(users_exports3, {
|
|
|
61610
61712
|
isBuilder: () => isBuilder2,
|
|
61611
61713
|
isCreator: () => isCreator2,
|
|
61612
61714
|
isGlobalBuilder: () => isGlobalBuilder2,
|
|
61613
|
-
isSupportedUserSearch: () => isSupportedUserSearch,
|
|
61614
61715
|
paginatedUsers: () => paginatedUsers,
|
|
61615
61716
|
removeAppBuilder: () => removeAppBuilder,
|
|
61616
61717
|
removePortalUserPermissions: () => removePortalUserPermissions,
|
|
@@ -65484,29 +65585,6 @@ function removeUserPassword(users) {
|
|
|
65484
65585
|
}
|
|
65485
65586
|
return users;
|
|
65486
65587
|
}
|
|
65487
|
-
function isSupportedUserSearch(query) {
|
|
65488
|
-
const allowed = [
|
|
65489
|
-
{ op: "string" /* STRING */, key: "email" },
|
|
65490
|
-
{ op: "equal" /* EQUAL */, key: "_id" },
|
|
65491
|
-
{ op: "oneOf" /* ONE_OF */, key: "_id" }
|
|
65492
|
-
];
|
|
65493
|
-
for (let [key, operation] of Object.entries(query)) {
|
|
65494
|
-
if (typeof operation !== "object") {
|
|
65495
|
-
return false;
|
|
65496
|
-
}
|
|
65497
|
-
const fields = Object.keys(operation || {});
|
|
65498
|
-
if (fields.length === 0) {
|
|
65499
|
-
continue;
|
|
65500
|
-
}
|
|
65501
|
-
const allowedOperation = allowed.find(
|
|
65502
|
-
(allow) => allow.op === key && fields.length === 1 && fields[0] === allow.key
|
|
65503
|
-
);
|
|
65504
|
-
if (!allowedOperation) {
|
|
65505
|
-
return false;
|
|
65506
|
-
}
|
|
65507
|
-
}
|
|
65508
|
-
return true;
|
|
65509
|
-
}
|
|
65510
65588
|
async function bulkGetGlobalUsersById(userIds, opts) {
|
|
65511
65589
|
const db = getGlobalDB();
|
|
65512
65590
|
let users = (await db.allDocs({
|
|
@@ -68070,7 +68148,7 @@ var SqlTableQueryBuilder = class {
|
|
|
68070
68148
|
var sqlTable_default = SqlTableQueryBuilder;
|
|
68071
68149
|
|
|
68072
68150
|
// src/sql/sql.ts
|
|
68073
|
-
var
|
|
68151
|
+
var import_lodash4 = require("lodash");
|
|
68074
68152
|
function getBaseLimit() {
|
|
68075
68153
|
const envLimit = environment_default.SQL_MAX_ROWS ? parseInt(environment_default.SQL_MAX_ROWS) : null;
|
|
68076
68154
|
return envLimit || 5e3;
|
|
@@ -68259,7 +68337,7 @@ var InternalBuilder = class {
|
|
|
68259
68337
|
return body2;
|
|
68260
68338
|
}
|
|
68261
68339
|
parseFilters(filters) {
|
|
68262
|
-
filters = (0,
|
|
68340
|
+
filters = (0, import_lodash4.cloneDeep)(filters);
|
|
68263
68341
|
for (const op of Object.values(BasicOperator)) {
|
|
68264
68342
|
const filter = filters[op];
|
|
68265
68343
|
if (!filter) {
|
|
@@ -68681,8 +68759,36 @@ var InternalBuilder = class {
|
|
|
68681
68759
|
}
|
|
68682
68760
|
return query.countDistinct(`${aliased}.${primary[0]} as total`);
|
|
68683
68761
|
}
|
|
68762
|
+
addAggregations(query, aggregations) {
|
|
68763
|
+
const fields = this.query.resource?.fields || [];
|
|
68764
|
+
if (fields.length > 0) {
|
|
68765
|
+
query = query.groupBy(fields.map((field) => `${this.table.name}.${field}`));
|
|
68766
|
+
}
|
|
68767
|
+
for (const aggregation of aggregations) {
|
|
68768
|
+
const op = aggregation.calculationType;
|
|
68769
|
+
const field = `${this.table.name}.${aggregation.field} as ${aggregation.name}`;
|
|
68770
|
+
switch (op) {
|
|
68771
|
+
case "count" /* COUNT */:
|
|
68772
|
+
query = query.count(field);
|
|
68773
|
+
break;
|
|
68774
|
+
case "sum" /* SUM */:
|
|
68775
|
+
query = query.sum(field);
|
|
68776
|
+
break;
|
|
68777
|
+
case "avg" /* AVG */:
|
|
68778
|
+
query = query.avg(field);
|
|
68779
|
+
break;
|
|
68780
|
+
case "min" /* MIN */:
|
|
68781
|
+
query = query.min(field);
|
|
68782
|
+
break;
|
|
68783
|
+
case "max" /* MAX */:
|
|
68784
|
+
query = query.max(field);
|
|
68785
|
+
break;
|
|
68786
|
+
}
|
|
68787
|
+
}
|
|
68788
|
+
return query;
|
|
68789
|
+
}
|
|
68684
68790
|
addSorting(query) {
|
|
68685
|
-
let { sort: sort2 } = this.query;
|
|
68791
|
+
let { sort: sort2, resource } = this.query;
|
|
68686
68792
|
const primaryKey = this.table.primary;
|
|
68687
68793
|
const tableName = getTableName(this.table);
|
|
68688
68794
|
const aliases = this.query.tableAliases;
|
|
@@ -68707,7 +68813,8 @@ var InternalBuilder = class {
|
|
|
68707
68813
|
}
|
|
68708
68814
|
}
|
|
68709
68815
|
}
|
|
68710
|
-
|
|
68816
|
+
const hasAggregations = (resource?.aggregations?.length ?? 0) > 0;
|
|
68817
|
+
if (!hasAggregations && (!sort2 || sort2[primaryKey[0]] === void 0)) {
|
|
68711
68818
|
query = query.orderBy(`${aliased}.${primaryKey[0]}`);
|
|
68712
68819
|
}
|
|
68713
68820
|
return query;
|
|
@@ -68981,7 +69088,14 @@ var InternalBuilder = class {
|
|
|
68981
69088
|
query = query.offset(foundOffset);
|
|
68982
69089
|
}
|
|
68983
69090
|
}
|
|
68984
|
-
|
|
69091
|
+
const aggregations = this.query.resource?.aggregations || [];
|
|
69092
|
+
if (counting) {
|
|
69093
|
+
query = this.addDistinctCount(query);
|
|
69094
|
+
} else if (aggregations.length > 0) {
|
|
69095
|
+
query = this.addAggregations(query, aggregations);
|
|
69096
|
+
} else {
|
|
69097
|
+
query = query.select(this.generateSelectStatement());
|
|
69098
|
+
}
|
|
68985
69099
|
if (!counting) {
|
|
68986
69100
|
query = this.addSorting(query);
|
|
68987
69101
|
}
|