@budibase/backend-core 2.13.15 → 2.13.17
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 +278 -250
- 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.meta.json +1 -1
- package/dist/src/security/permissions.d.ts +1 -0
- package/dist/src/security/permissions.js +2 -1
- package/dist/src/security/permissions.js.map +1 -1
- package/dist/src/users/db.d.ts +1 -1
- package/dist/src/users/db.js +1 -6
- package/dist/src/users/db.js.map +1 -1
- package/dist/src/users/users.d.ts +2 -0
- package/dist/src/users/users.js +26 -1
- package/dist/src/users/users.js.map +1 -1
- package/package.json +4 -4
- package/src/security/permissions.ts +1 -0
- package/src/users/db.ts +2 -9
- package/src/users/users.ts +18 -0
package/dist/index.js
CHANGED
|
@@ -691,6 +691,7 @@ var init_permissions = __esm({
|
|
|
691
691
|
PermissionType2["AUTOMATION"] = "automation";
|
|
692
692
|
PermissionType2["WEBHOOK"] = "webhook";
|
|
693
693
|
PermissionType2["BUILDER"] = "builder";
|
|
694
|
+
PermissionType2["CREATOR"] = "creator";
|
|
694
695
|
PermissionType2["GLOBAL_BUILDER"] = "globalBuilder";
|
|
695
696
|
PermissionType2["QUERY"] = "query";
|
|
696
697
|
PermissionType2["VIEW"] = "view";
|
|
@@ -6672,6 +6673,7 @@ var getStatus = async () => {
|
|
|
6672
6673
|
var users_exports3 = {};
|
|
6673
6674
|
__export(users_exports3, {
|
|
6674
6675
|
UserDB: () => UserDB,
|
|
6676
|
+
addAppBuilder: () => addAppBuilder,
|
|
6675
6677
|
bulkGetGlobalUsersById: () => bulkGetGlobalUsersById,
|
|
6676
6678
|
bulkUpdateGlobalUsers: () => bulkUpdateGlobalUsers,
|
|
6677
6679
|
cleanseUserObject: () => cleanseUserObject,
|
|
@@ -6697,6 +6699,7 @@ __export(users_exports3, {
|
|
|
6697
6699
|
isGlobalBuilder: () => isGlobalBuilder2,
|
|
6698
6700
|
isSupportedUserSearch: () => isSupportedUserSearch,
|
|
6699
6701
|
paginatedUsers: () => paginatedUsers,
|
|
6702
|
+
removeAppBuilder: () => removeAppBuilder,
|
|
6700
6703
|
removePortalUserPermissions: () => removePortalUserPermissions,
|
|
6701
6704
|
searchExistingEmails: () => searchExistingEmails,
|
|
6702
6705
|
searchGlobalUsersByApp: () => searchGlobalUsersByApp,
|
|
@@ -7307,12 +7310,14 @@ function getProdAppID2(appId) {
|
|
|
7307
7310
|
// ../shared-core/src/sdk/documents/users.ts
|
|
7308
7311
|
var users_exports2 = {};
|
|
7309
7312
|
__export(users_exports2, {
|
|
7313
|
+
canCreateApps: () => canCreateApps,
|
|
7310
7314
|
containsUserID: () => containsUserID,
|
|
7311
7315
|
getGlobalUserID: () => getGlobalUserID,
|
|
7312
7316
|
hasAdminPermissions: () => hasAdminPermissions,
|
|
7313
7317
|
hasAppBuilderPermissions: () => hasAppBuilderPermissions,
|
|
7314
7318
|
hasAppCreatorPermissions: () => hasAppCreatorPermissions,
|
|
7315
7319
|
hasBuilderPermissions: () => hasBuilderPermissions,
|
|
7320
|
+
hasCreatorPermissions: () => hasCreatorPermissions,
|
|
7316
7321
|
isAdmin: () => isAdmin,
|
|
7317
7322
|
isAdminOrBuilder: () => isAdminOrBuilder,
|
|
7318
7323
|
isAdminOrGlobalBuilder: () => isAdminOrGlobalBuilder,
|
|
@@ -7336,6 +7341,9 @@ function isBuilder(user, appId) {
|
|
|
7336
7341
|
function isGlobalBuilder(user) {
|
|
7337
7342
|
return isBuilder(user) && !hasAppBuilderPermissions(user) || isAdmin(user);
|
|
7338
7343
|
}
|
|
7344
|
+
function canCreateApps(user) {
|
|
7345
|
+
return isGlobalBuilder(user) || hasCreatorPermissions(user);
|
|
7346
|
+
}
|
|
7339
7347
|
function isAdmin(user) {
|
|
7340
7348
|
if (!user) {
|
|
7341
7349
|
return false;
|
|
@@ -7363,7 +7371,7 @@ function hasAppCreatorPermissions(user) {
|
|
|
7363
7371
|
return _.flow(
|
|
7364
7372
|
_.get("roles"),
|
|
7365
7373
|
_.values,
|
|
7366
|
-
_.find((x) =>
|
|
7374
|
+
_.find((x) => x === "CREATOR"),
|
|
7367
7375
|
(x) => !!x
|
|
7368
7376
|
)(user);
|
|
7369
7377
|
}
|
|
@@ -7371,7 +7379,7 @@ function hasBuilderPermissions(user) {
|
|
|
7371
7379
|
if (!user) {
|
|
7372
7380
|
return false;
|
|
7373
7381
|
}
|
|
7374
|
-
return user.builder?.global || hasAppBuilderPermissions(user);
|
|
7382
|
+
return user.builder?.global || hasAppBuilderPermissions(user) || hasCreatorPermissions(user);
|
|
7375
7383
|
}
|
|
7376
7384
|
function hasAdminPermissions(user) {
|
|
7377
7385
|
if (!user) {
|
|
@@ -7379,11 +7387,17 @@ function hasAdminPermissions(user) {
|
|
|
7379
7387
|
}
|
|
7380
7388
|
return !!user.admin?.global;
|
|
7381
7389
|
}
|
|
7390
|
+
function hasCreatorPermissions(user) {
|
|
7391
|
+
if (!user) {
|
|
7392
|
+
return false;
|
|
7393
|
+
}
|
|
7394
|
+
return !!user.builder?.creator;
|
|
7395
|
+
}
|
|
7382
7396
|
function isCreator(user) {
|
|
7383
7397
|
if (!user) {
|
|
7384
7398
|
return false;
|
|
7385
7399
|
}
|
|
7386
|
-
return isGlobalBuilder(user) || hasAdminPermissions(user) || hasAppBuilderPermissions(user) || hasAppCreatorPermissions(user);
|
|
7400
|
+
return isGlobalBuilder(user) || hasAdminPermissions(user) || hasCreatorPermissions(user) || hasAppBuilderPermissions(user) || hasAppCreatorPermissions(user);
|
|
7387
7401
|
}
|
|
7388
7402
|
function getGlobalUserID(userId) {
|
|
7389
7403
|
if (typeof userId !== "string") {
|
|
@@ -7478,250 +7492,6 @@ async function getAccountHolderFromUserIds(userIds) {
|
|
|
7478
7492
|
}
|
|
7479
7493
|
}
|
|
7480
7494
|
|
|
7481
|
-
// src/users/users.ts
|
|
7482
|
-
function removeUserPassword(users) {
|
|
7483
|
-
if (Array.isArray(users)) {
|
|
7484
|
-
return users.map((user) => {
|
|
7485
|
-
if (user) {
|
|
7486
|
-
delete user.password;
|
|
7487
|
-
return user;
|
|
7488
|
-
}
|
|
7489
|
-
});
|
|
7490
|
-
} else if (users) {
|
|
7491
|
-
delete users.password;
|
|
7492
|
-
return users;
|
|
7493
|
-
}
|
|
7494
|
-
return users;
|
|
7495
|
-
}
|
|
7496
|
-
function isSupportedUserSearch(query) {
|
|
7497
|
-
const allowed = [
|
|
7498
|
-
{ op: "string" /* STRING */, key: "email" },
|
|
7499
|
-
{ op: "equal" /* EQUAL */, key: "_id" }
|
|
7500
|
-
];
|
|
7501
|
-
for (let [key, operation] of Object.entries(query)) {
|
|
7502
|
-
if (typeof operation !== "object") {
|
|
7503
|
-
return false;
|
|
7504
|
-
}
|
|
7505
|
-
const fields = Object.keys(operation || {});
|
|
7506
|
-
if (fields.length === 0) {
|
|
7507
|
-
continue;
|
|
7508
|
-
}
|
|
7509
|
-
const allowedOperation = allowed.find(
|
|
7510
|
-
(allow) => allow.op === key && fields.length === 1 && fields[0] === allow.key
|
|
7511
|
-
);
|
|
7512
|
-
if (!allowedOperation) {
|
|
7513
|
-
return false;
|
|
7514
|
-
}
|
|
7515
|
-
}
|
|
7516
|
-
return true;
|
|
7517
|
-
}
|
|
7518
|
-
async function bulkGetGlobalUsersById(userIds, opts) {
|
|
7519
|
-
const db = getGlobalDB();
|
|
7520
|
-
let users = (await db.allDocs({
|
|
7521
|
-
keys: userIds,
|
|
7522
|
-
include_docs: true
|
|
7523
|
-
})).rows.map((row) => row.doc);
|
|
7524
|
-
if (opts?.cleanup) {
|
|
7525
|
-
users = removeUserPassword(users);
|
|
7526
|
-
}
|
|
7527
|
-
return users;
|
|
7528
|
-
}
|
|
7529
|
-
async function getAllUserIds() {
|
|
7530
|
-
const db = getGlobalDB();
|
|
7531
|
-
const startKey = `${"us" /* USER */}${SEPARATOR}`;
|
|
7532
|
-
const response = await db.allDocs({
|
|
7533
|
-
startkey: startKey,
|
|
7534
|
-
endkey: `${startKey}${UNICODE_MAX}`
|
|
7535
|
-
});
|
|
7536
|
-
return response.rows.map((row) => row.id);
|
|
7537
|
-
}
|
|
7538
|
-
async function bulkUpdateGlobalUsers(users) {
|
|
7539
|
-
const db = getGlobalDB();
|
|
7540
|
-
return await db.bulkDocs(users);
|
|
7541
|
-
}
|
|
7542
|
-
async function getById(id, opts) {
|
|
7543
|
-
const db = getGlobalDB();
|
|
7544
|
-
let user = await db.get(id);
|
|
7545
|
-
if (opts?.cleanup) {
|
|
7546
|
-
user = removeUserPassword(user);
|
|
7547
|
-
}
|
|
7548
|
-
return user;
|
|
7549
|
-
}
|
|
7550
|
-
async function getGlobalUserByEmail(email, opts) {
|
|
7551
|
-
if (email == null) {
|
|
7552
|
-
throw "Must supply an email address to view";
|
|
7553
|
-
}
|
|
7554
|
-
const response = await queryGlobalView("by_email2" /* USER_BY_EMAIL */, {
|
|
7555
|
-
key: email.toLowerCase(),
|
|
7556
|
-
include_docs: true
|
|
7557
|
-
});
|
|
7558
|
-
if (Array.isArray(response)) {
|
|
7559
|
-
throw new Error(`Multiple users found with email address: ${email}`);
|
|
7560
|
-
}
|
|
7561
|
-
let user = response;
|
|
7562
|
-
if (opts?.cleanup) {
|
|
7563
|
-
user = removeUserPassword(user);
|
|
7564
|
-
}
|
|
7565
|
-
return user;
|
|
7566
|
-
}
|
|
7567
|
-
async function doesUserExist(email) {
|
|
7568
|
-
try {
|
|
7569
|
-
const user = await getGlobalUserByEmail(email);
|
|
7570
|
-
if (Array.isArray(user) || user != null) {
|
|
7571
|
-
return true;
|
|
7572
|
-
}
|
|
7573
|
-
} catch (err) {
|
|
7574
|
-
return false;
|
|
7575
|
-
}
|
|
7576
|
-
return false;
|
|
7577
|
-
}
|
|
7578
|
-
async function searchGlobalUsersByApp(appId, opts, getOpts) {
|
|
7579
|
-
if (typeof appId !== "string") {
|
|
7580
|
-
throw new Error("Must provide a string based app ID");
|
|
7581
|
-
}
|
|
7582
|
-
const params2 = getUsersByAppParams(appId, {
|
|
7583
|
-
include_docs: true
|
|
7584
|
-
});
|
|
7585
|
-
params2.startkey = opts && opts.startkey ? opts.startkey : params2.startkey;
|
|
7586
|
-
let response = await queryGlobalView("by_app" /* USER_BY_APP */, params2);
|
|
7587
|
-
if (!response) {
|
|
7588
|
-
response = [];
|
|
7589
|
-
}
|
|
7590
|
-
let users = Array.isArray(response) ? response : [response];
|
|
7591
|
-
if (getOpts?.cleanup) {
|
|
7592
|
-
users = removeUserPassword(users);
|
|
7593
|
-
}
|
|
7594
|
-
return users;
|
|
7595
|
-
}
|
|
7596
|
-
async function searchGlobalUsersByAppAccess(appId, opts) {
|
|
7597
|
-
const roleSelector = `roles.${appId}`;
|
|
7598
|
-
let orQuery = [
|
|
7599
|
-
{
|
|
7600
|
-
"builder.global": true
|
|
7601
|
-
},
|
|
7602
|
-
{
|
|
7603
|
-
"admin.global": true
|
|
7604
|
-
}
|
|
7605
|
-
];
|
|
7606
|
-
if (appId) {
|
|
7607
|
-
const roleCheck = {
|
|
7608
|
-
[roleSelector]: {
|
|
7609
|
-
$exists: true
|
|
7610
|
-
}
|
|
7611
|
-
};
|
|
7612
|
-
orQuery.push(roleCheck);
|
|
7613
|
-
}
|
|
7614
|
-
let searchOptions = {
|
|
7615
|
-
selector: {
|
|
7616
|
-
$or: orQuery,
|
|
7617
|
-
_id: {
|
|
7618
|
-
$regex: "^us_"
|
|
7619
|
-
}
|
|
7620
|
-
},
|
|
7621
|
-
limit: opts?.limit || 50
|
|
7622
|
-
};
|
|
7623
|
-
const resp = await directCouchFind(getGlobalDBName(), searchOptions);
|
|
7624
|
-
return resp.rows;
|
|
7625
|
-
}
|
|
7626
|
-
function getGlobalUserByAppPage(appId, user) {
|
|
7627
|
-
if (!user) {
|
|
7628
|
-
return;
|
|
7629
|
-
}
|
|
7630
|
-
return generateAppUserID(getProdAppID(appId), user._id);
|
|
7631
|
-
}
|
|
7632
|
-
async function searchGlobalUsersByEmail(email, opts, getOpts) {
|
|
7633
|
-
if (typeof email !== "string") {
|
|
7634
|
-
throw new Error("Must provide a string to search by");
|
|
7635
|
-
}
|
|
7636
|
-
const lcEmail = email.toLowerCase();
|
|
7637
|
-
const startkey = opts && opts.startkey ? opts.startkey : lcEmail;
|
|
7638
|
-
let response = await queryGlobalView("by_email2" /* USER_BY_EMAIL */, {
|
|
7639
|
-
...opts,
|
|
7640
|
-
startkey,
|
|
7641
|
-
endkey: `${lcEmail}${UNICODE_MAX}`
|
|
7642
|
-
});
|
|
7643
|
-
if (!response) {
|
|
7644
|
-
response = [];
|
|
7645
|
-
}
|
|
7646
|
-
let users = Array.isArray(response) ? response : [response];
|
|
7647
|
-
if (getOpts?.cleanup) {
|
|
7648
|
-
users = removeUserPassword(users);
|
|
7649
|
-
}
|
|
7650
|
-
return users;
|
|
7651
|
-
}
|
|
7652
|
-
var PAGE_LIMIT = 8;
|
|
7653
|
-
async function paginatedUsers({
|
|
7654
|
-
bookmark,
|
|
7655
|
-
query,
|
|
7656
|
-
appId,
|
|
7657
|
-
limit
|
|
7658
|
-
} = {}) {
|
|
7659
|
-
const db = getGlobalDB();
|
|
7660
|
-
const pageSize = limit ?? PAGE_LIMIT;
|
|
7661
|
-
const pageLimit = pageSize + 1;
|
|
7662
|
-
const opts = {
|
|
7663
|
-
include_docs: true,
|
|
7664
|
-
limit: pageLimit
|
|
7665
|
-
};
|
|
7666
|
-
if (bookmark) {
|
|
7667
|
-
opts.startkey = bookmark;
|
|
7668
|
-
}
|
|
7669
|
-
let userList, property = "_id", getKey;
|
|
7670
|
-
if (query?.equal?._id) {
|
|
7671
|
-
userList = [await getById(query.equal._id)];
|
|
7672
|
-
} else if (appId) {
|
|
7673
|
-
userList = await searchGlobalUsersByApp(appId, opts);
|
|
7674
|
-
getKey = (doc) => getGlobalUserByAppPage(appId, doc);
|
|
7675
|
-
} else if (query?.string?.email) {
|
|
7676
|
-
userList = await searchGlobalUsersByEmail(query?.string?.email, opts);
|
|
7677
|
-
property = "email";
|
|
7678
|
-
} else {
|
|
7679
|
-
const response = await db.allDocs(getGlobalUserParams(null, opts));
|
|
7680
|
-
userList = response.rows.map((row) => row.doc);
|
|
7681
|
-
}
|
|
7682
|
-
return pagination(userList, pageSize, {
|
|
7683
|
-
paginate: true,
|
|
7684
|
-
property,
|
|
7685
|
-
getKey
|
|
7686
|
-
});
|
|
7687
|
-
}
|
|
7688
|
-
async function getUserCount() {
|
|
7689
|
-
const response = await queryGlobalViewRaw("by_email2" /* USER_BY_EMAIL */, {
|
|
7690
|
-
limit: 0,
|
|
7691
|
-
// to be as fast as possible - we just want the total rows count
|
|
7692
|
-
include_docs: false
|
|
7693
|
-
});
|
|
7694
|
-
return response.total_rows;
|
|
7695
|
-
}
|
|
7696
|
-
async function getCreatorCount() {
|
|
7697
|
-
let creators = 0;
|
|
7698
|
-
async function iterate(startPage) {
|
|
7699
|
-
const page = await paginatedUsers({ bookmark: startPage });
|
|
7700
|
-
creators += page.data.filter(isCreator2).length;
|
|
7701
|
-
if (page.hasNextPage) {
|
|
7702
|
-
await iterate(page.nextPage);
|
|
7703
|
-
}
|
|
7704
|
-
}
|
|
7705
|
-
await iterate();
|
|
7706
|
-
return creators;
|
|
7707
|
-
}
|
|
7708
|
-
function removePortalUserPermissions(user) {
|
|
7709
|
-
delete user.admin;
|
|
7710
|
-
delete user.builder;
|
|
7711
|
-
return user;
|
|
7712
|
-
}
|
|
7713
|
-
function cleanseUserObject(user, base) {
|
|
7714
|
-
delete user.admin;
|
|
7715
|
-
delete user.builder;
|
|
7716
|
-
delete user.roles;
|
|
7717
|
-
if (base) {
|
|
7718
|
-
user.admin = base.admin;
|
|
7719
|
-
user.builder = base.builder;
|
|
7720
|
-
user.roles = base.roles;
|
|
7721
|
-
}
|
|
7722
|
-
return user;
|
|
7723
|
-
}
|
|
7724
|
-
|
|
7725
7495
|
// src/users/db.ts
|
|
7726
7496
|
init_environment2();
|
|
7727
7497
|
|
|
@@ -10497,9 +10267,6 @@ var UserDB = class _UserDB {
|
|
|
10497
10267
|
if (!email && !_id) {
|
|
10498
10268
|
throw new Error("_id or email is required");
|
|
10499
10269
|
}
|
|
10500
|
-
if (user.builder?.apps?.length && !await _UserDB.features.isAppBuildersEnabled()) {
|
|
10501
|
-
throw new Error("Unable to update app builders, please check license");
|
|
10502
|
-
}
|
|
10503
10270
|
let dbUser;
|
|
10504
10271
|
if (_id) {
|
|
10505
10272
|
try {
|
|
@@ -10739,6 +10506,265 @@ var UserDB = class _UserDB {
|
|
|
10739
10506
|
}
|
|
10740
10507
|
};
|
|
10741
10508
|
|
|
10509
|
+
// src/users/users.ts
|
|
10510
|
+
function removeUserPassword(users) {
|
|
10511
|
+
if (Array.isArray(users)) {
|
|
10512
|
+
return users.map((user) => {
|
|
10513
|
+
if (user) {
|
|
10514
|
+
delete user.password;
|
|
10515
|
+
return user;
|
|
10516
|
+
}
|
|
10517
|
+
});
|
|
10518
|
+
} else if (users) {
|
|
10519
|
+
delete users.password;
|
|
10520
|
+
return users;
|
|
10521
|
+
}
|
|
10522
|
+
return users;
|
|
10523
|
+
}
|
|
10524
|
+
function isSupportedUserSearch(query) {
|
|
10525
|
+
const allowed = [
|
|
10526
|
+
{ op: "string" /* STRING */, key: "email" },
|
|
10527
|
+
{ op: "equal" /* EQUAL */, key: "_id" }
|
|
10528
|
+
];
|
|
10529
|
+
for (let [key, operation] of Object.entries(query)) {
|
|
10530
|
+
if (typeof operation !== "object") {
|
|
10531
|
+
return false;
|
|
10532
|
+
}
|
|
10533
|
+
const fields = Object.keys(operation || {});
|
|
10534
|
+
if (fields.length === 0) {
|
|
10535
|
+
continue;
|
|
10536
|
+
}
|
|
10537
|
+
const allowedOperation = allowed.find(
|
|
10538
|
+
(allow) => allow.op === key && fields.length === 1 && fields[0] === allow.key
|
|
10539
|
+
);
|
|
10540
|
+
if (!allowedOperation) {
|
|
10541
|
+
return false;
|
|
10542
|
+
}
|
|
10543
|
+
}
|
|
10544
|
+
return true;
|
|
10545
|
+
}
|
|
10546
|
+
async function bulkGetGlobalUsersById(userIds, opts) {
|
|
10547
|
+
const db = getGlobalDB();
|
|
10548
|
+
let users = (await db.allDocs({
|
|
10549
|
+
keys: userIds,
|
|
10550
|
+
include_docs: true
|
|
10551
|
+
})).rows.map((row) => row.doc);
|
|
10552
|
+
if (opts?.cleanup) {
|
|
10553
|
+
users = removeUserPassword(users);
|
|
10554
|
+
}
|
|
10555
|
+
return users;
|
|
10556
|
+
}
|
|
10557
|
+
async function getAllUserIds() {
|
|
10558
|
+
const db = getGlobalDB();
|
|
10559
|
+
const startKey = `${"us" /* USER */}${SEPARATOR}`;
|
|
10560
|
+
const response = await db.allDocs({
|
|
10561
|
+
startkey: startKey,
|
|
10562
|
+
endkey: `${startKey}${UNICODE_MAX}`
|
|
10563
|
+
});
|
|
10564
|
+
return response.rows.map((row) => row.id);
|
|
10565
|
+
}
|
|
10566
|
+
async function bulkUpdateGlobalUsers(users) {
|
|
10567
|
+
const db = getGlobalDB();
|
|
10568
|
+
return await db.bulkDocs(users);
|
|
10569
|
+
}
|
|
10570
|
+
async function getById(id, opts) {
|
|
10571
|
+
const db = getGlobalDB();
|
|
10572
|
+
let user = await db.get(id);
|
|
10573
|
+
if (opts?.cleanup) {
|
|
10574
|
+
user = removeUserPassword(user);
|
|
10575
|
+
}
|
|
10576
|
+
return user;
|
|
10577
|
+
}
|
|
10578
|
+
async function getGlobalUserByEmail(email, opts) {
|
|
10579
|
+
if (email == null) {
|
|
10580
|
+
throw "Must supply an email address to view";
|
|
10581
|
+
}
|
|
10582
|
+
const response = await queryGlobalView("by_email2" /* USER_BY_EMAIL */, {
|
|
10583
|
+
key: email.toLowerCase(),
|
|
10584
|
+
include_docs: true
|
|
10585
|
+
});
|
|
10586
|
+
if (Array.isArray(response)) {
|
|
10587
|
+
throw new Error(`Multiple users found with email address: ${email}`);
|
|
10588
|
+
}
|
|
10589
|
+
let user = response;
|
|
10590
|
+
if (opts?.cleanup) {
|
|
10591
|
+
user = removeUserPassword(user);
|
|
10592
|
+
}
|
|
10593
|
+
return user;
|
|
10594
|
+
}
|
|
10595
|
+
async function doesUserExist(email) {
|
|
10596
|
+
try {
|
|
10597
|
+
const user = await getGlobalUserByEmail(email);
|
|
10598
|
+
if (Array.isArray(user) || user != null) {
|
|
10599
|
+
return true;
|
|
10600
|
+
}
|
|
10601
|
+
} catch (err) {
|
|
10602
|
+
return false;
|
|
10603
|
+
}
|
|
10604
|
+
return false;
|
|
10605
|
+
}
|
|
10606
|
+
async function searchGlobalUsersByApp(appId, opts, getOpts) {
|
|
10607
|
+
if (typeof appId !== "string") {
|
|
10608
|
+
throw new Error("Must provide a string based app ID");
|
|
10609
|
+
}
|
|
10610
|
+
const params2 = getUsersByAppParams(appId, {
|
|
10611
|
+
include_docs: true
|
|
10612
|
+
});
|
|
10613
|
+
params2.startkey = opts && opts.startkey ? opts.startkey : params2.startkey;
|
|
10614
|
+
let response = await queryGlobalView("by_app" /* USER_BY_APP */, params2);
|
|
10615
|
+
if (!response) {
|
|
10616
|
+
response = [];
|
|
10617
|
+
}
|
|
10618
|
+
let users = Array.isArray(response) ? response : [response];
|
|
10619
|
+
if (getOpts?.cleanup) {
|
|
10620
|
+
users = removeUserPassword(users);
|
|
10621
|
+
}
|
|
10622
|
+
return users;
|
|
10623
|
+
}
|
|
10624
|
+
async function searchGlobalUsersByAppAccess(appId, opts) {
|
|
10625
|
+
const roleSelector = `roles.${appId}`;
|
|
10626
|
+
let orQuery = [
|
|
10627
|
+
{
|
|
10628
|
+
"builder.global": true
|
|
10629
|
+
},
|
|
10630
|
+
{
|
|
10631
|
+
"admin.global": true
|
|
10632
|
+
}
|
|
10633
|
+
];
|
|
10634
|
+
if (appId) {
|
|
10635
|
+
const roleCheck = {
|
|
10636
|
+
[roleSelector]: {
|
|
10637
|
+
$exists: true
|
|
10638
|
+
}
|
|
10639
|
+
};
|
|
10640
|
+
orQuery.push(roleCheck);
|
|
10641
|
+
}
|
|
10642
|
+
let searchOptions = {
|
|
10643
|
+
selector: {
|
|
10644
|
+
$or: orQuery,
|
|
10645
|
+
_id: {
|
|
10646
|
+
$regex: "^us_"
|
|
10647
|
+
}
|
|
10648
|
+
},
|
|
10649
|
+
limit: opts?.limit || 50
|
|
10650
|
+
};
|
|
10651
|
+
const resp = await directCouchFind(getGlobalDBName(), searchOptions);
|
|
10652
|
+
return resp.rows;
|
|
10653
|
+
}
|
|
10654
|
+
function getGlobalUserByAppPage(appId, user) {
|
|
10655
|
+
if (!user) {
|
|
10656
|
+
return;
|
|
10657
|
+
}
|
|
10658
|
+
return generateAppUserID(getProdAppID(appId), user._id);
|
|
10659
|
+
}
|
|
10660
|
+
async function searchGlobalUsersByEmail(email, opts, getOpts) {
|
|
10661
|
+
if (typeof email !== "string") {
|
|
10662
|
+
throw new Error("Must provide a string to search by");
|
|
10663
|
+
}
|
|
10664
|
+
const lcEmail = email.toLowerCase();
|
|
10665
|
+
const startkey = opts && opts.startkey ? opts.startkey : lcEmail;
|
|
10666
|
+
let response = await queryGlobalView("by_email2" /* USER_BY_EMAIL */, {
|
|
10667
|
+
...opts,
|
|
10668
|
+
startkey,
|
|
10669
|
+
endkey: `${lcEmail}${UNICODE_MAX}`
|
|
10670
|
+
});
|
|
10671
|
+
if (!response) {
|
|
10672
|
+
response = [];
|
|
10673
|
+
}
|
|
10674
|
+
let users = Array.isArray(response) ? response : [response];
|
|
10675
|
+
if (getOpts?.cleanup) {
|
|
10676
|
+
users = removeUserPassword(users);
|
|
10677
|
+
}
|
|
10678
|
+
return users;
|
|
10679
|
+
}
|
|
10680
|
+
var PAGE_LIMIT = 8;
|
|
10681
|
+
async function paginatedUsers({
|
|
10682
|
+
bookmark,
|
|
10683
|
+
query,
|
|
10684
|
+
appId,
|
|
10685
|
+
limit
|
|
10686
|
+
} = {}) {
|
|
10687
|
+
const db = getGlobalDB();
|
|
10688
|
+
const pageSize = limit ?? PAGE_LIMIT;
|
|
10689
|
+
const pageLimit = pageSize + 1;
|
|
10690
|
+
const opts = {
|
|
10691
|
+
include_docs: true,
|
|
10692
|
+
limit: pageLimit
|
|
10693
|
+
};
|
|
10694
|
+
if (bookmark) {
|
|
10695
|
+
opts.startkey = bookmark;
|
|
10696
|
+
}
|
|
10697
|
+
let userList, property = "_id", getKey;
|
|
10698
|
+
if (query?.equal?._id) {
|
|
10699
|
+
userList = [await getById(query.equal._id)];
|
|
10700
|
+
} else if (appId) {
|
|
10701
|
+
userList = await searchGlobalUsersByApp(appId, opts);
|
|
10702
|
+
getKey = (doc) => getGlobalUserByAppPage(appId, doc);
|
|
10703
|
+
} else if (query?.string?.email) {
|
|
10704
|
+
userList = await searchGlobalUsersByEmail(query?.string?.email, opts);
|
|
10705
|
+
property = "email";
|
|
10706
|
+
} else {
|
|
10707
|
+
const response = await db.allDocs(getGlobalUserParams(null, opts));
|
|
10708
|
+
userList = response.rows.map((row) => row.doc);
|
|
10709
|
+
}
|
|
10710
|
+
return pagination(userList, pageSize, {
|
|
10711
|
+
paginate: true,
|
|
10712
|
+
property,
|
|
10713
|
+
getKey
|
|
10714
|
+
});
|
|
10715
|
+
}
|
|
10716
|
+
async function getUserCount() {
|
|
10717
|
+
const response = await queryGlobalViewRaw("by_email2" /* USER_BY_EMAIL */, {
|
|
10718
|
+
limit: 0,
|
|
10719
|
+
// to be as fast as possible - we just want the total rows count
|
|
10720
|
+
include_docs: false
|
|
10721
|
+
});
|
|
10722
|
+
return response.total_rows;
|
|
10723
|
+
}
|
|
10724
|
+
async function getCreatorCount() {
|
|
10725
|
+
let creators = 0;
|
|
10726
|
+
async function iterate(startPage) {
|
|
10727
|
+
const page = await paginatedUsers({ bookmark: startPage });
|
|
10728
|
+
creators += page.data.filter(isCreator2).length;
|
|
10729
|
+
if (page.hasNextPage) {
|
|
10730
|
+
await iterate(page.nextPage);
|
|
10731
|
+
}
|
|
10732
|
+
}
|
|
10733
|
+
await iterate();
|
|
10734
|
+
return creators;
|
|
10735
|
+
}
|
|
10736
|
+
function removePortalUserPermissions(user) {
|
|
10737
|
+
delete user.admin;
|
|
10738
|
+
delete user.builder;
|
|
10739
|
+
return user;
|
|
10740
|
+
}
|
|
10741
|
+
function cleanseUserObject(user, base) {
|
|
10742
|
+
delete user.admin;
|
|
10743
|
+
delete user.builder;
|
|
10744
|
+
delete user.roles;
|
|
10745
|
+
if (base) {
|
|
10746
|
+
user.admin = base.admin;
|
|
10747
|
+
user.builder = base.builder;
|
|
10748
|
+
user.roles = base.roles;
|
|
10749
|
+
}
|
|
10750
|
+
return user;
|
|
10751
|
+
}
|
|
10752
|
+
async function addAppBuilder(user, appId) {
|
|
10753
|
+
const prodAppId = getProdAppID(appId);
|
|
10754
|
+
user.builder ??= {};
|
|
10755
|
+
user.builder.creator = true;
|
|
10756
|
+
user.builder.apps ??= [];
|
|
10757
|
+
user.builder.apps.push(prodAppId);
|
|
10758
|
+
await UserDB.save(user, { hashPassword: false });
|
|
10759
|
+
}
|
|
10760
|
+
async function removeAppBuilder(user, appId) {
|
|
10761
|
+
const prodAppId = getProdAppID(appId);
|
|
10762
|
+
if (user.builder && user.builder.apps?.includes(prodAppId)) {
|
|
10763
|
+
user.builder.apps = user.builder.apps.filter((id) => id !== prodAppId);
|
|
10764
|
+
}
|
|
10765
|
+
await UserDB.save(user, { hashPassword: false });
|
|
10766
|
+
}
|
|
10767
|
+
|
|
10742
10768
|
// src/cache/user.ts
|
|
10743
10769
|
var EXPIRY_SECONDS3 = 3600;
|
|
10744
10770
|
async function populateFromDB2(userId, tenantId) {
|
|
@@ -11334,6 +11360,7 @@ __export(permissions_exports, {
|
|
|
11334
11360
|
BUILDER: () => BUILDER,
|
|
11335
11361
|
BUILTIN_PERMISSIONS: () => BUILTIN_PERMISSIONS,
|
|
11336
11362
|
BuiltinPermissionID: () => BuiltinPermissionID,
|
|
11363
|
+
CREATOR: () => CREATOR,
|
|
11337
11364
|
GLOBAL_BUILDER: () => GLOBAL_BUILDER,
|
|
11338
11365
|
Permission: () => Permission,
|
|
11339
11366
|
PermissionLevel: () => PermissionLevel,
|
|
@@ -11474,6 +11501,7 @@ function isPermissionLevelHigherThanRead(level) {
|
|
|
11474
11501
|
return levelToNumber(level) > 1;
|
|
11475
11502
|
}
|
|
11476
11503
|
var BUILDER = "builder" /* BUILDER */;
|
|
11504
|
+
var CREATOR = "creator" /* CREATOR */;
|
|
11477
11505
|
var GLOBAL_BUILDER = "globalBuilder" /* GLOBAL_BUILDER */;
|
|
11478
11506
|
|
|
11479
11507
|
// src/security/roles.ts
|