@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.
- package/dist/index.js +324 -276
- 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/cache/appMetadata.d.ts +5 -5
- package/dist/src/cache/appMetadata.js +5 -5
- package/dist/src/cache/user.d.ts +5 -5
- package/dist/src/cache/user.js +5 -5
- package/dist/src/cache/writethrough.d.ts +1 -1
- package/dist/src/cache/writethrough.js +2 -2
- package/dist/src/cache/writethrough.js.map +1 -1
- package/dist/src/configs/configs.d.ts +1 -1
- package/dist/src/configs/configs.js +1 -1
- package/dist/src/context/mainContext.d.ts +1 -1
- package/dist/src/context/mainContext.js +1 -1
- package/dist/src/db/Replication.d.ts +4 -4
- package/dist/src/db/Replication.js +4 -4
- package/dist/src/db/lucene.d.ts +8 -8
- package/dist/src/db/lucene.js +12 -12
- package/dist/src/db/utils.d.ts +1 -1
- package/dist/src/db/utils.js +1 -1
- package/dist/src/docIds/conversions.d.ts +1 -1
- package/dist/src/docIds/conversions.js +1 -1
- package/dist/src/docIds/ids.d.ts +11 -11
- package/dist/src/docIds/ids.js +11 -11
- package/dist/src/docIds/params.d.ts +8 -8
- package/dist/src/docIds/params.js +8 -8
- package/dist/src/helpers.d.ts +2 -2
- package/dist/src/helpers.js +2 -2
- package/dist/src/middleware/passport/local.d.ts +4 -4
- package/dist/src/middleware/passport/local.js +4 -4
- package/dist/src/middleware/passport/sso/oidc.js +11 -11
- package/dist/src/middleware/passport/utils.d.ts +3 -3
- package/dist/src/middleware/passport/utils.js +3 -3
- package/dist/src/objectStore/buckets/app.d.ts +3 -3
- package/dist/src/objectStore/buckets/app.js +3 -3
- package/dist/src/objectStore/objectStore.d.ts +3 -3
- package/dist/src/objectStore/objectStore.js +3 -3
- package/dist/src/queue/inMemoryQueue.d.ts +6 -6
- package/dist/src/queue/inMemoryQueue.js +9 -9
- package/dist/src/redis/redis.js +1 -1
- package/dist/src/security/permissions.d.ts +2 -2
- package/dist/src/security/permissions.js +2 -2
- package/dist/src/security/roles.d.ts +6 -6
- package/dist/src/security/roles.js +6 -6
- package/dist/src/users/db.d.ts +1 -1
- package/dist/src/users/db.js +12 -5
- package/dist/src/users/db.js.map +1 -1
- package/dist/src/users/users.d.ts +2 -1
- 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/src/utils/utils.d.ts +11 -11
- package/dist/src/utils/utils.js +11 -11
- package/dist/tests/core/utilities/structures/licenses.js +13 -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/cache/appMetadata.ts +5 -5
- package/src/cache/user.ts +5 -5
- package/src/cache/writethrough.ts +2 -2
- package/src/configs/configs.ts +1 -1
- package/src/context/mainContext.ts +1 -1
- package/src/db/Replication.ts +4 -4
- package/src/db/lucene.ts +12 -12
- package/src/db/utils.ts +1 -1
- package/src/docIds/conversions.ts +1 -1
- package/src/docIds/ids.ts +11 -11
- package/src/docIds/params.ts +8 -8
- package/src/helpers.ts +2 -2
- package/src/middleware/passport/local.ts +4 -4
- package/src/middleware/passport/sso/oidc.ts +11 -11
- package/src/middleware/passport/utils.ts +3 -3
- package/src/objectStore/buckets/app.ts +3 -3
- package/src/objectStore/objectStore.ts +3 -3
- package/src/queue/inMemoryQueue.ts +9 -9
- package/src/redis/redis.ts +1 -1
- package/src/security/permissions.ts +2 -2
- package/src/security/roles.ts +6 -6
- package/src/users/db.ts +63 -48
- package/src/users/users.ts +16 -2
- package/src/users/utils.ts +1 -0
- package/src/utils/utils.ts +11 -11
- package/tests/core/users/users.spec.js +54 -0
- package/tests/core/utilities/structures/licenses.ts +13 -0
- 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
|
|
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
|
}
|
|
@@ -3899,8 +3899,8 @@ var init_Replication = __esm({
|
|
|
3899
3899
|
Replication = class {
|
|
3900
3900
|
/**
|
|
3901
3901
|
*
|
|
3902
|
-
* @param
|
|
3903
|
-
* @param
|
|
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
|
|
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
|
|
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
|
|
7423
|
-
* @param
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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(
|
|
9963
|
-
newUsers.
|
|
9964
|
-
|
|
9965
|
-
|
|
9966
|
-
|
|
9967
|
-
|
|
9968
|
-
|
|
9969
|
-
|
|
9970
|
-
|
|
9971
|
-
|
|
9972
|
-
|
|
9973
|
-
|
|
9974
|
-
|
|
9975
|
-
|
|
9976
|
-
|
|
9977
|
-
|
|
9978
|
-
|
|
9979
|
-
|
|
9980
|
-
|
|
9981
|
-
await
|
|
9982
|
-
await
|
|
9983
|
-
|
|
9984
|
-
|
|
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
|
-
|
|
9987
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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,
|
|
10327
|
+
async put(doc, writeRateMs = this.writeRateMs) {
|
|
10328
|
+
return put(this.db, doc, writeRateMs);
|
|
10281
10329
|
}
|
|
10282
10330
|
async get(id) {
|
|
10283
|
-
return
|
|
10331
|
+
return get3(this.db, id);
|
|
10284
10332
|
}
|
|
10285
10333
|
async remove(docOrId, rev) {
|
|
10286
10334
|
return remove(this.db, docOrId, rev);
|