@budibase/backend-core 2.11.42 → 2.11.44
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 +652 -587
- package/dist/index.js.map +3 -3
- package/dist/index.js.meta.json +1 -1
- package/dist/package.json +4 -4
- package/dist/plugins.js.map +1 -1
- package/dist/plugins.js.meta.json +1 -1
- package/dist/src/environment.js +2 -2
- package/dist/src/environment.js.map +1 -1
- package/dist/src/objectStore/buckets/app.d.ts +7 -10
- package/dist/src/objectStore/buckets/app.js +40 -27
- package/dist/src/objectStore/buckets/app.js.map +1 -1
- package/dist/src/objectStore/buckets/plugins.d.ts +4 -4
- package/dist/src/objectStore/buckets/plugins.js +19 -19
- package/dist/src/objectStore/buckets/plugins.js.map +1 -1
- package/dist/src/objectStore/objectStore.d.ts +19 -16
- package/dist/src/objectStore/objectStore.js +257 -218
- package/dist/src/objectStore/objectStore.js.map +1 -1
- package/dist/src/users/users.d.ts +1 -0
- package/dist/src/users/users.js +20 -2
- package/dist/src/users/users.js.map +1 -1
- package/dist/src/users/utils.d.ts +1 -0
- package/dist/src/users/utils.js +2 -1
- package/dist/src/users/utils.js.map +1 -1
- package/dist/tests/core/utilities/structures/licenses.js +5 -0
- package/dist/tests/core/utilities/structures/licenses.js.map +1 -1
- package/dist/tests/core/utilities/structures/quotas.d.ts +1 -1
- package/dist/tests/core/utilities/structures/quotas.js +3 -2
- package/dist/tests/core/utilities/structures/quotas.js.map +1 -1
- package/package.json +4 -4
- package/src/environment.ts +2 -2
- package/src/objectStore/buckets/app.ts +36 -23
- package/src/objectStore/buckets/plugins.ts +8 -8
- package/src/objectStore/buckets/tests/app.spec.ts +16 -26
- package/src/objectStore/objectStore.ts +38 -24
- package/src/users/users.ts +15 -1
- package/src/users/utils.ts +1 -0
- package/tests/core/utilities/structures/licenses.ts +5 -0
- package/tests/core/utilities/structures/quotas.ts +3 -2
package/dist/index.js
CHANGED
|
@@ -1753,11 +1753,11 @@ function getPackageJsonFields() {
|
|
|
1753
1753
|
const content = (0, import_fs.readFileSync)(packageJsonFile, "utf-8");
|
|
1754
1754
|
const parsedContent = JSON.parse(content);
|
|
1755
1755
|
return {
|
|
1756
|
-
VERSION: parsedContent.version,
|
|
1756
|
+
VERSION: process.env.BUDIBASE_VERSION || parsedContent.version,
|
|
1757
1757
|
SERVICE_NAME: parsedContent.name
|
|
1758
1758
|
};
|
|
1759
1759
|
} catch {
|
|
1760
|
-
return { VERSION: "", SERVICE_NAME: "" };
|
|
1760
|
+
return { VERSION: process.env.BUDIBASE_VERSION || "", SERVICE_NAME: "" };
|
|
1761
1761
|
}
|
|
1762
1762
|
}
|
|
1763
1763
|
function isWorker() {
|
|
@@ -2141,8 +2141,8 @@ var init_pouchDB = __esm({
|
|
|
2141
2141
|
import_pouchdb.default.adapter("writableStream", replicationStream.adapters.writableStream);
|
|
2142
2142
|
}
|
|
2143
2143
|
if (opts.find) {
|
|
2144
|
-
const
|
|
2145
|
-
import_pouchdb.default.plugin(
|
|
2144
|
+
const find2 = require("pouchdb-find");
|
|
2145
|
+
import_pouchdb.default.plugin(find2);
|
|
2146
2146
|
}
|
|
2147
2147
|
return import_pouchdb.default.defaults(POUCH_DB_DEFAULTS);
|
|
2148
2148
|
};
|
|
@@ -2581,12 +2581,12 @@ function getAppId() {
|
|
|
2581
2581
|
return foundId;
|
|
2582
2582
|
}
|
|
2583
2583
|
}
|
|
2584
|
-
function doInEnvironmentContext(
|
|
2585
|
-
if (!
|
|
2584
|
+
function doInEnvironmentContext(values2, task) {
|
|
2585
|
+
if (!values2) {
|
|
2586
2586
|
throw new Error("Must supply environment variables.");
|
|
2587
2587
|
}
|
|
2588
2588
|
const updates = {
|
|
2589
|
-
environmentVariables:
|
|
2589
|
+
environmentVariables: values2
|
|
2590
2590
|
};
|
|
2591
2591
|
return newContext(updates, task);
|
|
2592
2592
|
}
|
|
@@ -4734,7 +4734,282 @@ function sanitizeKey(input) {
|
|
|
4734
4734
|
function sanitizeBucket(input) {
|
|
4735
4735
|
return input.replace(new RegExp(APP_DEV_PREFIX, "g"), APP_PREFIX);
|
|
4736
4736
|
}
|
|
4737
|
-
|
|
4737
|
+
function ObjectStore(bucket, opts = { presigning: false }) {
|
|
4738
|
+
const config = {
|
|
4739
|
+
s3ForcePathStyle: true,
|
|
4740
|
+
signatureVersion: "v4",
|
|
4741
|
+
apiVersion: "2006-03-01",
|
|
4742
|
+
accessKeyId: environment_default.MINIO_ACCESS_KEY,
|
|
4743
|
+
secretAccessKey: environment_default.MINIO_SECRET_KEY,
|
|
4744
|
+
region: environment_default.AWS_REGION
|
|
4745
|
+
};
|
|
4746
|
+
if (bucket) {
|
|
4747
|
+
config.params = {
|
|
4748
|
+
Bucket: sanitizeBucket(bucket)
|
|
4749
|
+
};
|
|
4750
|
+
}
|
|
4751
|
+
if (environment_default.MINIO_URL) {
|
|
4752
|
+
if (opts.presigning && environment_default.MINIO_ENABLED) {
|
|
4753
|
+
config.endpoint = "minio-service";
|
|
4754
|
+
} else {
|
|
4755
|
+
config.endpoint = environment_default.MINIO_URL;
|
|
4756
|
+
}
|
|
4757
|
+
}
|
|
4758
|
+
return new import_aws_sdk.default.S3(config);
|
|
4759
|
+
}
|
|
4760
|
+
async function makeSureBucketExists(client, bucketName) {
|
|
4761
|
+
bucketName = sanitizeBucket(bucketName);
|
|
4762
|
+
try {
|
|
4763
|
+
await client.headBucket({
|
|
4764
|
+
Bucket: bucketName
|
|
4765
|
+
}).promise();
|
|
4766
|
+
} catch (err) {
|
|
4767
|
+
const promises = STATE.bucketCreationPromises;
|
|
4768
|
+
const doesntExist = err.statusCode === 404, noAccess = err.statusCode === 403;
|
|
4769
|
+
if (promises[bucketName]) {
|
|
4770
|
+
await promises[bucketName];
|
|
4771
|
+
} else if (doesntExist || noAccess) {
|
|
4772
|
+
if (doesntExist) {
|
|
4773
|
+
promises[bucketName] = client.createBucket({
|
|
4774
|
+
Bucket: bucketName
|
|
4775
|
+
}).promise();
|
|
4776
|
+
await promises[bucketName];
|
|
4777
|
+
delete promises[bucketName];
|
|
4778
|
+
}
|
|
4779
|
+
} else {
|
|
4780
|
+
throw new Error("Unable to write to object store bucket.");
|
|
4781
|
+
}
|
|
4782
|
+
}
|
|
4783
|
+
}
|
|
4784
|
+
async function upload({
|
|
4785
|
+
bucket: bucketName,
|
|
4786
|
+
filename,
|
|
4787
|
+
path: path2,
|
|
4788
|
+
type,
|
|
4789
|
+
metadata
|
|
4790
|
+
}) {
|
|
4791
|
+
const extension = filename.split(".").pop();
|
|
4792
|
+
const fileBytes = import_fs3.default.readFileSync(path2);
|
|
4793
|
+
const objectStore = ObjectStore(bucketName);
|
|
4794
|
+
await makeSureBucketExists(objectStore, bucketName);
|
|
4795
|
+
let contentType = type;
|
|
4796
|
+
if (!contentType) {
|
|
4797
|
+
contentType = extension ? CONTENT_TYPE_MAP[extension.toLowerCase()] : CONTENT_TYPE_MAP.txt;
|
|
4798
|
+
}
|
|
4799
|
+
const config = {
|
|
4800
|
+
// windows file paths need to be converted to forward slashes for s3
|
|
4801
|
+
Key: sanitizeKey(filename),
|
|
4802
|
+
Body: fileBytes,
|
|
4803
|
+
ContentType: contentType
|
|
4804
|
+
};
|
|
4805
|
+
if (metadata && typeof metadata === "object") {
|
|
4806
|
+
for (let key of Object.keys(metadata)) {
|
|
4807
|
+
if (!metadata[key] || typeof metadata[key] !== "string") {
|
|
4808
|
+
delete metadata[key];
|
|
4809
|
+
}
|
|
4810
|
+
}
|
|
4811
|
+
config.Metadata = metadata;
|
|
4812
|
+
}
|
|
4813
|
+
return objectStore.upload(config).promise();
|
|
4814
|
+
}
|
|
4815
|
+
async function streamUpload(bucketName, filename, stream2, extra = {}) {
|
|
4816
|
+
const objectStore = ObjectStore(bucketName);
|
|
4817
|
+
await makeSureBucketExists(objectStore, bucketName);
|
|
4818
|
+
if (filename?.endsWith(".js")) {
|
|
4819
|
+
extra = {
|
|
4820
|
+
...extra,
|
|
4821
|
+
ContentType: "application/javascript"
|
|
4822
|
+
};
|
|
4823
|
+
} else if (filename?.endsWith(".svg")) {
|
|
4824
|
+
extra = {
|
|
4825
|
+
...extra,
|
|
4826
|
+
ContentType: "image"
|
|
4827
|
+
};
|
|
4828
|
+
}
|
|
4829
|
+
const params2 = {
|
|
4830
|
+
Bucket: sanitizeBucket(bucketName),
|
|
4831
|
+
Key: sanitizeKey(filename),
|
|
4832
|
+
Body: stream2,
|
|
4833
|
+
...extra
|
|
4834
|
+
};
|
|
4835
|
+
return objectStore.upload(params2).promise();
|
|
4836
|
+
}
|
|
4837
|
+
async function retrieve(bucketName, filepath) {
|
|
4838
|
+
const objectStore = ObjectStore(bucketName);
|
|
4839
|
+
const params2 = {
|
|
4840
|
+
Bucket: sanitizeBucket(bucketName),
|
|
4841
|
+
Key: sanitizeKey(filepath)
|
|
4842
|
+
};
|
|
4843
|
+
const response = await objectStore.getObject(params2).promise();
|
|
4844
|
+
if (STRING_CONTENT_TYPES.includes(response.ContentType)) {
|
|
4845
|
+
return response.Body.toString("utf8");
|
|
4846
|
+
} else {
|
|
4847
|
+
return response.Body;
|
|
4848
|
+
}
|
|
4849
|
+
}
|
|
4850
|
+
async function listAllObjects(bucketName, path2) {
|
|
4851
|
+
const objectStore = ObjectStore(bucketName);
|
|
4852
|
+
const list = (params2 = {}) => {
|
|
4853
|
+
return objectStore.listObjectsV2({
|
|
4854
|
+
...params2,
|
|
4855
|
+
Bucket: sanitizeBucket(bucketName),
|
|
4856
|
+
Prefix: sanitizeKey(path2)
|
|
4857
|
+
}).promise();
|
|
4858
|
+
};
|
|
4859
|
+
let isTruncated = false, token, objects = [];
|
|
4860
|
+
do {
|
|
4861
|
+
let params2 = {};
|
|
4862
|
+
if (token) {
|
|
4863
|
+
params2.ContinuationToken = token;
|
|
4864
|
+
}
|
|
4865
|
+
const response = await list(params2);
|
|
4866
|
+
if (response.Contents) {
|
|
4867
|
+
objects = objects.concat(response.Contents);
|
|
4868
|
+
}
|
|
4869
|
+
isTruncated = !!response.IsTruncated;
|
|
4870
|
+
} while (isTruncated);
|
|
4871
|
+
return objects;
|
|
4872
|
+
}
|
|
4873
|
+
function getPresignedUrl(bucketName, key, durationSeconds = 3600) {
|
|
4874
|
+
const objectStore = ObjectStore(bucketName, { presigning: true });
|
|
4875
|
+
const params2 = {
|
|
4876
|
+
Bucket: sanitizeBucket(bucketName),
|
|
4877
|
+
Key: sanitizeKey(key),
|
|
4878
|
+
Expires: durationSeconds
|
|
4879
|
+
};
|
|
4880
|
+
const url = objectStore.getSignedUrl("getObject", params2);
|
|
4881
|
+
if (!environment_default.MINIO_ENABLED) {
|
|
4882
|
+
return url;
|
|
4883
|
+
} else {
|
|
4884
|
+
const signedUrl = new URL(url);
|
|
4885
|
+
const path2 = signedUrl.pathname;
|
|
4886
|
+
const query = signedUrl.search;
|
|
4887
|
+
return `/files/signed${path2}${query}`;
|
|
4888
|
+
}
|
|
4889
|
+
}
|
|
4890
|
+
async function retrieveToTmp(bucketName, filepath) {
|
|
4891
|
+
bucketName = sanitizeBucket(bucketName);
|
|
4892
|
+
filepath = sanitizeKey(filepath);
|
|
4893
|
+
const data = await retrieve(bucketName, filepath);
|
|
4894
|
+
const outputPath = (0, import_path2.join)(budibaseTempDir(), (0, import_uuid2.v4)());
|
|
4895
|
+
import_fs3.default.writeFileSync(outputPath, data);
|
|
4896
|
+
return outputPath;
|
|
4897
|
+
}
|
|
4898
|
+
async function retrieveDirectory(bucketName, path2) {
|
|
4899
|
+
let writePath = (0, import_path2.join)(budibaseTempDir(), (0, import_uuid2.v4)());
|
|
4900
|
+
import_fs3.default.mkdirSync(writePath);
|
|
4901
|
+
const objects = await listAllObjects(bucketName, path2);
|
|
4902
|
+
let fullObjects = await Promise.all(
|
|
4903
|
+
objects.map((obj) => retrieve(bucketName, obj.Key))
|
|
4904
|
+
);
|
|
4905
|
+
let count = 0;
|
|
4906
|
+
for (let obj of objects) {
|
|
4907
|
+
const filename = obj.Key;
|
|
4908
|
+
const data = fullObjects[count++];
|
|
4909
|
+
const possiblePath = filename.split("/");
|
|
4910
|
+
if (possiblePath.length > 1) {
|
|
4911
|
+
const dirs = possiblePath.slice(0, possiblePath.length - 1);
|
|
4912
|
+
import_fs3.default.mkdirSync((0, import_path2.join)(writePath, ...dirs), { recursive: true });
|
|
4913
|
+
}
|
|
4914
|
+
import_fs3.default.writeFileSync((0, import_path2.join)(writePath, ...possiblePath), data);
|
|
4915
|
+
}
|
|
4916
|
+
return writePath;
|
|
4917
|
+
}
|
|
4918
|
+
async function deleteFile(bucketName, filepath) {
|
|
4919
|
+
const objectStore = ObjectStore(bucketName);
|
|
4920
|
+
await makeSureBucketExists(objectStore, bucketName);
|
|
4921
|
+
const params2 = {
|
|
4922
|
+
Bucket: bucketName,
|
|
4923
|
+
Key: sanitizeKey(filepath)
|
|
4924
|
+
};
|
|
4925
|
+
return objectStore.deleteObject(params2).promise();
|
|
4926
|
+
}
|
|
4927
|
+
async function deleteFiles(bucketName, filepaths) {
|
|
4928
|
+
const objectStore = ObjectStore(bucketName);
|
|
4929
|
+
await makeSureBucketExists(objectStore, bucketName);
|
|
4930
|
+
const params2 = {
|
|
4931
|
+
Bucket: bucketName,
|
|
4932
|
+
Delete: {
|
|
4933
|
+
Objects: filepaths.map((path2) => ({ Key: sanitizeKey(path2) }))
|
|
4934
|
+
}
|
|
4935
|
+
};
|
|
4936
|
+
return objectStore.deleteObjects(params2).promise();
|
|
4937
|
+
}
|
|
4938
|
+
async function deleteFolder(bucketName, folder) {
|
|
4939
|
+
bucketName = sanitizeBucket(bucketName);
|
|
4940
|
+
folder = sanitizeKey(folder);
|
|
4941
|
+
const client = ObjectStore(bucketName);
|
|
4942
|
+
const listParams = {
|
|
4943
|
+
Bucket: bucketName,
|
|
4944
|
+
Prefix: folder
|
|
4945
|
+
};
|
|
4946
|
+
const existingObjectsResponse = await client.listObjects(listParams).promise();
|
|
4947
|
+
if (existingObjectsResponse.Contents?.length === 0) {
|
|
4948
|
+
return;
|
|
4949
|
+
}
|
|
4950
|
+
const deleteParams = {
|
|
4951
|
+
Bucket: bucketName,
|
|
4952
|
+
Delete: {
|
|
4953
|
+
Objects: []
|
|
4954
|
+
}
|
|
4955
|
+
};
|
|
4956
|
+
existingObjectsResponse.Contents?.forEach((content) => {
|
|
4957
|
+
deleteParams.Delete.Objects.push({ Key: content.Key });
|
|
4958
|
+
});
|
|
4959
|
+
const deleteResponse = await client.deleteObjects(deleteParams).promise();
|
|
4960
|
+
if (deleteResponse.Deleted?.length === 1e3) {
|
|
4961
|
+
return deleteFolder(bucketName, folder);
|
|
4962
|
+
}
|
|
4963
|
+
}
|
|
4964
|
+
async function uploadDirectory(bucketName, localPath, bucketPath) {
|
|
4965
|
+
bucketName = sanitizeBucket(bucketName);
|
|
4966
|
+
let uploads = [];
|
|
4967
|
+
const files = import_fs3.default.readdirSync(localPath, { withFileTypes: true });
|
|
4968
|
+
for (let file of files) {
|
|
4969
|
+
const path2 = sanitizeKey((0, import_path2.join)(bucketPath, file.name));
|
|
4970
|
+
const local = (0, import_path2.join)(localPath, file.name);
|
|
4971
|
+
if (file.isDirectory()) {
|
|
4972
|
+
uploads.push(uploadDirectory(bucketName, local, path2));
|
|
4973
|
+
} else {
|
|
4974
|
+
uploads.push(streamUpload(bucketName, path2, import_fs3.default.createReadStream(local)));
|
|
4975
|
+
}
|
|
4976
|
+
}
|
|
4977
|
+
await Promise.all(uploads);
|
|
4978
|
+
return files;
|
|
4979
|
+
}
|
|
4980
|
+
async function downloadTarballDirect(url, path2, headers = {}) {
|
|
4981
|
+
path2 = sanitizeKey(path2);
|
|
4982
|
+
const response = await (0, import_node_fetch3.default)(url, { headers });
|
|
4983
|
+
if (!response.ok) {
|
|
4984
|
+
throw new Error(`unexpected response ${response.statusText}`);
|
|
4985
|
+
}
|
|
4986
|
+
await streamPipeline(response.body, import_zlib.default.createUnzip(), import_tar_fs.default.extract(path2));
|
|
4987
|
+
}
|
|
4988
|
+
async function downloadTarball(url, bucketName, path2) {
|
|
4989
|
+
bucketName = sanitizeBucket(bucketName);
|
|
4990
|
+
path2 = sanitizeKey(path2);
|
|
4991
|
+
const response = await (0, import_node_fetch3.default)(url);
|
|
4992
|
+
if (!response.ok) {
|
|
4993
|
+
throw new Error(`unexpected response ${response.statusText}`);
|
|
4994
|
+
}
|
|
4995
|
+
const tmpPath = (0, import_path2.join)(budibaseTempDir(), path2);
|
|
4996
|
+
await streamPipeline(response.body, import_zlib.default.createUnzip(), import_tar_fs.default.extract(tmpPath));
|
|
4997
|
+
if (!environment_default.isTest() && environment_default.SELF_HOSTED) {
|
|
4998
|
+
await uploadDirectory(bucketName, tmpPath, path2);
|
|
4999
|
+
}
|
|
5000
|
+
return tmpPath;
|
|
5001
|
+
}
|
|
5002
|
+
async function getReadStream(bucketName, path2) {
|
|
5003
|
+
bucketName = sanitizeBucket(bucketName);
|
|
5004
|
+
path2 = sanitizeKey(path2);
|
|
5005
|
+
const client = ObjectStore(bucketName);
|
|
5006
|
+
const params2 = {
|
|
5007
|
+
Bucket: bucketName,
|
|
5008
|
+
Key: path2
|
|
5009
|
+
};
|
|
5010
|
+
return client.getObject(params2).createReadStream();
|
|
5011
|
+
}
|
|
5012
|
+
var import_aws_sdk, import_stream, import_node_fetch3, import_tar_fs, import_zlib, import_util, import_path2, import_fs3, import_uuid2, sanitize, streamPipeline, STATE, CONTENT_TYPE_MAP, STRING_CONTENT_TYPES;
|
|
4738
5013
|
var init_objectStore = __esm({
|
|
4739
5014
|
"src/objectStore/objectStore.ts"() {
|
|
4740
5015
|
"use strict";
|
|
@@ -4769,271 +5044,6 @@ var init_objectStore = __esm({
|
|
|
4769
5044
|
CONTENT_TYPE_MAP.js,
|
|
4770
5045
|
CONTENT_TYPE_MAP.json
|
|
4771
5046
|
];
|
|
4772
|
-
ObjectStore = (bucket, opts = { presigning: false }) => {
|
|
4773
|
-
const config = {
|
|
4774
|
-
s3ForcePathStyle: true,
|
|
4775
|
-
signatureVersion: "v4",
|
|
4776
|
-
apiVersion: "2006-03-01",
|
|
4777
|
-
accessKeyId: environment_default.MINIO_ACCESS_KEY,
|
|
4778
|
-
secretAccessKey: environment_default.MINIO_SECRET_KEY,
|
|
4779
|
-
region: environment_default.AWS_REGION
|
|
4780
|
-
};
|
|
4781
|
-
if (bucket) {
|
|
4782
|
-
config.params = {
|
|
4783
|
-
Bucket: sanitizeBucket(bucket)
|
|
4784
|
-
};
|
|
4785
|
-
}
|
|
4786
|
-
if (environment_default.MINIO_URL) {
|
|
4787
|
-
if (opts.presigning && environment_default.MINIO_ENABLED) {
|
|
4788
|
-
config.endpoint = "minio-service";
|
|
4789
|
-
} else {
|
|
4790
|
-
config.endpoint = environment_default.MINIO_URL;
|
|
4791
|
-
}
|
|
4792
|
-
}
|
|
4793
|
-
return new import_aws_sdk.default.S3(config);
|
|
4794
|
-
};
|
|
4795
|
-
makeSureBucketExists = async (client, bucketName) => {
|
|
4796
|
-
bucketName = sanitizeBucket(bucketName);
|
|
4797
|
-
try {
|
|
4798
|
-
await client.headBucket({
|
|
4799
|
-
Bucket: bucketName
|
|
4800
|
-
}).promise();
|
|
4801
|
-
} catch (err) {
|
|
4802
|
-
const promises = STATE.bucketCreationPromises;
|
|
4803
|
-
const doesntExist = err.statusCode === 404, noAccess = err.statusCode === 403;
|
|
4804
|
-
if (promises[bucketName]) {
|
|
4805
|
-
await promises[bucketName];
|
|
4806
|
-
} else if (doesntExist || noAccess) {
|
|
4807
|
-
if (doesntExist) {
|
|
4808
|
-
promises[bucketName] = client.createBucket({
|
|
4809
|
-
Bucket: bucketName
|
|
4810
|
-
}).promise();
|
|
4811
|
-
await promises[bucketName];
|
|
4812
|
-
delete promises[bucketName];
|
|
4813
|
-
}
|
|
4814
|
-
} else {
|
|
4815
|
-
throw new Error("Unable to write to object store bucket.");
|
|
4816
|
-
}
|
|
4817
|
-
}
|
|
4818
|
-
};
|
|
4819
|
-
upload = async ({
|
|
4820
|
-
bucket: bucketName,
|
|
4821
|
-
filename,
|
|
4822
|
-
path: path2,
|
|
4823
|
-
type,
|
|
4824
|
-
metadata
|
|
4825
|
-
}) => {
|
|
4826
|
-
const extension = filename.split(".").pop();
|
|
4827
|
-
const fileBytes = import_fs3.default.readFileSync(path2);
|
|
4828
|
-
const objectStore = ObjectStore(bucketName);
|
|
4829
|
-
await makeSureBucketExists(objectStore, bucketName);
|
|
4830
|
-
let contentType = type;
|
|
4831
|
-
if (!contentType) {
|
|
4832
|
-
contentType = extension ? CONTENT_TYPE_MAP[extension.toLowerCase()] : CONTENT_TYPE_MAP.txt;
|
|
4833
|
-
}
|
|
4834
|
-
const config = {
|
|
4835
|
-
// windows file paths need to be converted to forward slashes for s3
|
|
4836
|
-
Key: sanitizeKey(filename),
|
|
4837
|
-
Body: fileBytes,
|
|
4838
|
-
ContentType: contentType
|
|
4839
|
-
};
|
|
4840
|
-
if (metadata && typeof metadata === "object") {
|
|
4841
|
-
for (let key of Object.keys(metadata)) {
|
|
4842
|
-
if (!metadata[key] || typeof metadata[key] !== "string") {
|
|
4843
|
-
delete metadata[key];
|
|
4844
|
-
}
|
|
4845
|
-
}
|
|
4846
|
-
config.Metadata = metadata;
|
|
4847
|
-
}
|
|
4848
|
-
return objectStore.upload(config).promise();
|
|
4849
|
-
};
|
|
4850
|
-
streamUpload = async (bucketName, filename, stream2, extra = {}) => {
|
|
4851
|
-
const objectStore = ObjectStore(bucketName);
|
|
4852
|
-
await makeSureBucketExists(objectStore, bucketName);
|
|
4853
|
-
if (filename?.endsWith(".js")) {
|
|
4854
|
-
extra = {
|
|
4855
|
-
...extra,
|
|
4856
|
-
ContentType: "application/javascript"
|
|
4857
|
-
};
|
|
4858
|
-
} else if (filename?.endsWith(".svg")) {
|
|
4859
|
-
extra = {
|
|
4860
|
-
...extra,
|
|
4861
|
-
ContentType: "image"
|
|
4862
|
-
};
|
|
4863
|
-
}
|
|
4864
|
-
const params2 = {
|
|
4865
|
-
Bucket: sanitizeBucket(bucketName),
|
|
4866
|
-
Key: sanitizeKey(filename),
|
|
4867
|
-
Body: stream2,
|
|
4868
|
-
...extra
|
|
4869
|
-
};
|
|
4870
|
-
return objectStore.upload(params2).promise();
|
|
4871
|
-
};
|
|
4872
|
-
retrieve = async (bucketName, filepath) => {
|
|
4873
|
-
const objectStore = ObjectStore(bucketName);
|
|
4874
|
-
const params2 = {
|
|
4875
|
-
Bucket: sanitizeBucket(bucketName),
|
|
4876
|
-
Key: sanitizeKey(filepath)
|
|
4877
|
-
};
|
|
4878
|
-
const response = await objectStore.getObject(params2).promise();
|
|
4879
|
-
if (STRING_CONTENT_TYPES.includes(response.ContentType)) {
|
|
4880
|
-
return response.Body.toString("utf8");
|
|
4881
|
-
} else {
|
|
4882
|
-
return response.Body;
|
|
4883
|
-
}
|
|
4884
|
-
};
|
|
4885
|
-
listAllObjects = async (bucketName, path2) => {
|
|
4886
|
-
const objectStore = ObjectStore(bucketName);
|
|
4887
|
-
const list = (params2 = {}) => {
|
|
4888
|
-
return objectStore.listObjectsV2({
|
|
4889
|
-
...params2,
|
|
4890
|
-
Bucket: sanitizeBucket(bucketName),
|
|
4891
|
-
Prefix: sanitizeKey(path2)
|
|
4892
|
-
}).promise();
|
|
4893
|
-
};
|
|
4894
|
-
let isTruncated = false, token, objects = [];
|
|
4895
|
-
do {
|
|
4896
|
-
let params2 = {};
|
|
4897
|
-
if (token) {
|
|
4898
|
-
params2.ContinuationToken = token;
|
|
4899
|
-
}
|
|
4900
|
-
const response = await list(params2);
|
|
4901
|
-
if (response.Contents) {
|
|
4902
|
-
objects = objects.concat(response.Contents);
|
|
4903
|
-
}
|
|
4904
|
-
isTruncated = !!response.IsTruncated;
|
|
4905
|
-
} while (isTruncated);
|
|
4906
|
-
return objects;
|
|
4907
|
-
};
|
|
4908
|
-
getPresignedUrl = (bucketName, key, durationSeconds = 3600) => {
|
|
4909
|
-
const objectStore = ObjectStore(bucketName, { presigning: true });
|
|
4910
|
-
const params2 = {
|
|
4911
|
-
Bucket: sanitizeBucket(bucketName),
|
|
4912
|
-
Key: sanitizeKey(key),
|
|
4913
|
-
Expires: durationSeconds
|
|
4914
|
-
};
|
|
4915
|
-
const url = objectStore.getSignedUrl("getObject", params2);
|
|
4916
|
-
if (!environment_default.MINIO_ENABLED) {
|
|
4917
|
-
return url;
|
|
4918
|
-
} else {
|
|
4919
|
-
const signedUrl = new URL(url);
|
|
4920
|
-
const path2 = signedUrl.pathname;
|
|
4921
|
-
const query = signedUrl.search;
|
|
4922
|
-
return `/files/signed${path2}${query}`;
|
|
4923
|
-
}
|
|
4924
|
-
};
|
|
4925
|
-
retrieveToTmp = async (bucketName, filepath) => {
|
|
4926
|
-
bucketName = sanitizeBucket(bucketName);
|
|
4927
|
-
filepath = sanitizeKey(filepath);
|
|
4928
|
-
const data = await retrieve(bucketName, filepath);
|
|
4929
|
-
const outputPath = (0, import_path2.join)(budibaseTempDir(), (0, import_uuid2.v4)());
|
|
4930
|
-
import_fs3.default.writeFileSync(outputPath, data);
|
|
4931
|
-
return outputPath;
|
|
4932
|
-
};
|
|
4933
|
-
retrieveDirectory = async (bucketName, path2) => {
|
|
4934
|
-
let writePath = (0, import_path2.join)(budibaseTempDir(), (0, import_uuid2.v4)());
|
|
4935
|
-
import_fs3.default.mkdirSync(writePath);
|
|
4936
|
-
const objects = await listAllObjects(bucketName, path2);
|
|
4937
|
-
let fullObjects = await Promise.all(
|
|
4938
|
-
objects.map((obj) => retrieve(bucketName, obj.Key))
|
|
4939
|
-
);
|
|
4940
|
-
let count = 0;
|
|
4941
|
-
for (let obj of objects) {
|
|
4942
|
-
const filename = obj.Key;
|
|
4943
|
-
const data = fullObjects[count++];
|
|
4944
|
-
const possiblePath = filename.split("/");
|
|
4945
|
-
if (possiblePath.length > 1) {
|
|
4946
|
-
const dirs = possiblePath.slice(0, possiblePath.length - 1);
|
|
4947
|
-
import_fs3.default.mkdirSync((0, import_path2.join)(writePath, ...dirs), { recursive: true });
|
|
4948
|
-
}
|
|
4949
|
-
import_fs3.default.writeFileSync((0, import_path2.join)(writePath, ...possiblePath), data);
|
|
4950
|
-
}
|
|
4951
|
-
return writePath;
|
|
4952
|
-
};
|
|
4953
|
-
deleteFile = async (bucketName, filepath) => {
|
|
4954
|
-
const objectStore = ObjectStore(bucketName);
|
|
4955
|
-
await makeSureBucketExists(objectStore, bucketName);
|
|
4956
|
-
const params2 = {
|
|
4957
|
-
Bucket: bucketName,
|
|
4958
|
-
Key: sanitizeKey(filepath)
|
|
4959
|
-
};
|
|
4960
|
-
return objectStore.deleteObject(params2).promise();
|
|
4961
|
-
};
|
|
4962
|
-
deleteFiles = async (bucketName, filepaths) => {
|
|
4963
|
-
const objectStore = ObjectStore(bucketName);
|
|
4964
|
-
await makeSureBucketExists(objectStore, bucketName);
|
|
4965
|
-
const params2 = {
|
|
4966
|
-
Bucket: bucketName,
|
|
4967
|
-
Delete: {
|
|
4968
|
-
Objects: filepaths.map((path2) => ({ Key: sanitizeKey(path2) }))
|
|
4969
|
-
}
|
|
4970
|
-
};
|
|
4971
|
-
return objectStore.deleteObjects(params2).promise();
|
|
4972
|
-
};
|
|
4973
|
-
deleteFolder = async (bucketName, folder) => {
|
|
4974
|
-
bucketName = sanitizeBucket(bucketName);
|
|
4975
|
-
folder = sanitizeKey(folder);
|
|
4976
|
-
const client = ObjectStore(bucketName);
|
|
4977
|
-
const listParams = {
|
|
4978
|
-
Bucket: bucketName,
|
|
4979
|
-
Prefix: folder
|
|
4980
|
-
};
|
|
4981
|
-
const existingObjectsResponse = await client.listObjects(listParams).promise();
|
|
4982
|
-
if (existingObjectsResponse.Contents?.length === 0) {
|
|
4983
|
-
return;
|
|
4984
|
-
}
|
|
4985
|
-
const deleteParams = {
|
|
4986
|
-
Bucket: bucketName,
|
|
4987
|
-
Delete: {
|
|
4988
|
-
Objects: []
|
|
4989
|
-
}
|
|
4990
|
-
};
|
|
4991
|
-
existingObjectsResponse.Contents?.forEach((content) => {
|
|
4992
|
-
deleteParams.Delete.Objects.push({ Key: content.Key });
|
|
4993
|
-
});
|
|
4994
|
-
const deleteResponse = await client.deleteObjects(deleteParams).promise();
|
|
4995
|
-
if (deleteResponse.Deleted?.length === 1e3) {
|
|
4996
|
-
return deleteFolder(bucketName, folder);
|
|
4997
|
-
}
|
|
4998
|
-
};
|
|
4999
|
-
uploadDirectory = async (bucketName, localPath, bucketPath) => {
|
|
5000
|
-
bucketName = sanitizeBucket(bucketName);
|
|
5001
|
-
let uploads = [];
|
|
5002
|
-
const files = import_fs3.default.readdirSync(localPath, { withFileTypes: true });
|
|
5003
|
-
for (let file of files) {
|
|
5004
|
-
const path2 = sanitizeKey((0, import_path2.join)(bucketPath, file.name));
|
|
5005
|
-
const local = (0, import_path2.join)(localPath, file.name);
|
|
5006
|
-
if (file.isDirectory()) {
|
|
5007
|
-
uploads.push(uploadDirectory(bucketName, local, path2));
|
|
5008
|
-
} else {
|
|
5009
|
-
uploads.push(streamUpload(bucketName, path2, import_fs3.default.createReadStream(local)));
|
|
5010
|
-
}
|
|
5011
|
-
}
|
|
5012
|
-
await Promise.all(uploads);
|
|
5013
|
-
return files;
|
|
5014
|
-
};
|
|
5015
|
-
downloadTarballDirect = async (url, path2, headers = {}) => {
|
|
5016
|
-
path2 = sanitizeKey(path2);
|
|
5017
|
-
const response = await (0, import_node_fetch3.default)(url, { headers });
|
|
5018
|
-
if (!response.ok) {
|
|
5019
|
-
throw new Error(`unexpected response ${response.statusText}`);
|
|
5020
|
-
}
|
|
5021
|
-
await streamPipeline(response.body, import_zlib.default.createUnzip(), import_tar_fs.default.extract(path2));
|
|
5022
|
-
};
|
|
5023
|
-
downloadTarball = async (url, bucketName, path2) => {
|
|
5024
|
-
bucketName = sanitizeBucket(bucketName);
|
|
5025
|
-
path2 = sanitizeKey(path2);
|
|
5026
|
-
const response = await (0, import_node_fetch3.default)(url);
|
|
5027
|
-
if (!response.ok) {
|
|
5028
|
-
throw new Error(`unexpected response ${response.statusText}`);
|
|
5029
|
-
}
|
|
5030
|
-
const tmpPath = (0, import_path2.join)(budibaseTempDir(), path2);
|
|
5031
|
-
await streamPipeline(response.body, import_zlib.default.createUnzip(), import_tar_fs.default.extract(tmpPath));
|
|
5032
|
-
if (!environment_default.isTest() && environment_default.SELF_HOSTED) {
|
|
5033
|
-
await uploadDirectory(bucketName, tmpPath, path2);
|
|
5034
|
-
}
|
|
5035
|
-
return tmpPath;
|
|
5036
|
-
};
|
|
5037
5047
|
}
|
|
5038
5048
|
});
|
|
5039
5049
|
|
|
@@ -5079,35 +5089,51 @@ var init_cloudfront = __esm({
|
|
|
5079
5089
|
});
|
|
5080
5090
|
|
|
5081
5091
|
// src/objectStore/buckets/app.ts
|
|
5082
|
-
|
|
5092
|
+
function clientLibraryPath(appId) {
|
|
5093
|
+
return `${sanitizeKey(appId)}/budibase-client.js`;
|
|
5094
|
+
}
|
|
5095
|
+
function clientLibraryCDNUrl(appId, version) {
|
|
5096
|
+
let file = clientLibraryPath(appId);
|
|
5097
|
+
if (environment_default.CLOUDFRONT_CDN) {
|
|
5098
|
+
if (version) {
|
|
5099
|
+
file += `?v=${version}`;
|
|
5100
|
+
}
|
|
5101
|
+
return getUrl(file);
|
|
5102
|
+
} else {
|
|
5103
|
+
return getPresignedUrl(environment_default.APPS_BUCKET_NAME, file);
|
|
5104
|
+
}
|
|
5105
|
+
}
|
|
5106
|
+
function clientLibraryUrl(appId, version) {
|
|
5107
|
+
let tenantId, qsParams;
|
|
5108
|
+
try {
|
|
5109
|
+
tenantId = getTenantId();
|
|
5110
|
+
} finally {
|
|
5111
|
+
qsParams = {
|
|
5112
|
+
appId,
|
|
5113
|
+
version
|
|
5114
|
+
};
|
|
5115
|
+
}
|
|
5116
|
+
if (tenantId && tenantId !== DEFAULT_TENANT_ID) {
|
|
5117
|
+
qsParams.tenantId = tenantId;
|
|
5118
|
+
}
|
|
5119
|
+
return `/api/assets/client?${import_querystring.default.encode(qsParams)}`;
|
|
5120
|
+
}
|
|
5121
|
+
function getAppFileUrl(s3Key) {
|
|
5122
|
+
if (environment_default.CLOUDFRONT_CDN) {
|
|
5123
|
+
return getPresignedUrl2(s3Key);
|
|
5124
|
+
} else {
|
|
5125
|
+
return getPresignedUrl(environment_default.APPS_BUCKET_NAME, s3Key);
|
|
5126
|
+
}
|
|
5127
|
+
}
|
|
5128
|
+
var import_querystring;
|
|
5083
5129
|
var init_app5 = __esm({
|
|
5084
5130
|
"src/objectStore/buckets/app.ts"() {
|
|
5085
5131
|
"use strict";
|
|
5086
5132
|
init_environment2();
|
|
5087
5133
|
init_objectStore();
|
|
5088
5134
|
init_cloudfront();
|
|
5089
|
-
|
|
5090
|
-
|
|
5091
|
-
let file = `${sanitizeKey(appId)}/budibase-client.js`;
|
|
5092
|
-
if (environment_default.CLOUDFRONT_CDN) {
|
|
5093
|
-
if (version) {
|
|
5094
|
-
file += `?v=${version}`;
|
|
5095
|
-
}
|
|
5096
|
-
return getUrl(file);
|
|
5097
|
-
} else {
|
|
5098
|
-
return getPresignedUrl(environment_default.APPS_BUCKET_NAME, file);
|
|
5099
|
-
}
|
|
5100
|
-
} else {
|
|
5101
|
-
return `/api/assets/client`;
|
|
5102
|
-
}
|
|
5103
|
-
};
|
|
5104
|
-
getAppFileUrl = (s3Key) => {
|
|
5105
|
-
if (environment_default.CLOUDFRONT_CDN) {
|
|
5106
|
-
return getPresignedUrl2(s3Key);
|
|
5107
|
-
} else {
|
|
5108
|
-
return getPresignedUrl(environment_default.APPS_BUCKET_NAME, s3Key);
|
|
5109
|
-
}
|
|
5110
|
-
};
|
|
5135
|
+
import_querystring = __toESM(require("querystring"));
|
|
5136
|
+
init_context2();
|
|
5111
5137
|
}
|
|
5112
5138
|
});
|
|
5113
5139
|
|
|
@@ -5143,7 +5169,59 @@ var init_global3 = __esm({
|
|
|
5143
5169
|
});
|
|
5144
5170
|
|
|
5145
5171
|
// src/objectStore/buckets/plugins.ts
|
|
5146
|
-
|
|
5172
|
+
function enrichPluginURLs(plugins) {
|
|
5173
|
+
if (!plugins || !plugins.length) {
|
|
5174
|
+
return [];
|
|
5175
|
+
}
|
|
5176
|
+
return plugins.map((plugin) => {
|
|
5177
|
+
const jsUrl = getPluginJSUrl(plugin);
|
|
5178
|
+
const iconUrl = getPluginIconUrl(plugin);
|
|
5179
|
+
return { ...plugin, jsUrl, iconUrl };
|
|
5180
|
+
});
|
|
5181
|
+
}
|
|
5182
|
+
function getPluginJSUrl(plugin) {
|
|
5183
|
+
const s3Key = getPluginJSKey(plugin);
|
|
5184
|
+
return getPluginUrl(s3Key);
|
|
5185
|
+
}
|
|
5186
|
+
function getPluginIconUrl(plugin) {
|
|
5187
|
+
const s3Key = getPluginIconKey(plugin);
|
|
5188
|
+
if (!s3Key) {
|
|
5189
|
+
return;
|
|
5190
|
+
}
|
|
5191
|
+
return getPluginUrl(s3Key);
|
|
5192
|
+
}
|
|
5193
|
+
function getPluginUrl(s3Key) {
|
|
5194
|
+
if (environment_default.CLOUDFRONT_CDN) {
|
|
5195
|
+
return getPresignedUrl2(s3Key);
|
|
5196
|
+
} else {
|
|
5197
|
+
return getPresignedUrl(environment_default.PLUGIN_BUCKET_NAME, s3Key);
|
|
5198
|
+
}
|
|
5199
|
+
}
|
|
5200
|
+
function getPluginJSKey(plugin) {
|
|
5201
|
+
return getPluginS3Key(plugin, "plugin.min.js");
|
|
5202
|
+
}
|
|
5203
|
+
function getPluginIconKey(plugin) {
|
|
5204
|
+
const iconFileName = plugin.iconUrl ? "icon.svg" : plugin.iconFileName;
|
|
5205
|
+
if (!iconFileName) {
|
|
5206
|
+
return;
|
|
5207
|
+
}
|
|
5208
|
+
return getPluginS3Key(plugin, iconFileName);
|
|
5209
|
+
}
|
|
5210
|
+
function getPluginS3Key(plugin, fileName) {
|
|
5211
|
+
const s3Key = getPluginS3Dir(plugin.name);
|
|
5212
|
+
return `${s3Key}/${fileName}`;
|
|
5213
|
+
}
|
|
5214
|
+
function getPluginS3Dir(pluginName) {
|
|
5215
|
+
let s3Key = `${pluginName}`;
|
|
5216
|
+
if (environment_default.MULTI_TENANCY) {
|
|
5217
|
+
const tenantId = getTenantId();
|
|
5218
|
+
s3Key = `${tenantId}/${s3Key}`;
|
|
5219
|
+
}
|
|
5220
|
+
if (environment_default.CLOUDFRONT_CDN) {
|
|
5221
|
+
s3Key = `plugins/${s3Key}`;
|
|
5222
|
+
}
|
|
5223
|
+
return s3Key;
|
|
5224
|
+
}
|
|
5147
5225
|
var init_plugins = __esm({
|
|
5148
5226
|
"src/objectStore/buckets/plugins.ts"() {
|
|
5149
5227
|
"use strict";
|
|
@@ -5151,59 +5229,6 @@ var init_plugins = __esm({
|
|
|
5151
5229
|
init_objectStore();
|
|
5152
5230
|
init_context2();
|
|
5153
5231
|
init_cloudfront();
|
|
5154
|
-
enrichPluginURLs = (plugins) => {
|
|
5155
|
-
if (!plugins || !plugins.length) {
|
|
5156
|
-
return [];
|
|
5157
|
-
}
|
|
5158
|
-
return plugins.map((plugin) => {
|
|
5159
|
-
const jsUrl = getPluginJSUrl(plugin);
|
|
5160
|
-
const iconUrl = getPluginIconUrl(plugin);
|
|
5161
|
-
return { ...plugin, jsUrl, iconUrl };
|
|
5162
|
-
});
|
|
5163
|
-
};
|
|
5164
|
-
getPluginJSUrl = (plugin) => {
|
|
5165
|
-
const s3Key = getPluginJSKey(plugin);
|
|
5166
|
-
return getPluginUrl(s3Key);
|
|
5167
|
-
};
|
|
5168
|
-
getPluginIconUrl = (plugin) => {
|
|
5169
|
-
const s3Key = getPluginIconKey(plugin);
|
|
5170
|
-
if (!s3Key) {
|
|
5171
|
-
return;
|
|
5172
|
-
}
|
|
5173
|
-
return getPluginUrl(s3Key);
|
|
5174
|
-
};
|
|
5175
|
-
getPluginUrl = (s3Key) => {
|
|
5176
|
-
if (environment_default.CLOUDFRONT_CDN) {
|
|
5177
|
-
return getPresignedUrl2(s3Key);
|
|
5178
|
-
} else {
|
|
5179
|
-
return getPresignedUrl(environment_default.PLUGIN_BUCKET_NAME, s3Key);
|
|
5180
|
-
}
|
|
5181
|
-
};
|
|
5182
|
-
getPluginJSKey = (plugin) => {
|
|
5183
|
-
return getPluginS3Key(plugin, "plugin.min.js");
|
|
5184
|
-
};
|
|
5185
|
-
getPluginIconKey = (plugin) => {
|
|
5186
|
-
const iconFileName = plugin.iconUrl ? "icon.svg" : plugin.iconFileName;
|
|
5187
|
-
if (!iconFileName) {
|
|
5188
|
-
return;
|
|
5189
|
-
}
|
|
5190
|
-
return getPluginS3Key(plugin, iconFileName);
|
|
5191
|
-
};
|
|
5192
|
-
getPluginS3Key = (plugin, fileName) => {
|
|
5193
|
-
const s3Key = getPluginS3Dir(plugin.name);
|
|
5194
|
-
return `${s3Key}/${fileName}`;
|
|
5195
|
-
};
|
|
5196
|
-
getPluginS3Dir = (pluginName) => {
|
|
5197
|
-
let s3Key = `${pluginName}`;
|
|
5198
|
-
if (environment_default.MULTI_TENANCY) {
|
|
5199
|
-
const tenantId = getTenantId();
|
|
5200
|
-
s3Key = `${tenantId}/${s3Key}`;
|
|
5201
|
-
}
|
|
5202
|
-
if (environment_default.CLOUDFRONT_CDN) {
|
|
5203
|
-
s3Key = `plugins/${s3Key}`;
|
|
5204
|
-
}
|
|
5205
|
-
return s3Key;
|
|
5206
|
-
};
|
|
5207
5232
|
}
|
|
5208
5233
|
});
|
|
5209
5234
|
|
|
@@ -5223,6 +5248,8 @@ __export(objectStore_exports2, {
|
|
|
5223
5248
|
ObjectStore: () => ObjectStore,
|
|
5224
5249
|
ObjectStoreBuckets: () => ObjectStoreBuckets,
|
|
5225
5250
|
budibaseTempDir: () => budibaseTempDir,
|
|
5251
|
+
clientLibraryCDNUrl: () => clientLibraryCDNUrl,
|
|
5252
|
+
clientLibraryPath: () => clientLibraryPath,
|
|
5226
5253
|
clientLibraryUrl: () => clientLibraryUrl,
|
|
5227
5254
|
deleteFile: () => deleteFile,
|
|
5228
5255
|
deleteFiles: () => deleteFiles,
|
|
@@ -5237,6 +5264,7 @@ __export(objectStore_exports2, {
|
|
|
5237
5264
|
getPluginJSKey: () => getPluginJSKey,
|
|
5238
5265
|
getPluginS3Dir: () => getPluginS3Dir,
|
|
5239
5266
|
getPresignedUrl: () => getPresignedUrl,
|
|
5267
|
+
getReadStream: () => getReadStream,
|
|
5240
5268
|
listAllObjects: () => listAllObjects,
|
|
5241
5269
|
makeSureBucketExists: () => makeSureBucketExists,
|
|
5242
5270
|
retrieve: () => retrieve,
|
|
@@ -6254,6 +6282,7 @@ __export(users_exports3, {
|
|
|
6254
6282
|
getAccountHolderFromUserIds: () => getAccountHolderFromUserIds,
|
|
6255
6283
|
getAllUserIds: () => getAllUserIds,
|
|
6256
6284
|
getById: () => getById,
|
|
6285
|
+
getCreatorCount: () => getCreatorCount,
|
|
6257
6286
|
getExistingAccounts: () => getExistingAccounts,
|
|
6258
6287
|
getExistingPlatformUsers: () => getExistingPlatformUsers,
|
|
6259
6288
|
getExistingTenantUsers: () => getExistingTenantUsers,
|
|
@@ -6267,6 +6296,7 @@ __export(users_exports3, {
|
|
|
6267
6296
|
isAdmin: () => isAdmin2,
|
|
6268
6297
|
isAdminOrBuilder: () => isAdminOrBuilder2,
|
|
6269
6298
|
isBuilder: () => isBuilder2,
|
|
6299
|
+
isCreator: () => isCreator2,
|
|
6270
6300
|
isGlobalBuilder: () => isGlobalBuilder2,
|
|
6271
6301
|
isSupportedUserSearch: () => isSupportedUserSearch,
|
|
6272
6302
|
paginatedUsers: () => paginatedUsers,
|
|
@@ -6283,240 +6313,22 @@ init_db4();
|
|
|
6283
6313
|
init_src();
|
|
6284
6314
|
init_context2();
|
|
6285
6315
|
init_context2();
|
|
6286
|
-
|
|
6287
|
-
|
|
6288
|
-
|
|
6289
|
-
|
|
6290
|
-
|
|
6291
|
-
|
|
6292
|
-
|
|
6293
|
-
|
|
6294
|
-
|
|
6295
|
-
|
|
6296
|
-
|
|
6297
|
-
|
|
6298
|
-
|
|
6299
|
-
|
|
6300
|
-
|
|
6301
|
-
|
|
6302
|
-
{ op: "string" /* STRING */, key: "email" },
|
|
6303
|
-
{ op: "equal" /* EQUAL */, key: "_id" }
|
|
6304
|
-
];
|
|
6305
|
-
for (let [key, operation] of Object.entries(query)) {
|
|
6306
|
-
if (typeof operation !== "object") {
|
|
6307
|
-
return false;
|
|
6308
|
-
}
|
|
6309
|
-
const fields = Object.keys(operation || {});
|
|
6310
|
-
if (fields.length === 0) {
|
|
6311
|
-
continue;
|
|
6312
|
-
}
|
|
6313
|
-
const allowedOperation = allowed.find(
|
|
6314
|
-
(allow) => allow.op === key && fields.length === 1 && fields[0] === allow.key
|
|
6315
|
-
);
|
|
6316
|
-
if (!allowedOperation) {
|
|
6317
|
-
return false;
|
|
6318
|
-
}
|
|
6319
|
-
}
|
|
6320
|
-
return true;
|
|
6321
|
-
};
|
|
6322
|
-
var bulkGetGlobalUsersById = async (userIds, opts) => {
|
|
6323
|
-
const db = getGlobalDB();
|
|
6324
|
-
let users = (await db.allDocs({
|
|
6325
|
-
keys: userIds,
|
|
6326
|
-
include_docs: true
|
|
6327
|
-
})).rows.map((row) => row.doc);
|
|
6328
|
-
if (opts?.cleanup) {
|
|
6329
|
-
users = removeUserPassword(users);
|
|
6330
|
-
}
|
|
6331
|
-
return users;
|
|
6332
|
-
};
|
|
6333
|
-
var getAllUserIds = async () => {
|
|
6334
|
-
const db = getGlobalDB();
|
|
6335
|
-
const startKey = `${"us" /* USER */}${SEPARATOR}`;
|
|
6336
|
-
const response = await db.allDocs({
|
|
6337
|
-
startkey: startKey,
|
|
6338
|
-
endkey: `${startKey}${UNICODE_MAX}`
|
|
6339
|
-
});
|
|
6340
|
-
return response.rows.map((row) => row.id);
|
|
6341
|
-
};
|
|
6342
|
-
var bulkUpdateGlobalUsers = async (users) => {
|
|
6343
|
-
const db = getGlobalDB();
|
|
6344
|
-
return await db.bulkDocs(users);
|
|
6345
|
-
};
|
|
6346
|
-
async function getById(id, opts) {
|
|
6347
|
-
const db = getGlobalDB();
|
|
6348
|
-
let user = await db.get(id);
|
|
6349
|
-
if (opts?.cleanup) {
|
|
6350
|
-
user = removeUserPassword(user);
|
|
6351
|
-
}
|
|
6352
|
-
return user;
|
|
6353
|
-
}
|
|
6354
|
-
var getGlobalUserByEmail = async (email, opts) => {
|
|
6355
|
-
if (email == null) {
|
|
6356
|
-
throw "Must supply an email address to view";
|
|
6357
|
-
}
|
|
6358
|
-
const response = await queryGlobalView("by_email2" /* USER_BY_EMAIL */, {
|
|
6359
|
-
key: email.toLowerCase(),
|
|
6360
|
-
include_docs: true
|
|
6361
|
-
});
|
|
6362
|
-
if (Array.isArray(response)) {
|
|
6363
|
-
throw new Error(`Multiple users found with email address: ${email}`);
|
|
6364
|
-
}
|
|
6365
|
-
let user = response;
|
|
6366
|
-
if (opts?.cleanup) {
|
|
6367
|
-
user = removeUserPassword(user);
|
|
6368
|
-
}
|
|
6369
|
-
return user;
|
|
6370
|
-
};
|
|
6371
|
-
var searchGlobalUsersByApp = async (appId, opts, getOpts) => {
|
|
6372
|
-
if (typeof appId !== "string") {
|
|
6373
|
-
throw new Error("Must provide a string based app ID");
|
|
6374
|
-
}
|
|
6375
|
-
const params2 = getUsersByAppParams(appId, {
|
|
6376
|
-
include_docs: true
|
|
6377
|
-
});
|
|
6378
|
-
params2.startkey = opts && opts.startkey ? opts.startkey : params2.startkey;
|
|
6379
|
-
let response = await queryGlobalView("by_app" /* USER_BY_APP */, params2);
|
|
6380
|
-
if (!response) {
|
|
6381
|
-
response = [];
|
|
6382
|
-
}
|
|
6383
|
-
let users = Array.isArray(response) ? response : [response];
|
|
6384
|
-
if (getOpts?.cleanup) {
|
|
6385
|
-
users = removeUserPassword(users);
|
|
6386
|
-
}
|
|
6387
|
-
return users;
|
|
6388
|
-
};
|
|
6389
|
-
var searchGlobalUsersByAppAccess = async (appId, opts) => {
|
|
6390
|
-
const roleSelector = `roles.${appId}`;
|
|
6391
|
-
let orQuery = [
|
|
6392
|
-
{
|
|
6393
|
-
"builder.global": true
|
|
6394
|
-
},
|
|
6395
|
-
{
|
|
6396
|
-
"admin.global": true
|
|
6397
|
-
}
|
|
6398
|
-
];
|
|
6399
|
-
if (appId) {
|
|
6400
|
-
const roleCheck = {
|
|
6401
|
-
[roleSelector]: {
|
|
6402
|
-
$exists: true
|
|
6403
|
-
}
|
|
6404
|
-
};
|
|
6405
|
-
orQuery.push(roleCheck);
|
|
6406
|
-
}
|
|
6407
|
-
let searchOptions = {
|
|
6408
|
-
selector: {
|
|
6409
|
-
$or: orQuery,
|
|
6410
|
-
_id: {
|
|
6411
|
-
$regex: "^us_"
|
|
6412
|
-
}
|
|
6413
|
-
},
|
|
6414
|
-
limit: opts?.limit || 50
|
|
6415
|
-
};
|
|
6416
|
-
const resp = await directCouchFind(getGlobalDBName(), searchOptions);
|
|
6417
|
-
return resp?.rows;
|
|
6418
|
-
};
|
|
6419
|
-
var getGlobalUserByAppPage = (appId, user) => {
|
|
6420
|
-
if (!user) {
|
|
6421
|
-
return;
|
|
6422
|
-
}
|
|
6423
|
-
return generateAppUserID(getProdAppID(appId), user._id);
|
|
6424
|
-
};
|
|
6425
|
-
var searchGlobalUsersByEmail = async (email, opts, getOpts) => {
|
|
6426
|
-
if (typeof email !== "string") {
|
|
6427
|
-
throw new Error("Must provide a string to search by");
|
|
6428
|
-
}
|
|
6429
|
-
const lcEmail = email.toLowerCase();
|
|
6430
|
-
const startkey = opts && opts.startkey ? opts.startkey : lcEmail;
|
|
6431
|
-
let response = await queryGlobalView("by_email2" /* USER_BY_EMAIL */, {
|
|
6432
|
-
...opts,
|
|
6433
|
-
startkey,
|
|
6434
|
-
endkey: `${lcEmail}${UNICODE_MAX}`
|
|
6435
|
-
});
|
|
6436
|
-
if (!response) {
|
|
6437
|
-
response = [];
|
|
6438
|
-
}
|
|
6439
|
-
let users = Array.isArray(response) ? response : [response];
|
|
6440
|
-
if (getOpts?.cleanup) {
|
|
6441
|
-
users = removeUserPassword(users);
|
|
6442
|
-
}
|
|
6443
|
-
return users;
|
|
6444
|
-
};
|
|
6445
|
-
var PAGE_LIMIT = 8;
|
|
6446
|
-
var paginatedUsers = async ({
|
|
6447
|
-
bookmark,
|
|
6448
|
-
query,
|
|
6449
|
-
appId,
|
|
6450
|
-
limit
|
|
6451
|
-
} = {}) => {
|
|
6452
|
-
const db = getGlobalDB();
|
|
6453
|
-
const pageLimit = limit ? limit + 1 : PAGE_LIMIT + 1;
|
|
6454
|
-
const opts = {
|
|
6455
|
-
include_docs: true,
|
|
6456
|
-
limit: pageLimit
|
|
6457
|
-
};
|
|
6458
|
-
if (bookmark) {
|
|
6459
|
-
opts.startkey = bookmark;
|
|
6460
|
-
}
|
|
6461
|
-
let userList, property = "_id", getKey;
|
|
6462
|
-
if (query?.equal?._id) {
|
|
6463
|
-
userList = [await getById(query.equal._id)];
|
|
6464
|
-
} else if (appId) {
|
|
6465
|
-
userList = await searchGlobalUsersByApp(appId, opts);
|
|
6466
|
-
getKey = (doc) => getGlobalUserByAppPage(appId, doc);
|
|
6467
|
-
} else if (query?.string?.email) {
|
|
6468
|
-
userList = await searchGlobalUsersByEmail(query?.string?.email, opts);
|
|
6469
|
-
property = "email";
|
|
6470
|
-
} else {
|
|
6471
|
-
const response = await db.allDocs(getGlobalUserParams(null, opts));
|
|
6472
|
-
userList = response.rows.map((row) => row.doc);
|
|
6473
|
-
}
|
|
6474
|
-
return pagination(userList, pageLimit, {
|
|
6475
|
-
paginate: true,
|
|
6476
|
-
property,
|
|
6477
|
-
getKey
|
|
6478
|
-
});
|
|
6479
|
-
};
|
|
6480
|
-
async function getUserCount() {
|
|
6481
|
-
const response = await queryGlobalViewRaw("by_email2" /* USER_BY_EMAIL */, {
|
|
6482
|
-
limit: 0,
|
|
6483
|
-
// to be as fast as possible - we just want the total rows count
|
|
6484
|
-
include_docs: false
|
|
6485
|
-
});
|
|
6486
|
-
return response.total_rows;
|
|
6487
|
-
}
|
|
6488
|
-
function removePortalUserPermissions(user) {
|
|
6489
|
-
delete user.admin;
|
|
6490
|
-
delete user.builder;
|
|
6491
|
-
return user;
|
|
6492
|
-
}
|
|
6493
|
-
function cleanseUserObject(user, base) {
|
|
6494
|
-
delete user.admin;
|
|
6495
|
-
delete user.builder;
|
|
6496
|
-
delete user.roles;
|
|
6497
|
-
if (base) {
|
|
6498
|
-
user.admin = base.admin;
|
|
6499
|
-
user.builder = base.builder;
|
|
6500
|
-
user.roles = base.roles;
|
|
6501
|
-
}
|
|
6502
|
-
return user;
|
|
6503
|
-
}
|
|
6504
|
-
|
|
6505
|
-
// src/users/utils.ts
|
|
6506
|
-
init_environment2();
|
|
6507
|
-
|
|
6508
|
-
// src/users/lookup.ts
|
|
6509
|
-
init_db4();
|
|
6510
|
-
init_constants3();
|
|
6511
|
-
async function searchExistingEmails(emails) {
|
|
6512
|
-
let matchedEmails = [];
|
|
6513
|
-
const existingTenantUsers = await getExistingTenantUsers(emails);
|
|
6514
|
-
matchedEmails.push(...existingTenantUsers.map((user) => user.email));
|
|
6515
|
-
const existingPlatformUsers = await getExistingPlatformUsers(emails);
|
|
6516
|
-
matchedEmails.push(...existingPlatformUsers.map((user) => user._id));
|
|
6517
|
-
const existingAccounts = await getExistingAccounts(emails);
|
|
6518
|
-
matchedEmails.push(...existingAccounts.map((account) => account.email));
|
|
6519
|
-
return [...new Set(matchedEmails.map((email) => email.toLowerCase()))];
|
|
6316
|
+
|
|
6317
|
+
// src/users/utils.ts
|
|
6318
|
+
init_environment2();
|
|
6319
|
+
|
|
6320
|
+
// src/users/lookup.ts
|
|
6321
|
+
init_db4();
|
|
6322
|
+
init_constants3();
|
|
6323
|
+
async function searchExistingEmails(emails) {
|
|
6324
|
+
let matchedEmails = [];
|
|
6325
|
+
const existingTenantUsers = await getExistingTenantUsers(emails);
|
|
6326
|
+
matchedEmails.push(...existingTenantUsers.map((user) => user.email));
|
|
6327
|
+
const existingPlatformUsers = await getExistingPlatformUsers(emails);
|
|
6328
|
+
matchedEmails.push(...existingPlatformUsers.map((user) => user._id));
|
|
6329
|
+
const existingAccounts = await getExistingAccounts(emails);
|
|
6330
|
+
matchedEmails.push(...existingAccounts.map((account) => account.email));
|
|
6331
|
+
return [...new Set(matchedEmails.map((email) => email.toLowerCase()))];
|
|
6520
6332
|
}
|
|
6521
6333
|
async function getPlatformUser(identifier) {
|
|
6522
6334
|
return await queryPlatformView("platform_users_lowercase_2" /* PLATFORM_USERS_LOWERCASE */, {
|
|
@@ -6787,14 +6599,17 @@ __export(users_exports2, {
|
|
|
6787
6599
|
getGlobalUserID: () => getGlobalUserID,
|
|
6788
6600
|
hasAdminPermissions: () => hasAdminPermissions,
|
|
6789
6601
|
hasAppBuilderPermissions: () => hasAppBuilderPermissions,
|
|
6602
|
+
hasAppCreatorPermissions: () => hasAppCreatorPermissions,
|
|
6790
6603
|
hasBuilderPermissions: () => hasBuilderPermissions,
|
|
6791
6604
|
isAdmin: () => isAdmin,
|
|
6792
6605
|
isAdminOrBuilder: () => isAdminOrBuilder,
|
|
6793
6606
|
isAdminOrGlobalBuilder: () => isAdminOrGlobalBuilder,
|
|
6794
6607
|
isBuilder: () => isBuilder,
|
|
6608
|
+
isCreator: () => isCreator,
|
|
6795
6609
|
isGlobalBuilder: () => isGlobalBuilder
|
|
6796
6610
|
});
|
|
6797
6611
|
init_src();
|
|
6612
|
+
var _ = __toESM(require("lodash/fp"));
|
|
6798
6613
|
function isBuilder(user, appId) {
|
|
6799
6614
|
if (!user) {
|
|
6800
6615
|
return false;
|
|
@@ -6829,6 +6644,17 @@ function hasAppBuilderPermissions(user) {
|
|
|
6829
6644
|
const isGlobalBuilder3 = !!user.builder?.global;
|
|
6830
6645
|
return !isGlobalBuilder3 && appLength != null && appLength > 0;
|
|
6831
6646
|
}
|
|
6647
|
+
function hasAppCreatorPermissions(user) {
|
|
6648
|
+
if (!user) {
|
|
6649
|
+
return false;
|
|
6650
|
+
}
|
|
6651
|
+
return _.flow(
|
|
6652
|
+
_.get("roles"),
|
|
6653
|
+
_.values,
|
|
6654
|
+
_.find((x) => ["CREATOR", "ADMIN"].includes(x)),
|
|
6655
|
+
(x) => !!x
|
|
6656
|
+
)(user);
|
|
6657
|
+
}
|
|
6832
6658
|
function hasBuilderPermissions(user) {
|
|
6833
6659
|
if (!user) {
|
|
6834
6660
|
return false;
|
|
@@ -6841,6 +6667,12 @@ function hasAdminPermissions(user) {
|
|
|
6841
6667
|
}
|
|
6842
6668
|
return !!user.admin?.global;
|
|
6843
6669
|
}
|
|
6670
|
+
function isCreator(user) {
|
|
6671
|
+
if (!user) {
|
|
6672
|
+
return false;
|
|
6673
|
+
}
|
|
6674
|
+
return isGlobalBuilder(user) || hasAdminPermissions(user) || hasAppBuilderPermissions(user) || hasAppCreatorPermissions(user);
|
|
6675
|
+
}
|
|
6844
6676
|
function getGlobalUserID(userId) {
|
|
6845
6677
|
if (typeof userId !== "string") {
|
|
6846
6678
|
return userId;
|
|
@@ -6900,6 +6732,7 @@ var allowSortColumnByType = {
|
|
|
6900
6732
|
// src/users/utils.ts
|
|
6901
6733
|
var isBuilder2 = sdk_exports.users.isBuilder;
|
|
6902
6734
|
var isAdmin2 = sdk_exports.users.isAdmin;
|
|
6735
|
+
var isCreator2 = sdk_exports.users.isCreator;
|
|
6903
6736
|
var isGlobalBuilder2 = sdk_exports.users.isGlobalBuilder;
|
|
6904
6737
|
var isAdminOrBuilder2 = sdk_exports.users.isAdminOrBuilder;
|
|
6905
6738
|
var hasAdminPermissions2 = sdk_exports.users.hasAdminPermissions;
|
|
@@ -6933,6 +6766,238 @@ async function getAccountHolderFromUserIds(userIds) {
|
|
|
6933
6766
|
}
|
|
6934
6767
|
}
|
|
6935
6768
|
|
|
6769
|
+
// src/users/users.ts
|
|
6770
|
+
function removeUserPassword(users) {
|
|
6771
|
+
if (Array.isArray(users)) {
|
|
6772
|
+
return users.map((user) => {
|
|
6773
|
+
if (user) {
|
|
6774
|
+
delete user.password;
|
|
6775
|
+
return user;
|
|
6776
|
+
}
|
|
6777
|
+
});
|
|
6778
|
+
} else if (users) {
|
|
6779
|
+
delete users.password;
|
|
6780
|
+
return users;
|
|
6781
|
+
}
|
|
6782
|
+
return users;
|
|
6783
|
+
}
|
|
6784
|
+
var isSupportedUserSearch = (query) => {
|
|
6785
|
+
const allowed = [
|
|
6786
|
+
{ op: "string" /* STRING */, key: "email" },
|
|
6787
|
+
{ op: "equal" /* EQUAL */, key: "_id" }
|
|
6788
|
+
];
|
|
6789
|
+
for (let [key, operation] of Object.entries(query)) {
|
|
6790
|
+
if (typeof operation !== "object") {
|
|
6791
|
+
return false;
|
|
6792
|
+
}
|
|
6793
|
+
const fields = Object.keys(operation || {});
|
|
6794
|
+
if (fields.length === 0) {
|
|
6795
|
+
continue;
|
|
6796
|
+
}
|
|
6797
|
+
const allowedOperation = allowed.find(
|
|
6798
|
+
(allow) => allow.op === key && fields.length === 1 && fields[0] === allow.key
|
|
6799
|
+
);
|
|
6800
|
+
if (!allowedOperation) {
|
|
6801
|
+
return false;
|
|
6802
|
+
}
|
|
6803
|
+
}
|
|
6804
|
+
return true;
|
|
6805
|
+
};
|
|
6806
|
+
var bulkGetGlobalUsersById = async (userIds, opts) => {
|
|
6807
|
+
const db = getGlobalDB();
|
|
6808
|
+
let users = (await db.allDocs({
|
|
6809
|
+
keys: userIds,
|
|
6810
|
+
include_docs: true
|
|
6811
|
+
})).rows.map((row) => row.doc);
|
|
6812
|
+
if (opts?.cleanup) {
|
|
6813
|
+
users = removeUserPassword(users);
|
|
6814
|
+
}
|
|
6815
|
+
return users;
|
|
6816
|
+
};
|
|
6817
|
+
var getAllUserIds = async () => {
|
|
6818
|
+
const db = getGlobalDB();
|
|
6819
|
+
const startKey = `${"us" /* USER */}${SEPARATOR}`;
|
|
6820
|
+
const response = await db.allDocs({
|
|
6821
|
+
startkey: startKey,
|
|
6822
|
+
endkey: `${startKey}${UNICODE_MAX}`
|
|
6823
|
+
});
|
|
6824
|
+
return response.rows.map((row) => row.id);
|
|
6825
|
+
};
|
|
6826
|
+
var bulkUpdateGlobalUsers = async (users) => {
|
|
6827
|
+
const db = getGlobalDB();
|
|
6828
|
+
return await db.bulkDocs(users);
|
|
6829
|
+
};
|
|
6830
|
+
async function getById(id, opts) {
|
|
6831
|
+
const db = getGlobalDB();
|
|
6832
|
+
let user = await db.get(id);
|
|
6833
|
+
if (opts?.cleanup) {
|
|
6834
|
+
user = removeUserPassword(user);
|
|
6835
|
+
}
|
|
6836
|
+
return user;
|
|
6837
|
+
}
|
|
6838
|
+
var getGlobalUserByEmail = async (email, opts) => {
|
|
6839
|
+
if (email == null) {
|
|
6840
|
+
throw "Must supply an email address to view";
|
|
6841
|
+
}
|
|
6842
|
+
const response = await queryGlobalView("by_email2" /* USER_BY_EMAIL */, {
|
|
6843
|
+
key: email.toLowerCase(),
|
|
6844
|
+
include_docs: true
|
|
6845
|
+
});
|
|
6846
|
+
if (Array.isArray(response)) {
|
|
6847
|
+
throw new Error(`Multiple users found with email address: ${email}`);
|
|
6848
|
+
}
|
|
6849
|
+
let user = response;
|
|
6850
|
+
if (opts?.cleanup) {
|
|
6851
|
+
user = removeUserPassword(user);
|
|
6852
|
+
}
|
|
6853
|
+
return user;
|
|
6854
|
+
};
|
|
6855
|
+
var searchGlobalUsersByApp = async (appId, opts, getOpts) => {
|
|
6856
|
+
if (typeof appId !== "string") {
|
|
6857
|
+
throw new Error("Must provide a string based app ID");
|
|
6858
|
+
}
|
|
6859
|
+
const params2 = getUsersByAppParams(appId, {
|
|
6860
|
+
include_docs: true
|
|
6861
|
+
});
|
|
6862
|
+
params2.startkey = opts && opts.startkey ? opts.startkey : params2.startkey;
|
|
6863
|
+
let response = await queryGlobalView("by_app" /* USER_BY_APP */, params2);
|
|
6864
|
+
if (!response) {
|
|
6865
|
+
response = [];
|
|
6866
|
+
}
|
|
6867
|
+
let users = Array.isArray(response) ? response : [response];
|
|
6868
|
+
if (getOpts?.cleanup) {
|
|
6869
|
+
users = removeUserPassword(users);
|
|
6870
|
+
}
|
|
6871
|
+
return users;
|
|
6872
|
+
};
|
|
6873
|
+
var searchGlobalUsersByAppAccess = async (appId, opts) => {
|
|
6874
|
+
const roleSelector = `roles.${appId}`;
|
|
6875
|
+
let orQuery = [
|
|
6876
|
+
{
|
|
6877
|
+
"builder.global": true
|
|
6878
|
+
},
|
|
6879
|
+
{
|
|
6880
|
+
"admin.global": true
|
|
6881
|
+
}
|
|
6882
|
+
];
|
|
6883
|
+
if (appId) {
|
|
6884
|
+
const roleCheck = {
|
|
6885
|
+
[roleSelector]: {
|
|
6886
|
+
$exists: true
|
|
6887
|
+
}
|
|
6888
|
+
};
|
|
6889
|
+
orQuery.push(roleCheck);
|
|
6890
|
+
}
|
|
6891
|
+
let searchOptions = {
|
|
6892
|
+
selector: {
|
|
6893
|
+
$or: orQuery,
|
|
6894
|
+
_id: {
|
|
6895
|
+
$regex: "^us_"
|
|
6896
|
+
}
|
|
6897
|
+
},
|
|
6898
|
+
limit: opts?.limit || 50
|
|
6899
|
+
};
|
|
6900
|
+
const resp = await directCouchFind(getGlobalDBName(), searchOptions);
|
|
6901
|
+
return resp?.rows;
|
|
6902
|
+
};
|
|
6903
|
+
var getGlobalUserByAppPage = (appId, user) => {
|
|
6904
|
+
if (!user) {
|
|
6905
|
+
return;
|
|
6906
|
+
}
|
|
6907
|
+
return generateAppUserID(getProdAppID(appId), user._id);
|
|
6908
|
+
};
|
|
6909
|
+
var searchGlobalUsersByEmail = async (email, opts, getOpts) => {
|
|
6910
|
+
if (typeof email !== "string") {
|
|
6911
|
+
throw new Error("Must provide a string to search by");
|
|
6912
|
+
}
|
|
6913
|
+
const lcEmail = email.toLowerCase();
|
|
6914
|
+
const startkey = opts && opts.startkey ? opts.startkey : lcEmail;
|
|
6915
|
+
let response = await queryGlobalView("by_email2" /* USER_BY_EMAIL */, {
|
|
6916
|
+
...opts,
|
|
6917
|
+
startkey,
|
|
6918
|
+
endkey: `${lcEmail}${UNICODE_MAX}`
|
|
6919
|
+
});
|
|
6920
|
+
if (!response) {
|
|
6921
|
+
response = [];
|
|
6922
|
+
}
|
|
6923
|
+
let users = Array.isArray(response) ? response : [response];
|
|
6924
|
+
if (getOpts?.cleanup) {
|
|
6925
|
+
users = removeUserPassword(users);
|
|
6926
|
+
}
|
|
6927
|
+
return users;
|
|
6928
|
+
};
|
|
6929
|
+
var PAGE_LIMIT = 8;
|
|
6930
|
+
var paginatedUsers = async ({
|
|
6931
|
+
bookmark,
|
|
6932
|
+
query,
|
|
6933
|
+
appId,
|
|
6934
|
+
limit
|
|
6935
|
+
} = {}) => {
|
|
6936
|
+
const db = getGlobalDB();
|
|
6937
|
+
const pageLimit = limit ? limit + 1 : PAGE_LIMIT + 1;
|
|
6938
|
+
const opts = {
|
|
6939
|
+
include_docs: true,
|
|
6940
|
+
limit: pageLimit
|
|
6941
|
+
};
|
|
6942
|
+
if (bookmark) {
|
|
6943
|
+
opts.startkey = bookmark;
|
|
6944
|
+
}
|
|
6945
|
+
let userList, property = "_id", getKey;
|
|
6946
|
+
if (query?.equal?._id) {
|
|
6947
|
+
userList = [await getById(query.equal._id)];
|
|
6948
|
+
} else if (appId) {
|
|
6949
|
+
userList = await searchGlobalUsersByApp(appId, opts);
|
|
6950
|
+
getKey = (doc) => getGlobalUserByAppPage(appId, doc);
|
|
6951
|
+
} else if (query?.string?.email) {
|
|
6952
|
+
userList = await searchGlobalUsersByEmail(query?.string?.email, opts);
|
|
6953
|
+
property = "email";
|
|
6954
|
+
} else {
|
|
6955
|
+
const response = await db.allDocs(getGlobalUserParams(null, opts));
|
|
6956
|
+
userList = response.rows.map((row) => row.doc);
|
|
6957
|
+
}
|
|
6958
|
+
return pagination(userList, pageLimit, {
|
|
6959
|
+
paginate: true,
|
|
6960
|
+
property,
|
|
6961
|
+
getKey
|
|
6962
|
+
});
|
|
6963
|
+
};
|
|
6964
|
+
async function getUserCount() {
|
|
6965
|
+
const response = await queryGlobalViewRaw("by_email2" /* USER_BY_EMAIL */, {
|
|
6966
|
+
limit: 0,
|
|
6967
|
+
// to be as fast as possible - we just want the total rows count
|
|
6968
|
+
include_docs: false
|
|
6969
|
+
});
|
|
6970
|
+
return response.total_rows;
|
|
6971
|
+
}
|
|
6972
|
+
async function getCreatorCount() {
|
|
6973
|
+
let creators = 0;
|
|
6974
|
+
async function iterate(startPage) {
|
|
6975
|
+
const page = await paginatedUsers({ bookmark: startPage });
|
|
6976
|
+
creators += page.data.filter(isCreator2).length;
|
|
6977
|
+
if (page.hasNextPage) {
|
|
6978
|
+
await iterate(page.nextPage);
|
|
6979
|
+
}
|
|
6980
|
+
}
|
|
6981
|
+
await iterate();
|
|
6982
|
+
return creators;
|
|
6983
|
+
}
|
|
6984
|
+
function removePortalUserPermissions(user) {
|
|
6985
|
+
delete user.admin;
|
|
6986
|
+
delete user.builder;
|
|
6987
|
+
return user;
|
|
6988
|
+
}
|
|
6989
|
+
function cleanseUserObject(user, base) {
|
|
6990
|
+
delete user.admin;
|
|
6991
|
+
delete user.builder;
|
|
6992
|
+
delete user.roles;
|
|
6993
|
+
if (base) {
|
|
6994
|
+
user.admin = base.admin;
|
|
6995
|
+
user.builder = base.builder;
|
|
6996
|
+
user.roles = base.roles;
|
|
6997
|
+
}
|
|
6998
|
+
return user;
|
|
6999
|
+
}
|
|
7000
|
+
|
|
6936
7001
|
// src/users/db.ts
|
|
6937
7002
|
init_environment2();
|
|
6938
7003
|
|
|
@@ -10267,7 +10332,7 @@ async function put(db, doc, writeRateMs = DEFAULT_WRITE_RATE_MS) {
|
|
|
10267
10332
|
}
|
|
10268
10333
|
return { ok: true, id: output._id, rev: output._rev };
|
|
10269
10334
|
}
|
|
10270
|
-
async function
|
|
10335
|
+
async function get3(db, id) {
|
|
10271
10336
|
const cache = await getCache();
|
|
10272
10337
|
const cacheKey = makeCacheKey(db, id);
|
|
10273
10338
|
let cacheItem = await cache.get(cacheKey);
|
|
@@ -10300,7 +10365,7 @@ var Writethrough = class {
|
|
|
10300
10365
|
return put(this.db, doc, this.writeRateMs);
|
|
10301
10366
|
}
|
|
10302
10367
|
async get(id) {
|
|
10303
|
-
return
|
|
10368
|
+
return get3(this.db, id);
|
|
10304
10369
|
}
|
|
10305
10370
|
async remove(docOrId, rev) {
|
|
10306
10371
|
return remove(this.db, docOrId, rev);
|
|
@@ -10619,7 +10684,7 @@ var DEFINITIONS = [
|
|
|
10619
10684
|
},
|
|
10620
10685
|
{
|
|
10621
10686
|
type: "global" /* GLOBAL */,
|
|
10622
|
-
name: "
|
|
10687
|
+
name: "sync_quotas_2" /* SYNC_QUOTAS */
|
|
10623
10688
|
},
|
|
10624
10689
|
{
|
|
10625
10690
|
type: "app" /* APP */,
|