@budibase/backend-core 2.13.14 → 2.13.16
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 +302 -242
- 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/auth/auth.js.map +1 -1
- package/dist/src/configs/configs.js +3 -4
- package/dist/src/configs/configs.js.map +1 -1
- package/dist/src/constants/db.js.map +1 -1
- package/dist/src/db/utils.js.map +1 -1
- package/dist/src/docIds/conversions.js.map +1 -1
- package/dist/src/events/processors/posthog/index.js.map +1 -1
- package/dist/src/features/index.js.map +1 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/installation.js +2 -3
- package/dist/src/installation.js.map +1 -1
- package/dist/src/logging/correlation/correlation.js.map +1 -1
- package/dist/src/logging/correlation/middleware.js.map +1 -1
- package/dist/src/logging/pino/middleware.js.map +1 -1
- package/dist/src/middleware/index.js.map +1 -1
- package/dist/src/middleware/passport/sso/google.js.map +1 -1
- package/dist/src/objectStore/objectStore.js.map +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/security/roles.js +1 -2
- package/dist/src/security/roles.js.map +1 -1
- package/dist/src/security/sessions.js.map +1 -1
- package/dist/src/users/db.d.ts +6 -1
- package/dist/src/users/db.js +29 -8
- package/dist/src/users/db.js.map +1 -1
- package/dist/src/users/users.d.ts +14 -11
- package/dist/src/users/users.js +200 -144
- package/dist/src/users/users.js.map +1 -1
- package/dist/src/utils/hashing.js.map +1 -1
- package/dist/src/utils/utils.js.map +1 -1
- package/dist/tests/core/utilities/mocks/alerts.js.map +1 -1
- package/dist/tests/core/utilities/mocks/index.js.map +1 -1
- package/dist/tests/core/utilities/structures/generator.js.map +1 -1
- package/dist/tests/jestSetup.js.map +1 -1
- package/package.json +4 -4
- package/src/auth/auth.ts +2 -0
- package/src/configs/configs.ts +3 -4
- package/src/constants/db.ts +1 -0
- package/src/db/utils.ts +1 -0
- package/src/docIds/conversions.ts +1 -0
- package/src/events/processors/posthog/index.ts +1 -0
- package/src/events/processors/posthog/tests/PosthogProcessor.spec.ts +2 -0
- package/src/features/index.ts +1 -0
- package/src/index.ts +1 -0
- package/src/installation.ts +1 -2
- package/src/logging/correlation/correlation.ts +1 -0
- package/src/logging/correlation/middleware.ts +1 -0
- package/src/logging/pino/middleware.ts +3 -0
- package/src/middleware/index.ts +1 -0
- package/src/middleware/passport/sso/google.ts +1 -0
- package/src/middleware/passport/sso/tests/google.spec.ts +1 -0
- package/src/middleware/passport/sso/tests/sso.spec.ts +1 -0
- package/src/middleware/tests/builder.spec.ts +1 -0
- package/src/objectStore/objectStore.ts +1 -0
- package/src/security/permissions.ts +1 -0
- package/src/security/roles.ts +7 -2
- package/src/security/sessions.ts +1 -0
- package/src/users/db.ts +35 -14
- package/src/users/users.ts +46 -16
- package/src/utils/hashing.ts +1 -0
- package/src/utils/utils.ts +1 -0
- package/tests/core/utilities/mocks/alerts.ts +1 -0
- package/tests/core/utilities/mocks/index.ts +1 -0
- package/tests/core/utilities/structures/generator.ts +1 -0
- package/tests/jestSetup.ts +1 -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,9 +6673,11 @@ 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,
|
|
6680
|
+
doesUserExist: () => doesUserExist,
|
|
6678
6681
|
getAccountHolderFromUserIds: () => getAccountHolderFromUserIds,
|
|
6679
6682
|
getAllUserIds: () => getAllUserIds,
|
|
6680
6683
|
getById: () => getById,
|
|
@@ -6696,6 +6699,7 @@ __export(users_exports3, {
|
|
|
6696
6699
|
isGlobalBuilder: () => isGlobalBuilder2,
|
|
6697
6700
|
isSupportedUserSearch: () => isSupportedUserSearch,
|
|
6698
6701
|
paginatedUsers: () => paginatedUsers,
|
|
6702
|
+
removeAppBuilder: () => removeAppBuilder,
|
|
6699
6703
|
removePortalUserPermissions: () => removePortalUserPermissions,
|
|
6700
6704
|
searchExistingEmails: () => searchExistingEmails,
|
|
6701
6705
|
searchGlobalUsersByApp: () => searchGlobalUsersByApp,
|
|
@@ -7306,12 +7310,14 @@ function getProdAppID2(appId) {
|
|
|
7306
7310
|
// ../shared-core/src/sdk/documents/users.ts
|
|
7307
7311
|
var users_exports2 = {};
|
|
7308
7312
|
__export(users_exports2, {
|
|
7313
|
+
canCreateApps: () => canCreateApps,
|
|
7309
7314
|
containsUserID: () => containsUserID,
|
|
7310
7315
|
getGlobalUserID: () => getGlobalUserID,
|
|
7311
7316
|
hasAdminPermissions: () => hasAdminPermissions,
|
|
7312
7317
|
hasAppBuilderPermissions: () => hasAppBuilderPermissions,
|
|
7313
7318
|
hasAppCreatorPermissions: () => hasAppCreatorPermissions,
|
|
7314
7319
|
hasBuilderPermissions: () => hasBuilderPermissions,
|
|
7320
|
+
hasCreatorPermissions: () => hasCreatorPermissions,
|
|
7315
7321
|
isAdmin: () => isAdmin,
|
|
7316
7322
|
isAdminOrBuilder: () => isAdminOrBuilder,
|
|
7317
7323
|
isAdminOrGlobalBuilder: () => isAdminOrGlobalBuilder,
|
|
@@ -7335,6 +7341,9 @@ function isBuilder(user, appId) {
|
|
|
7335
7341
|
function isGlobalBuilder(user) {
|
|
7336
7342
|
return isBuilder(user) && !hasAppBuilderPermissions(user) || isAdmin(user);
|
|
7337
7343
|
}
|
|
7344
|
+
function canCreateApps(user) {
|
|
7345
|
+
return isGlobalBuilder(user) || hasCreatorPermissions(user);
|
|
7346
|
+
}
|
|
7338
7347
|
function isAdmin(user) {
|
|
7339
7348
|
if (!user) {
|
|
7340
7349
|
return false;
|
|
@@ -7362,7 +7371,7 @@ function hasAppCreatorPermissions(user) {
|
|
|
7362
7371
|
return _.flow(
|
|
7363
7372
|
_.get("roles"),
|
|
7364
7373
|
_.values,
|
|
7365
|
-
_.find((x) =>
|
|
7374
|
+
_.find((x) => x === "CREATOR"),
|
|
7366
7375
|
(x) => !!x
|
|
7367
7376
|
)(user);
|
|
7368
7377
|
}
|
|
@@ -7370,7 +7379,7 @@ function hasBuilderPermissions(user) {
|
|
|
7370
7379
|
if (!user) {
|
|
7371
7380
|
return false;
|
|
7372
7381
|
}
|
|
7373
|
-
return user.builder?.global || hasAppBuilderPermissions(user);
|
|
7382
|
+
return user.builder?.global || hasAppBuilderPermissions(user) || hasCreatorPermissions(user);
|
|
7374
7383
|
}
|
|
7375
7384
|
function hasAdminPermissions(user) {
|
|
7376
7385
|
if (!user) {
|
|
@@ -7378,11 +7387,17 @@ function hasAdminPermissions(user) {
|
|
|
7378
7387
|
}
|
|
7379
7388
|
return !!user.admin?.global;
|
|
7380
7389
|
}
|
|
7390
|
+
function hasCreatorPermissions(user) {
|
|
7391
|
+
if (!user) {
|
|
7392
|
+
return false;
|
|
7393
|
+
}
|
|
7394
|
+
return !!user.builder?.creator;
|
|
7395
|
+
}
|
|
7381
7396
|
function isCreator(user) {
|
|
7382
7397
|
if (!user) {
|
|
7383
7398
|
return false;
|
|
7384
7399
|
}
|
|
7385
|
-
return isGlobalBuilder(user) || hasAdminPermissions(user) || hasAppBuilderPermissions(user) || hasAppCreatorPermissions(user);
|
|
7400
|
+
return isGlobalBuilder(user) || hasAdminPermissions(user) || hasCreatorPermissions(user) || hasAppBuilderPermissions(user) || hasAppCreatorPermissions(user);
|
|
7386
7401
|
}
|
|
7387
7402
|
function getGlobalUserID(userId) {
|
|
7388
7403
|
if (typeof userId !== "string") {
|
|
@@ -7477,239 +7492,6 @@ async function getAccountHolderFromUserIds(userIds) {
|
|
|
7477
7492
|
}
|
|
7478
7493
|
}
|
|
7479
7494
|
|
|
7480
|
-
// src/users/users.ts
|
|
7481
|
-
function removeUserPassword(users) {
|
|
7482
|
-
if (Array.isArray(users)) {
|
|
7483
|
-
return users.map((user) => {
|
|
7484
|
-
if (user) {
|
|
7485
|
-
delete user.password;
|
|
7486
|
-
return user;
|
|
7487
|
-
}
|
|
7488
|
-
});
|
|
7489
|
-
} else if (users) {
|
|
7490
|
-
delete users.password;
|
|
7491
|
-
return users;
|
|
7492
|
-
}
|
|
7493
|
-
return users;
|
|
7494
|
-
}
|
|
7495
|
-
var isSupportedUserSearch = (query) => {
|
|
7496
|
-
const allowed = [
|
|
7497
|
-
{ op: "string" /* STRING */, key: "email" },
|
|
7498
|
-
{ op: "equal" /* EQUAL */, key: "_id" }
|
|
7499
|
-
];
|
|
7500
|
-
for (let [key, operation] of Object.entries(query)) {
|
|
7501
|
-
if (typeof operation !== "object") {
|
|
7502
|
-
return false;
|
|
7503
|
-
}
|
|
7504
|
-
const fields = Object.keys(operation || {});
|
|
7505
|
-
if (fields.length === 0) {
|
|
7506
|
-
continue;
|
|
7507
|
-
}
|
|
7508
|
-
const allowedOperation = allowed.find(
|
|
7509
|
-
(allow) => allow.op === key && fields.length === 1 && fields[0] === allow.key
|
|
7510
|
-
);
|
|
7511
|
-
if (!allowedOperation) {
|
|
7512
|
-
return false;
|
|
7513
|
-
}
|
|
7514
|
-
}
|
|
7515
|
-
return true;
|
|
7516
|
-
};
|
|
7517
|
-
var bulkGetGlobalUsersById = async (userIds, opts) => {
|
|
7518
|
-
const db = getGlobalDB();
|
|
7519
|
-
let users = (await db.allDocs({
|
|
7520
|
-
keys: userIds,
|
|
7521
|
-
include_docs: true
|
|
7522
|
-
})).rows.map((row) => row.doc);
|
|
7523
|
-
if (opts?.cleanup) {
|
|
7524
|
-
users = removeUserPassword(users);
|
|
7525
|
-
}
|
|
7526
|
-
return users;
|
|
7527
|
-
};
|
|
7528
|
-
var getAllUserIds = async () => {
|
|
7529
|
-
const db = getGlobalDB();
|
|
7530
|
-
const startKey = `${"us" /* USER */}${SEPARATOR}`;
|
|
7531
|
-
const response = await db.allDocs({
|
|
7532
|
-
startkey: startKey,
|
|
7533
|
-
endkey: `${startKey}${UNICODE_MAX}`
|
|
7534
|
-
});
|
|
7535
|
-
return response.rows.map((row) => row.id);
|
|
7536
|
-
};
|
|
7537
|
-
var bulkUpdateGlobalUsers = async (users) => {
|
|
7538
|
-
const db = getGlobalDB();
|
|
7539
|
-
return await db.bulkDocs(users);
|
|
7540
|
-
};
|
|
7541
|
-
async function getById(id, opts) {
|
|
7542
|
-
const db = getGlobalDB();
|
|
7543
|
-
let user = await db.get(id);
|
|
7544
|
-
if (opts?.cleanup) {
|
|
7545
|
-
user = removeUserPassword(user);
|
|
7546
|
-
}
|
|
7547
|
-
return user;
|
|
7548
|
-
}
|
|
7549
|
-
var getGlobalUserByEmail = async (email, opts) => {
|
|
7550
|
-
if (email == null) {
|
|
7551
|
-
throw "Must supply an email address to view";
|
|
7552
|
-
}
|
|
7553
|
-
const response = await queryGlobalView("by_email2" /* USER_BY_EMAIL */, {
|
|
7554
|
-
key: email.toLowerCase(),
|
|
7555
|
-
include_docs: true
|
|
7556
|
-
});
|
|
7557
|
-
if (Array.isArray(response)) {
|
|
7558
|
-
throw new Error(`Multiple users found with email address: ${email}`);
|
|
7559
|
-
}
|
|
7560
|
-
let user = response;
|
|
7561
|
-
if (opts?.cleanup) {
|
|
7562
|
-
user = removeUserPassword(user);
|
|
7563
|
-
}
|
|
7564
|
-
return user;
|
|
7565
|
-
};
|
|
7566
|
-
var searchGlobalUsersByApp = async (appId, opts, getOpts) => {
|
|
7567
|
-
if (typeof appId !== "string") {
|
|
7568
|
-
throw new Error("Must provide a string based app ID");
|
|
7569
|
-
}
|
|
7570
|
-
const params2 = getUsersByAppParams(appId, {
|
|
7571
|
-
include_docs: true
|
|
7572
|
-
});
|
|
7573
|
-
params2.startkey = opts && opts.startkey ? opts.startkey : params2.startkey;
|
|
7574
|
-
let response = await queryGlobalView("by_app" /* USER_BY_APP */, params2);
|
|
7575
|
-
if (!response) {
|
|
7576
|
-
response = [];
|
|
7577
|
-
}
|
|
7578
|
-
let users = Array.isArray(response) ? response : [response];
|
|
7579
|
-
if (getOpts?.cleanup) {
|
|
7580
|
-
users = removeUserPassword(users);
|
|
7581
|
-
}
|
|
7582
|
-
return users;
|
|
7583
|
-
};
|
|
7584
|
-
var searchGlobalUsersByAppAccess = async (appId, opts) => {
|
|
7585
|
-
const roleSelector = `roles.${appId}`;
|
|
7586
|
-
let orQuery = [
|
|
7587
|
-
{
|
|
7588
|
-
"builder.global": true
|
|
7589
|
-
},
|
|
7590
|
-
{
|
|
7591
|
-
"admin.global": true
|
|
7592
|
-
}
|
|
7593
|
-
];
|
|
7594
|
-
if (appId) {
|
|
7595
|
-
const roleCheck = {
|
|
7596
|
-
[roleSelector]: {
|
|
7597
|
-
$exists: true
|
|
7598
|
-
}
|
|
7599
|
-
};
|
|
7600
|
-
orQuery.push(roleCheck);
|
|
7601
|
-
}
|
|
7602
|
-
let searchOptions = {
|
|
7603
|
-
selector: {
|
|
7604
|
-
$or: orQuery,
|
|
7605
|
-
_id: {
|
|
7606
|
-
$regex: "^us_"
|
|
7607
|
-
}
|
|
7608
|
-
},
|
|
7609
|
-
limit: opts?.limit || 50
|
|
7610
|
-
};
|
|
7611
|
-
const resp = await directCouchFind(getGlobalDBName(), searchOptions);
|
|
7612
|
-
return resp.rows;
|
|
7613
|
-
};
|
|
7614
|
-
var getGlobalUserByAppPage = (appId, user) => {
|
|
7615
|
-
if (!user) {
|
|
7616
|
-
return;
|
|
7617
|
-
}
|
|
7618
|
-
return generateAppUserID(getProdAppID(appId), user._id);
|
|
7619
|
-
};
|
|
7620
|
-
var searchGlobalUsersByEmail = async (email, opts, getOpts) => {
|
|
7621
|
-
if (typeof email !== "string") {
|
|
7622
|
-
throw new Error("Must provide a string to search by");
|
|
7623
|
-
}
|
|
7624
|
-
const lcEmail = email.toLowerCase();
|
|
7625
|
-
const startkey = opts && opts.startkey ? opts.startkey : lcEmail;
|
|
7626
|
-
let response = await queryGlobalView("by_email2" /* USER_BY_EMAIL */, {
|
|
7627
|
-
...opts,
|
|
7628
|
-
startkey,
|
|
7629
|
-
endkey: `${lcEmail}${UNICODE_MAX}`
|
|
7630
|
-
});
|
|
7631
|
-
if (!response) {
|
|
7632
|
-
response = [];
|
|
7633
|
-
}
|
|
7634
|
-
let users = Array.isArray(response) ? response : [response];
|
|
7635
|
-
if (getOpts?.cleanup) {
|
|
7636
|
-
users = removeUserPassword(users);
|
|
7637
|
-
}
|
|
7638
|
-
return users;
|
|
7639
|
-
};
|
|
7640
|
-
var PAGE_LIMIT = 8;
|
|
7641
|
-
var paginatedUsers = async ({
|
|
7642
|
-
bookmark,
|
|
7643
|
-
query,
|
|
7644
|
-
appId,
|
|
7645
|
-
limit
|
|
7646
|
-
} = {}) => {
|
|
7647
|
-
const db = getGlobalDB();
|
|
7648
|
-
const pageSize = limit ?? PAGE_LIMIT;
|
|
7649
|
-
const pageLimit = pageSize + 1;
|
|
7650
|
-
const opts = {
|
|
7651
|
-
include_docs: true,
|
|
7652
|
-
limit: pageLimit
|
|
7653
|
-
};
|
|
7654
|
-
if (bookmark) {
|
|
7655
|
-
opts.startkey = bookmark;
|
|
7656
|
-
}
|
|
7657
|
-
let userList, property = "_id", getKey;
|
|
7658
|
-
if (query?.equal?._id) {
|
|
7659
|
-
userList = [await getById(query.equal._id)];
|
|
7660
|
-
} else if (appId) {
|
|
7661
|
-
userList = await searchGlobalUsersByApp(appId, opts);
|
|
7662
|
-
getKey = (doc) => getGlobalUserByAppPage(appId, doc);
|
|
7663
|
-
} else if (query?.string?.email) {
|
|
7664
|
-
userList = await searchGlobalUsersByEmail(query?.string?.email, opts);
|
|
7665
|
-
property = "email";
|
|
7666
|
-
} else {
|
|
7667
|
-
const response = await db.allDocs(getGlobalUserParams(null, opts));
|
|
7668
|
-
userList = response.rows.map((row) => row.doc);
|
|
7669
|
-
}
|
|
7670
|
-
return pagination(userList, pageSize, {
|
|
7671
|
-
paginate: true,
|
|
7672
|
-
property,
|
|
7673
|
-
getKey
|
|
7674
|
-
});
|
|
7675
|
-
};
|
|
7676
|
-
async function getUserCount() {
|
|
7677
|
-
const response = await queryGlobalViewRaw("by_email2" /* USER_BY_EMAIL */, {
|
|
7678
|
-
limit: 0,
|
|
7679
|
-
// to be as fast as possible - we just want the total rows count
|
|
7680
|
-
include_docs: false
|
|
7681
|
-
});
|
|
7682
|
-
return response.total_rows;
|
|
7683
|
-
}
|
|
7684
|
-
async function getCreatorCount() {
|
|
7685
|
-
let creators = 0;
|
|
7686
|
-
async function iterate(startPage) {
|
|
7687
|
-
const page = await paginatedUsers({ bookmark: startPage });
|
|
7688
|
-
creators += page.data.filter(isCreator2).length;
|
|
7689
|
-
if (page.hasNextPage) {
|
|
7690
|
-
await iterate(page.nextPage);
|
|
7691
|
-
}
|
|
7692
|
-
}
|
|
7693
|
-
await iterate();
|
|
7694
|
-
return creators;
|
|
7695
|
-
}
|
|
7696
|
-
function removePortalUserPermissions(user) {
|
|
7697
|
-
delete user.admin;
|
|
7698
|
-
delete user.builder;
|
|
7699
|
-
return user;
|
|
7700
|
-
}
|
|
7701
|
-
function cleanseUserObject(user, base) {
|
|
7702
|
-
delete user.admin;
|
|
7703
|
-
delete user.builder;
|
|
7704
|
-
delete user.roles;
|
|
7705
|
-
if (base) {
|
|
7706
|
-
user.admin = base.admin;
|
|
7707
|
-
user.builder = base.builder;
|
|
7708
|
-
user.roles = base.roles;
|
|
7709
|
-
}
|
|
7710
|
-
return user;
|
|
7711
|
-
}
|
|
7712
|
-
|
|
7713
7495
|
// src/users/db.ts
|
|
7714
7496
|
init_environment2();
|
|
7715
7497
|
|
|
@@ -8425,7 +8207,6 @@ __export(installation_exports, {
|
|
|
8425
8207
|
getInstallFromDB: () => getInstallFromDB
|
|
8426
8208
|
});
|
|
8427
8209
|
init_db4();
|
|
8428
|
-
init_db4();
|
|
8429
8210
|
init_src();
|
|
8430
8211
|
init_context2();
|
|
8431
8212
|
var import_semver = __toESM(require("semver"));
|
|
@@ -10486,9 +10267,6 @@ var UserDB = class _UserDB {
|
|
|
10486
10267
|
if (!email && !_id) {
|
|
10487
10268
|
throw new Error("_id or email is required");
|
|
10488
10269
|
}
|
|
10489
|
-
if (user.builder?.apps?.length && !await _UserDB.features.isAppBuildersEnabled()) {
|
|
10490
|
-
throw new Error("Unable to update app builders, please check license");
|
|
10491
|
-
}
|
|
10492
10270
|
let dbUser;
|
|
10493
10271
|
if (_id) {
|
|
10494
10272
|
try {
|
|
@@ -10697,6 +10475,29 @@ var UserDB = class _UserDB {
|
|
|
10697
10475
|
await user_exports.invalidateUser(userId);
|
|
10698
10476
|
await invalidateSessions(userId, { reason: "deletion" });
|
|
10699
10477
|
}
|
|
10478
|
+
static async createAdminUser(email, password, tenantId, opts) {
|
|
10479
|
+
const user = {
|
|
10480
|
+
email,
|
|
10481
|
+
password,
|
|
10482
|
+
createdAt: Date.now(),
|
|
10483
|
+
roles: {},
|
|
10484
|
+
builder: {
|
|
10485
|
+
global: true
|
|
10486
|
+
},
|
|
10487
|
+
admin: {
|
|
10488
|
+
global: true
|
|
10489
|
+
},
|
|
10490
|
+
tenantId
|
|
10491
|
+
};
|
|
10492
|
+
if (opts?.ssoId) {
|
|
10493
|
+
user.ssoId = opts.ssoId;
|
|
10494
|
+
}
|
|
10495
|
+
await bustCache("checklist" /* CHECKLIST */);
|
|
10496
|
+
return await _UserDB.save(user, {
|
|
10497
|
+
hashPassword: opts?.hashPassword,
|
|
10498
|
+
requirePassword: opts?.requirePassword
|
|
10499
|
+
});
|
|
10500
|
+
}
|
|
10700
10501
|
static async getGroups(groupIds) {
|
|
10701
10502
|
return await this.groups.getBulk(groupIds);
|
|
10702
10503
|
}
|
|
@@ -10705,6 +10506,265 @@ var UserDB = class _UserDB {
|
|
|
10705
10506
|
}
|
|
10706
10507
|
};
|
|
10707
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
|
+
|
|
10708
10768
|
// src/cache/user.ts
|
|
10709
10769
|
var EXPIRY_SECONDS3 = 3600;
|
|
10710
10770
|
async function populateFromDB2(userId, tenantId) {
|
|
@@ -10934,7 +10994,6 @@ async function getCode2(code) {
|
|
|
10934
10994
|
// src/configs/configs.ts
|
|
10935
10995
|
init_context2();
|
|
10936
10996
|
init_environment2();
|
|
10937
|
-
init_environment2();
|
|
10938
10997
|
function generateConfigID(type) {
|
|
10939
10998
|
return `${"config" /* CONFIG */}${SEPARATOR}${type}`;
|
|
10940
10999
|
}
|
|
@@ -11301,6 +11360,7 @@ __export(permissions_exports, {
|
|
|
11301
11360
|
BUILDER: () => BUILDER,
|
|
11302
11361
|
BUILTIN_PERMISSIONS: () => BUILTIN_PERMISSIONS,
|
|
11303
11362
|
BuiltinPermissionID: () => BuiltinPermissionID,
|
|
11363
|
+
CREATOR: () => CREATOR,
|
|
11304
11364
|
GLOBAL_BUILDER: () => GLOBAL_BUILDER,
|
|
11305
11365
|
Permission: () => Permission,
|
|
11306
11366
|
PermissionLevel: () => PermissionLevel,
|
|
@@ -11441,12 +11501,12 @@ function isPermissionLevelHigherThanRead(level) {
|
|
|
11441
11501
|
return levelToNumber(level) > 1;
|
|
11442
11502
|
}
|
|
11443
11503
|
var BUILDER = "builder" /* BUILDER */;
|
|
11504
|
+
var CREATOR = "creator" /* CREATOR */;
|
|
11444
11505
|
var GLOBAL_BUILDER = "globalBuilder" /* GLOBAL_BUILDER */;
|
|
11445
11506
|
|
|
11446
11507
|
// src/security/roles.ts
|
|
11447
11508
|
init_db4();
|
|
11448
11509
|
init_context2();
|
|
11449
|
-
init_db4();
|
|
11450
11510
|
var import_cloneDeep2 = __toESM(require("lodash/fp/cloneDeep"));
|
|
11451
11511
|
var BUILTIN_ROLE_IDS = {
|
|
11452
11512
|
ADMIN: "ADMIN",
|