@budibase/backend-core 2.11.37 → 2.11.39

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.
Files changed (92) hide show
  1. package/dist/index.js +324 -276
  2. package/dist/index.js.map +3 -3
  3. package/dist/index.js.meta.json +1 -1
  4. package/dist/package.json +4 -4
  5. package/dist/plugins.js.map +1 -1
  6. package/dist/plugins.js.meta.json +1 -1
  7. package/dist/src/cache/appMetadata.d.ts +5 -5
  8. package/dist/src/cache/appMetadata.js +5 -5
  9. package/dist/src/cache/user.d.ts +5 -5
  10. package/dist/src/cache/user.js +5 -5
  11. package/dist/src/cache/writethrough.d.ts +1 -1
  12. package/dist/src/cache/writethrough.js +2 -2
  13. package/dist/src/cache/writethrough.js.map +1 -1
  14. package/dist/src/configs/configs.d.ts +1 -1
  15. package/dist/src/configs/configs.js +1 -1
  16. package/dist/src/context/mainContext.d.ts +1 -1
  17. package/dist/src/context/mainContext.js +1 -1
  18. package/dist/src/db/Replication.d.ts +4 -4
  19. package/dist/src/db/Replication.js +4 -4
  20. package/dist/src/db/lucene.d.ts +8 -8
  21. package/dist/src/db/lucene.js +12 -12
  22. package/dist/src/db/utils.d.ts +1 -1
  23. package/dist/src/db/utils.js +1 -1
  24. package/dist/src/docIds/conversions.d.ts +1 -1
  25. package/dist/src/docIds/conversions.js +1 -1
  26. package/dist/src/docIds/ids.d.ts +11 -11
  27. package/dist/src/docIds/ids.js +11 -11
  28. package/dist/src/docIds/params.d.ts +8 -8
  29. package/dist/src/docIds/params.js +8 -8
  30. package/dist/src/helpers.d.ts +2 -2
  31. package/dist/src/helpers.js +2 -2
  32. package/dist/src/middleware/passport/local.d.ts +4 -4
  33. package/dist/src/middleware/passport/local.js +4 -4
  34. package/dist/src/middleware/passport/sso/oidc.js +11 -11
  35. package/dist/src/middleware/passport/utils.d.ts +3 -3
  36. package/dist/src/middleware/passport/utils.js +3 -3
  37. package/dist/src/objectStore/buckets/app.d.ts +3 -3
  38. package/dist/src/objectStore/buckets/app.js +3 -3
  39. package/dist/src/objectStore/objectStore.d.ts +3 -3
  40. package/dist/src/objectStore/objectStore.js +3 -3
  41. package/dist/src/queue/inMemoryQueue.d.ts +6 -6
  42. package/dist/src/queue/inMemoryQueue.js +9 -9
  43. package/dist/src/redis/redis.js +1 -1
  44. package/dist/src/security/permissions.d.ts +2 -2
  45. package/dist/src/security/permissions.js +2 -2
  46. package/dist/src/security/roles.d.ts +6 -6
  47. package/dist/src/security/roles.js +6 -6
  48. package/dist/src/users/db.d.ts +1 -1
  49. package/dist/src/users/db.js +12 -5
  50. package/dist/src/users/db.js.map +1 -1
  51. package/dist/src/users/users.d.ts +2 -1
  52. package/dist/src/users/users.js +20 -2
  53. package/dist/src/users/users.js.map +1 -1
  54. package/dist/src/users/utils.d.ts +1 -0
  55. package/dist/src/users/utils.js +2 -1
  56. package/dist/src/users/utils.js.map +1 -1
  57. package/dist/src/utils/utils.d.ts +11 -11
  58. package/dist/src/utils/utils.js +11 -11
  59. package/dist/tests/core/utilities/structures/licenses.js +13 -0
  60. package/dist/tests/core/utilities/structures/licenses.js.map +1 -1
  61. package/dist/tests/core/utilities/structures/quotas.d.ts +1 -1
  62. package/dist/tests/core/utilities/structures/quotas.js +3 -2
  63. package/dist/tests/core/utilities/structures/quotas.js.map +1 -1
  64. package/package.json +4 -4
  65. package/src/cache/appMetadata.ts +5 -5
  66. package/src/cache/user.ts +5 -5
  67. package/src/cache/writethrough.ts +2 -2
  68. package/src/configs/configs.ts +1 -1
  69. package/src/context/mainContext.ts +1 -1
  70. package/src/db/Replication.ts +4 -4
  71. package/src/db/lucene.ts +12 -12
  72. package/src/db/utils.ts +1 -1
  73. package/src/docIds/conversions.ts +1 -1
  74. package/src/docIds/ids.ts +11 -11
  75. package/src/docIds/params.ts +8 -8
  76. package/src/helpers.ts +2 -2
  77. package/src/middleware/passport/local.ts +4 -4
  78. package/src/middleware/passport/sso/oidc.ts +11 -11
  79. package/src/middleware/passport/utils.ts +3 -3
  80. package/src/objectStore/buckets/app.ts +3 -3
  81. package/src/objectStore/objectStore.ts +3 -3
  82. package/src/queue/inMemoryQueue.ts +9 -9
  83. package/src/redis/redis.ts +1 -1
  84. package/src/security/permissions.ts +2 -2
  85. package/src/security/roles.ts +6 -6
  86. package/src/users/db.ts +63 -48
  87. package/src/users/users.ts +16 -2
  88. package/src/users/utils.ts +1 -0
  89. package/src/utils/utils.ts +11 -11
  90. package/tests/core/users/users.spec.js +54 -0
  91. package/tests/core/utilities/structures/licenses.ts +13 -0
  92. package/tests/core/utilities/structures/quotas.ts +3 -2
package/dist/index.js CHANGED
@@ -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 find = require("pouchdb-find");
2145
- import_pouchdb.default.plugin(find);
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(values, task) {
2585
- if (!values) {
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: values
2589
+ environmentVariables: values2
2590
2590
  };
2591
2591
  return newContext(updates, task);
2592
2592
  }
@@ -3899,8 +3899,8 @@ var init_Replication = __esm({
3899
3899
  Replication = class {
3900
3900
  /**
3901
3901
  *
3902
- * @param {String} source - the DB you want to replicate or rollback to
3903
- * @param {String} target - the DB you want to replicate to, or rollback from
3902
+ * @param source - the DB you want to replicate or rollback to
3903
+ * @param target - the DB you want to replicate to, or rollback from
3904
3904
  */
3905
3905
  constructor({ source, target }) {
3906
3906
  this.source = getPouchDB(source);
@@ -3922,7 +3922,7 @@ var init_Replication = __esm({
3922
3922
  }
3923
3923
  /**
3924
3924
  * Two way replication operation, intended to be promise based.
3925
- * @param {Object} opts - PouchDB replication options
3925
+ * @param opts - PouchDB replication options
3926
3926
  */
3927
3927
  sync(opts = {}) {
3928
3928
  this.replication = this.promisify(this.source.sync, opts);
@@ -3930,7 +3930,7 @@ var init_Replication = __esm({
3930
3930
  }
3931
3931
  /**
3932
3932
  * One way replication operation, intended to be promise based.
3933
- * @param {Object} opts - PouchDB replication options
3933
+ * @param opts - PouchDB replication options
3934
3934
  */
3935
3935
  replicate(opts = {}) {
3936
3936
  this.replication = this.promisify(this.source.replicate.to, opts);
@@ -6254,6 +6254,7 @@ __export(users_exports3, {
6254
6254
  getAccountHolderFromUserIds: () => getAccountHolderFromUserIds,
6255
6255
  getAllUserIds: () => getAllUserIds,
6256
6256
  getById: () => getById,
6257
+ getCreatorCount: () => getCreatorCount,
6257
6258
  getExistingAccounts: () => getExistingAccounts,
6258
6259
  getExistingPlatformUsers: () => getExistingPlatformUsers,
6259
6260
  getExistingTenantUsers: () => getExistingTenantUsers,
@@ -6267,6 +6268,7 @@ __export(users_exports3, {
6267
6268
  isAdmin: () => isAdmin2,
6268
6269
  isAdminOrBuilder: () => isAdminOrBuilder2,
6269
6270
  isBuilder: () => isBuilder2,
6271
+ isCreator: () => isCreator2,
6270
6272
  isGlobalBuilder: () => isGlobalBuilder2,
6271
6273
  isSupportedUserSearch: () => isSupportedUserSearch,
6272
6274
  paginatedUsers: () => paginatedUsers,
@@ -6283,222 +6285,6 @@ init_db4();
6283
6285
  init_src();
6284
6286
  init_context2();
6285
6287
  init_context2();
6286
- function removeUserPassword(users) {
6287
- if (Array.isArray(users)) {
6288
- return users.map((user) => {
6289
- if (user) {
6290
- delete user.password;
6291
- return user;
6292
- }
6293
- });
6294
- } else if (users) {
6295
- delete users.password;
6296
- return users;
6297
- }
6298
- return users;
6299
- }
6300
- var isSupportedUserSearch = (query) => {
6301
- const allowed = [
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
- } = {}) => {
6451
- const db = getGlobalDB();
6452
- const opts = {
6453
- include_docs: true,
6454
- limit: PAGE_LIMIT + 1
6455
- };
6456
- if (bookmark) {
6457
- opts.startkey = bookmark;
6458
- }
6459
- let userList, property = "_id", getKey;
6460
- if (query?.equal?._id) {
6461
- userList = [await getById(query.equal._id)];
6462
- } else if (appId) {
6463
- userList = await searchGlobalUsersByApp(appId, opts);
6464
- getKey = (doc) => getGlobalUserByAppPage(appId, doc);
6465
- } else if (query?.string?.email) {
6466
- userList = await searchGlobalUsersByEmail(query?.string?.email, opts);
6467
- property = "email";
6468
- } else {
6469
- const response = await db.allDocs(getGlobalUserParams(null, opts));
6470
- userList = response.rows.map((row) => row.doc);
6471
- }
6472
- return pagination(userList, PAGE_LIMIT, {
6473
- paginate: true,
6474
- property,
6475
- getKey
6476
- });
6477
- };
6478
- async function getUserCount() {
6479
- const response = await queryGlobalViewRaw("by_email2" /* USER_BY_EMAIL */, {
6480
- limit: 0,
6481
- // to be as fast as possible - we just want the total rows count
6482
- include_docs: false
6483
- });
6484
- return response.total_rows;
6485
- }
6486
- function removePortalUserPermissions(user) {
6487
- delete user.admin;
6488
- delete user.builder;
6489
- return user;
6490
- }
6491
- function cleanseUserObject(user, base) {
6492
- delete user.admin;
6493
- delete user.builder;
6494
- delete user.roles;
6495
- if (base) {
6496
- user.admin = base.admin;
6497
- user.builder = base.builder;
6498
- user.roles = base.roles;
6499
- }
6500
- return user;
6501
- }
6502
6288
 
6503
6289
  // src/users/utils.ts
6504
6290
  init_environment2();
@@ -6785,14 +6571,17 @@ __export(users_exports2, {
6785
6571
  getGlobalUserID: () => getGlobalUserID,
6786
6572
  hasAdminPermissions: () => hasAdminPermissions,
6787
6573
  hasAppBuilderPermissions: () => hasAppBuilderPermissions,
6574
+ hasAppCreatorPermissions: () => hasAppCreatorPermissions,
6788
6575
  hasBuilderPermissions: () => hasBuilderPermissions,
6789
6576
  isAdmin: () => isAdmin,
6790
6577
  isAdminOrBuilder: () => isAdminOrBuilder,
6791
6578
  isAdminOrGlobalBuilder: () => isAdminOrGlobalBuilder,
6792
6579
  isBuilder: () => isBuilder,
6580
+ isCreator: () => isCreator,
6793
6581
  isGlobalBuilder: () => isGlobalBuilder
6794
6582
  });
6795
6583
  init_src();
6584
+ var _ = __toESM(require("lodash/fp"));
6796
6585
  function isBuilder(user, appId) {
6797
6586
  if (!user) {
6798
6587
  return false;
@@ -6827,6 +6616,17 @@ function hasAppBuilderPermissions(user) {
6827
6616
  const isGlobalBuilder3 = !!user.builder?.global;
6828
6617
  return !isGlobalBuilder3 && appLength != null && appLength > 0;
6829
6618
  }
6619
+ function hasAppCreatorPermissions(user) {
6620
+ if (!user) {
6621
+ return false;
6622
+ }
6623
+ return _.flow(
6624
+ _.get("roles"),
6625
+ _.values,
6626
+ _.find((x) => ["CREATOR", "ADMIN"].includes(x)),
6627
+ (x) => !!x
6628
+ )(user);
6629
+ }
6830
6630
  function hasBuilderPermissions(user) {
6831
6631
  if (!user) {
6832
6632
  return false;
@@ -6839,6 +6639,12 @@ function hasAdminPermissions(user) {
6839
6639
  }
6840
6640
  return !!user.admin?.global;
6841
6641
  }
6642
+ function isCreator(user) {
6643
+ if (!user) {
6644
+ return false;
6645
+ }
6646
+ return isGlobalBuilder(user) || hasAdminPermissions(user) || hasAppBuilderPermissions(user) || hasAppCreatorPermissions(user);
6647
+ }
6842
6648
  function getGlobalUserID(userId) {
6843
6649
  if (typeof userId !== "string") {
6844
6650
  return userId;
@@ -6880,6 +6686,7 @@ var allowDisplayColumnByType = {
6880
6686
  // src/users/utils.ts
6881
6687
  var isBuilder2 = sdk_exports.users.isBuilder;
6882
6688
  var isAdmin2 = sdk_exports.users.isAdmin;
6689
+ var isCreator2 = sdk_exports.users.isCreator;
6883
6690
  var isGlobalBuilder2 = sdk_exports.users.isGlobalBuilder;
6884
6691
  var isAdminOrBuilder2 = sdk_exports.users.isAdminOrBuilder;
6885
6692
  var hasAdminPermissions2 = sdk_exports.users.hasAdminPermissions;
@@ -6913,6 +6720,236 @@ async function getAccountHolderFromUserIds(userIds) {
6913
6720
  }
6914
6721
  }
6915
6722
 
6723
+ // src/users/users.ts
6724
+ function removeUserPassword(users) {
6725
+ if (Array.isArray(users)) {
6726
+ return users.map((user) => {
6727
+ if (user) {
6728
+ delete user.password;
6729
+ return user;
6730
+ }
6731
+ });
6732
+ } else if (users) {
6733
+ delete users.password;
6734
+ return users;
6735
+ }
6736
+ return users;
6737
+ }
6738
+ var isSupportedUserSearch = (query) => {
6739
+ const allowed = [
6740
+ { op: "string" /* STRING */, key: "email" },
6741
+ { op: "equal" /* EQUAL */, key: "_id" }
6742
+ ];
6743
+ for (let [key, operation] of Object.entries(query)) {
6744
+ if (typeof operation !== "object") {
6745
+ return false;
6746
+ }
6747
+ const fields = Object.keys(operation || {});
6748
+ if (fields.length === 0) {
6749
+ continue;
6750
+ }
6751
+ const allowedOperation = allowed.find(
6752
+ (allow) => allow.op === key && fields.length === 1 && fields[0] === allow.key
6753
+ );
6754
+ if (!allowedOperation) {
6755
+ return false;
6756
+ }
6757
+ }
6758
+ return true;
6759
+ };
6760
+ var bulkGetGlobalUsersById = async (userIds, opts) => {
6761
+ const db = getGlobalDB();
6762
+ let users = (await db.allDocs({
6763
+ keys: userIds,
6764
+ include_docs: true
6765
+ })).rows.map((row) => row.doc);
6766
+ if (opts?.cleanup) {
6767
+ users = removeUserPassword(users);
6768
+ }
6769
+ return users;
6770
+ };
6771
+ var getAllUserIds = async () => {
6772
+ const db = getGlobalDB();
6773
+ const startKey = `${"us" /* USER */}${SEPARATOR}`;
6774
+ const response = await db.allDocs({
6775
+ startkey: startKey,
6776
+ endkey: `${startKey}${UNICODE_MAX}`
6777
+ });
6778
+ return response.rows.map((row) => row.id);
6779
+ };
6780
+ var bulkUpdateGlobalUsers = async (users) => {
6781
+ const db = getGlobalDB();
6782
+ return await db.bulkDocs(users);
6783
+ };
6784
+ async function getById(id, opts) {
6785
+ const db = getGlobalDB();
6786
+ let user = await db.get(id);
6787
+ if (opts?.cleanup) {
6788
+ user = removeUserPassword(user);
6789
+ }
6790
+ return user;
6791
+ }
6792
+ var getGlobalUserByEmail = async (email, opts) => {
6793
+ if (email == null) {
6794
+ throw "Must supply an email address to view";
6795
+ }
6796
+ const response = await queryGlobalView("by_email2" /* USER_BY_EMAIL */, {
6797
+ key: email.toLowerCase(),
6798
+ include_docs: true
6799
+ });
6800
+ if (Array.isArray(response)) {
6801
+ throw new Error(`Multiple users found with email address: ${email}`);
6802
+ }
6803
+ let user = response;
6804
+ if (opts?.cleanup) {
6805
+ user = removeUserPassword(user);
6806
+ }
6807
+ return user;
6808
+ };
6809
+ var searchGlobalUsersByApp = async (appId, opts, getOpts) => {
6810
+ if (typeof appId !== "string") {
6811
+ throw new Error("Must provide a string based app ID");
6812
+ }
6813
+ const params2 = getUsersByAppParams(appId, {
6814
+ include_docs: true
6815
+ });
6816
+ params2.startkey = opts && opts.startkey ? opts.startkey : params2.startkey;
6817
+ let response = await queryGlobalView("by_app" /* USER_BY_APP */, params2);
6818
+ if (!response) {
6819
+ response = [];
6820
+ }
6821
+ let users = Array.isArray(response) ? response : [response];
6822
+ if (getOpts?.cleanup) {
6823
+ users = removeUserPassword(users);
6824
+ }
6825
+ return users;
6826
+ };
6827
+ var searchGlobalUsersByAppAccess = async (appId, opts) => {
6828
+ const roleSelector = `roles.${appId}`;
6829
+ let orQuery = [
6830
+ {
6831
+ "builder.global": true
6832
+ },
6833
+ {
6834
+ "admin.global": true
6835
+ }
6836
+ ];
6837
+ if (appId) {
6838
+ const roleCheck = {
6839
+ [roleSelector]: {
6840
+ $exists: true
6841
+ }
6842
+ };
6843
+ orQuery.push(roleCheck);
6844
+ }
6845
+ let searchOptions = {
6846
+ selector: {
6847
+ $or: orQuery,
6848
+ _id: {
6849
+ $regex: "^us_"
6850
+ }
6851
+ },
6852
+ limit: opts?.limit || 50
6853
+ };
6854
+ const resp = await directCouchFind(getGlobalDBName(), searchOptions);
6855
+ return resp?.rows;
6856
+ };
6857
+ var getGlobalUserByAppPage = (appId, user) => {
6858
+ if (!user) {
6859
+ return;
6860
+ }
6861
+ return generateAppUserID(getProdAppID(appId), user._id);
6862
+ };
6863
+ var searchGlobalUsersByEmail = async (email, opts, getOpts) => {
6864
+ if (typeof email !== "string") {
6865
+ throw new Error("Must provide a string to search by");
6866
+ }
6867
+ const lcEmail = email.toLowerCase();
6868
+ const startkey = opts && opts.startkey ? opts.startkey : lcEmail;
6869
+ let response = await queryGlobalView("by_email2" /* USER_BY_EMAIL */, {
6870
+ ...opts,
6871
+ startkey,
6872
+ endkey: `${lcEmail}${UNICODE_MAX}`
6873
+ });
6874
+ if (!response) {
6875
+ response = [];
6876
+ }
6877
+ let users = Array.isArray(response) ? response : [response];
6878
+ if (getOpts?.cleanup) {
6879
+ users = removeUserPassword(users);
6880
+ }
6881
+ return users;
6882
+ };
6883
+ var PAGE_LIMIT = 8;
6884
+ var paginatedUsers = async ({
6885
+ bookmark,
6886
+ query,
6887
+ appId
6888
+ } = {}) => {
6889
+ const db = getGlobalDB();
6890
+ const opts = {
6891
+ include_docs: true,
6892
+ limit: PAGE_LIMIT + 1
6893
+ };
6894
+ if (bookmark) {
6895
+ opts.startkey = bookmark;
6896
+ }
6897
+ let userList, property = "_id", getKey;
6898
+ if (query?.equal?._id) {
6899
+ userList = [await getById(query.equal._id)];
6900
+ } else if (appId) {
6901
+ userList = await searchGlobalUsersByApp(appId, opts);
6902
+ getKey = (doc) => getGlobalUserByAppPage(appId, doc);
6903
+ } else if (query?.string?.email) {
6904
+ userList = await searchGlobalUsersByEmail(query?.string?.email, opts);
6905
+ property = "email";
6906
+ } else {
6907
+ const response = await db.allDocs(getGlobalUserParams(null, opts));
6908
+ userList = response.rows.map((row) => row.doc);
6909
+ }
6910
+ return pagination(userList, PAGE_LIMIT, {
6911
+ paginate: true,
6912
+ property,
6913
+ getKey
6914
+ });
6915
+ };
6916
+ async function getUserCount() {
6917
+ const response = await queryGlobalViewRaw("by_email2" /* USER_BY_EMAIL */, {
6918
+ limit: 0,
6919
+ // to be as fast as possible - we just want the total rows count
6920
+ include_docs: false
6921
+ });
6922
+ return response.total_rows;
6923
+ }
6924
+ async function getCreatorCount() {
6925
+ let creators = 0;
6926
+ async function iterate(startPage) {
6927
+ const page = await paginatedUsers({ bookmark: startPage });
6928
+ creators += page.data.filter(isCreator2).length;
6929
+ if (page.hasNextPage) {
6930
+ await iterate(page.nextPage);
6931
+ }
6932
+ }
6933
+ await iterate();
6934
+ return creators;
6935
+ }
6936
+ function removePortalUserPermissions(user) {
6937
+ delete user.admin;
6938
+ delete user.builder;
6939
+ return user;
6940
+ }
6941
+ function cleanseUserObject(user, base) {
6942
+ delete user.admin;
6943
+ delete user.builder;
6944
+ delete user.roles;
6945
+ if (base) {
6946
+ user.admin = base.admin;
6947
+ user.builder = base.builder;
6948
+ user.roles = base.roles;
6949
+ }
6950
+ return user;
6951
+ }
6952
+
6916
6953
  // src/users/db.ts
6917
6954
  init_environment2();
6918
6955
 
@@ -7419,8 +7456,8 @@ function newJob(queue, message) {
7419
7456
  var InMemoryQueue = class {
7420
7457
  /**
7421
7458
  * The constructor the queue, exactly the same as that of Bulls.
7422
- * @param {string} name The name of the queue which is being configured.
7423
- * @param {object|null} opts This is not used by the in memory queue as there is no real use
7459
+ * @param name The name of the queue which is being configured.
7460
+ * @param opts This is not used by the in memory queue as there is no real use
7424
7461
  * case when in memory, but is the same API as Bull
7425
7462
  */
7426
7463
  constructor(name, opts = null) {
@@ -7435,7 +7472,7 @@ var InMemoryQueue = class {
7435
7472
  * Same callback API as Bull, each callback passed to this will consume messages as they are
7436
7473
  * available. Please note this is a queue service, not a notification service, so each
7437
7474
  * consumer will receive different messages.
7438
- * @param {function<object>} func The callback function which will return a "Job", the same
7475
+ * @param func The callback function which will return a "Job", the same
7439
7476
  * as the Bull API, within this job the property "data" contains the JSON message. Please
7440
7477
  * note this is incredibly limited compared to Bull as in reality the Job would contain
7441
7478
  * a lot more information about the queue and current status of Bull cluster.
@@ -7458,9 +7495,9 @@ var InMemoryQueue = class {
7458
7495
  * Simple function to replicate the add message functionality of Bull, putting
7459
7496
  * a new message on the queue. This then emits an event which will be used to
7460
7497
  * return the message to a consumer (if one is attached).
7461
- * @param {object} msg A message to be transported over the queue, this should be
7498
+ * @param msg A message to be transported over the queue, this should be
7462
7499
  * a JSON message as this is required by Bull.
7463
- * @param {boolean} repeat serves no purpose for the import queue.
7500
+ * @param repeat serves no purpose for the import queue.
7464
7501
  */
7465
7502
  // eslint-disable-next-line no-unused-vars
7466
7503
  add(msg, repeat) {
@@ -7479,7 +7516,7 @@ var InMemoryQueue = class {
7479
7516
  }
7480
7517
  /**
7481
7518
  * This removes a cron which has been implemented, this is part of Bull API.
7482
- * @param {string} cronJobId The cron which is to be removed.
7519
+ * @param cronJobId The cron which is to be removed.
7483
7520
  */
7484
7521
  removeRepeatableByKey(cronJobId) {
7485
7522
  console.log(cronJobId);
@@ -9898,7 +9935,8 @@ var UserDB = class _UserDB {
9898
9935
  }
9899
9936
  }
9900
9937
  const change = dbUser ? 0 : 1;
9901
- return _UserDB.quotas.addUsers(change, async () => {
9938
+ const creatorsChange = isCreator2(dbUser) !== isCreator2(user) ? 1 : 0;
9939
+ return _UserDB.quotas.addUsers(change, creatorsChange, async () => {
9902
9940
  await validateUniqueUser(email, tenantId);
9903
9941
  let builtUser = await _UserDB.buildUser(user, opts, tenantId, dbUser);
9904
9942
  if (opts.currentUserId && opts.currentUserId === dbUser?._id) {
@@ -9942,6 +9980,7 @@ var UserDB = class _UserDB {
9942
9980
  const tenantId = getTenantId();
9943
9981
  let usersToSave = [];
9944
9982
  let newUsers = [];
9983
+ let newCreators = [];
9945
9984
  const emails = newUsersRequested.map((user) => user.email);
9946
9985
  const existingEmails = await searchExistingEmails(emails);
9947
9986
  const unsuccessful = [];
@@ -9957,49 +9996,56 @@ var UserDB = class _UserDB {
9957
9996
  }
9958
9997
  newUser.userGroups = groups;
9959
9998
  newUsers.push(newUser);
9999
+ if (isCreator2(newUser)) {
10000
+ newCreators.push(newUser);
10001
+ }
9960
10002
  }
9961
10003
  const account = await getAccountByTenantId(tenantId);
9962
- return _UserDB.quotas.addUsers(newUsers.length, async () => {
9963
- newUsers.forEach((user) => {
9964
- usersToSave.push(
9965
- _UserDB.buildUser(
9966
- user,
9967
- {
9968
- hashPassword: true,
9969
- requirePassword: user.requirePassword
9970
- },
9971
- tenantId,
9972
- void 0,
9973
- // no dbUser
9974
- account
9975
- )
9976
- );
9977
- });
9978
- const usersToBulkSave = await Promise.all(usersToSave);
9979
- await bulkUpdateGlobalUsers(usersToBulkSave);
9980
- for (const user of usersToBulkSave) {
9981
- await users_exports.addUser(tenantId, user._id, user.email);
9982
- await handleSaveEvents(user, void 0);
9983
- }
9984
- const saved = usersToBulkSave.map((user) => {
10004
+ return _UserDB.quotas.addUsers(
10005
+ newUsers.length,
10006
+ newCreators.length,
10007
+ async () => {
10008
+ newUsers.forEach((user) => {
10009
+ usersToSave.push(
10010
+ _UserDB.buildUser(
10011
+ user,
10012
+ {
10013
+ hashPassword: true,
10014
+ requirePassword: user.requirePassword
10015
+ },
10016
+ tenantId,
10017
+ void 0,
10018
+ // no dbUser
10019
+ account
10020
+ )
10021
+ );
10022
+ });
10023
+ const usersToBulkSave = await Promise.all(usersToSave);
10024
+ await bulkUpdateGlobalUsers(usersToBulkSave);
10025
+ for (const user of usersToBulkSave) {
10026
+ await users_exports.addUser(tenantId, user._id, user.email);
10027
+ await handleSaveEvents(user, void 0);
10028
+ }
10029
+ const saved = usersToBulkSave.map((user) => {
10030
+ return {
10031
+ _id: user._id,
10032
+ email: user.email
10033
+ };
10034
+ });
10035
+ if (Array.isArray(saved) && groups) {
10036
+ const groupPromises = [];
10037
+ const createdUserIds = saved.map((user) => user._id);
10038
+ for (let groupId of groups) {
10039
+ groupPromises.push(_UserDB.groups.addUsers(groupId, createdUserIds));
10040
+ }
10041
+ await Promise.all(groupPromises);
10042
+ }
9985
10043
  return {
9986
- _id: user._id,
9987
- email: user.email
10044
+ successful: saved,
10045
+ unsuccessful
9988
10046
  };
9989
- });
9990
- if (Array.isArray(saved) && groups) {
9991
- const groupPromises = [];
9992
- const createdUserIds = saved.map((user) => user._id);
9993
- for (let groupId of groups) {
9994
- groupPromises.push(_UserDB.groups.addUsers(groupId, createdUserIds));
9995
- }
9996
- await Promise.all(groupPromises);
9997
10047
  }
9998
- return {
9999
- successful: saved,
10000
- unsuccessful
10001
- };
10002
- });
10048
+ );
10003
10049
  }
10004
10050
  static async bulkDelete(userIds) {
10005
10051
  const db = getGlobalDB();
@@ -10030,10 +10076,11 @@ var UserDB = class _UserDB {
10030
10076
  _deleted: true
10031
10077
  }));
10032
10078
  const dbResponse = await bulkUpdateGlobalUsers(toDelete);
10033
- await _UserDB.quotas.removeUsers(toDelete.length);
10079
+ const creatorsToDelete = usersToDelete.filter(isCreator2);
10034
10080
  for (let user of usersToDelete) {
10035
10081
  await bulkDeleteProcessing(user);
10036
10082
  }
10083
+ await _UserDB.quotas.removeUsers(toDelete.length, creatorsToDelete.length);
10037
10084
  const userIndex = {};
10038
10085
  usersToDelete.reduce((prev, current) => {
10039
10086
  prev[current._id] = current;
@@ -10070,7 +10117,8 @@ var UserDB = class _UserDB {
10070
10117
  }
10071
10118
  await users_exports.removeUser(dbUser);
10072
10119
  await db.remove(userId, dbUser._rev);
10073
- await _UserDB.quotas.removeUsers(1);
10120
+ const creatorsToDelete = isCreator2(dbUser) ? 1 : 0;
10121
+ await _UserDB.quotas.removeUsers(1, creatorsToDelete);
10074
10122
  await handleDeleteEvents(dbUser);
10075
10123
  await user_exports.invalidateUser(userId);
10076
10124
  await invalidateSessions(userId, { reason: "deletion" });
@@ -10247,7 +10295,7 @@ async function put(db, doc, writeRateMs = DEFAULT_WRITE_RATE_MS) {
10247
10295
  }
10248
10296
  return { ok: true, id: output._id, rev: output._rev };
10249
10297
  }
10250
- async function get2(db, id) {
10298
+ async function get3(db, id) {
10251
10299
  const cache = await getCache();
10252
10300
  const cacheKey = makeCacheKey(db, id);
10253
10301
  let cacheItem = await cache.get(cacheKey);
@@ -10276,11 +10324,11 @@ var Writethrough = class {
10276
10324
  this.db = db;
10277
10325
  this.writeRateMs = writeRateMs;
10278
10326
  }
10279
- async put(doc) {
10280
- return put(this.db, doc, this.writeRateMs);
10327
+ async put(doc, writeRateMs = this.writeRateMs) {
10328
+ return put(this.db, doc, writeRateMs);
10281
10329
  }
10282
10330
  async get(id) {
10283
- return get2(this.db, id);
10331
+ return get3(this.db, id);
10284
10332
  }
10285
10333
  async remove(docOrId, rev) {
10286
10334
  return remove(this.db, docOrId, rev);