@budibase/backend-core 2.10.12-alpha.7 → 2.10.13

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.
@@ -1,22 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ssoUser = exports.appBuilderUser = exports.builderUser = exports.adminOnlyUser = exports.adminUser = exports.user = exports.newEmail = void 0;
3
+ exports.ssoUser = exports.appBuilderUser = exports.builderUser = exports.adminOnlyUser = exports.adminUser = exports.newEmail = exports.user = void 0;
4
+ const shared_1 = require("./shared");
4
5
  const sso_1 = require("./sso");
5
- const common_1 = require("./common");
6
- const generator_1 = require("./generator");
7
- const _1 = require(".");
8
- const docIds_1 = require("../../../../src/docIds");
9
- const newEmail = () => {
10
- return `${(0, common_1.uuid)()}@test.com`;
11
- };
12
- exports.newEmail = newEmail;
13
- const user = (userProps) => {
14
- const userId = (userProps === null || userProps === void 0 ? void 0 : userProps._id) || (0, docIds_1.generateGlobalUserID)();
15
- return Object.assign({ _id: userId, userId, email: (0, exports.newEmail)(), password: "test", roles: { app_test: "admin" }, firstName: generator_1.generator.first(), lastName: generator_1.generator.last(), pictureUrl: "http://test.com", tenantId: _1.tenant.id() }, userProps);
16
- };
17
- exports.user = user;
6
+ var shared_2 = require("./shared");
7
+ Object.defineProperty(exports, "user", { enumerable: true, get: function () { return shared_2.user; } });
8
+ Object.defineProperty(exports, "newEmail", { enumerable: true, get: function () { return shared_2.newEmail; } });
18
9
  const adminUser = (userProps) => {
19
- return Object.assign(Object.assign({}, (0, exports.user)(userProps)), { admin: {
10
+ return Object.assign(Object.assign({}, (0, shared_1.user)(userProps)), { admin: {
20
11
  global: true,
21
12
  }, builder: {
22
13
  global: true,
@@ -24,26 +15,26 @@ const adminUser = (userProps) => {
24
15
  };
25
16
  exports.adminUser = adminUser;
26
17
  const adminOnlyUser = (userProps) => {
27
- return Object.assign(Object.assign({}, (0, exports.user)(userProps)), { admin: {
18
+ return Object.assign(Object.assign({}, (0, shared_1.user)(userProps)), { admin: {
28
19
  global: true,
29
20
  } });
30
21
  };
31
22
  exports.adminOnlyUser = adminOnlyUser;
32
23
  const builderUser = (userProps) => {
33
- return Object.assign(Object.assign({}, (0, exports.user)(userProps)), { builder: {
24
+ return Object.assign(Object.assign({}, (0, shared_1.user)(userProps)), { builder: {
34
25
  global: true,
35
26
  } });
36
27
  };
37
28
  exports.builderUser = builderUser;
38
29
  const appBuilderUser = (appId, userProps) => {
39
- return Object.assign(Object.assign({}, (0, exports.user)(userProps)), { builder: {
30
+ return Object.assign(Object.assign({}, (0, shared_1.user)(userProps)), { builder: {
40
31
  apps: [appId],
41
32
  } });
42
33
  };
43
34
  exports.appBuilderUser = appBuilderUser;
44
35
  function ssoUser(opts = {}) {
45
36
  var _a, _b, _c;
46
- const base = (0, exports.user)(opts.user);
37
+ const base = (0, shared_1.user)(opts.user);
47
38
  delete base.password;
48
39
  if (!opts.details) {
49
40
  opts.details = (0, sso_1.authDetails)(base);
@@ -1 +1 @@
1
- {"version":3,"file":"users.js","sourceRoot":"","sources":["../../../../../tests/core/utilities/structures/users.ts"],"names":[],"mappings":";;;AAQA,+BAAmC;AACnC,qCAA+B;AAC/B,2CAAuC;AACvC,wBAA0B;AAC1B,mDAA6D;AAEtD,MAAM,QAAQ,GAAG,GAAG,EAAE;IAC3B,OAAO,GAAG,IAAA,aAAI,GAAE,WAAW,CAAA;AAC7B,CAAC,CAAA;AAFY,QAAA,QAAQ,YAEpB;AAEM,MAAM,IAAI,GAAG,CAAC,SAAyC,EAAQ,EAAE;IACtE,MAAM,MAAM,GAAG,CAAA,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,GAAG,KAAI,IAAA,6BAAoB,GAAE,CAAA;IACvD,uBACE,GAAG,EAAE,MAAM,EACX,MAAM,EACN,KAAK,EAAE,IAAA,gBAAQ,GAAE,EACjB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,EAC5B,SAAS,EAAE,qBAAS,CAAC,KAAK,EAAE,EAC5B,QAAQ,EAAE,qBAAS,CAAC,IAAI,EAAE,EAC1B,UAAU,EAAE,iBAAiB,EAC7B,QAAQ,EAAE,SAAM,CAAC,EAAE,EAAE,IAClB,SAAS,EACb;AACH,CAAC,CAAA;AAdY,QAAA,IAAI,QAchB;AAEM,MAAM,SAAS,GAAG,CAAC,SAAe,EAAa,EAAE;IACtD,uCACK,IAAA,YAAI,EAAC,SAAS,CAAC,KAClB,KAAK,EAAE;YACL,MAAM,EAAE,IAAI;SACb,EACD,OAAO,EAAE;YACP,MAAM,EAAE,IAAI;SACb,IACF;AACH,CAAC,CAAA;AAVY,QAAA,SAAS,aAUrB;AAEM,MAAM,aAAa,GAAG,CAAC,SAAe,EAAiB,EAAE;IAC9D,uCACK,IAAA,YAAI,EAAC,SAAS,CAAC,KAClB,KAAK,EAAE;YACL,MAAM,EAAE,IAAI;SACb,IACF;AACH,CAAC,CAAA;AAPY,QAAA,aAAa,iBAOzB;AAEM,MAAM,WAAW,GAAG,CAAC,SAAe,EAAe,EAAE;IAC1D,uCACK,IAAA,YAAI,EAAC,SAAS,CAAC,KAClB,OAAO,EAAE;YACP,MAAM,EAAE,IAAI;SACb,IACF;AACH,CAAC,CAAA;AAPY,QAAA,WAAW,eAOvB;AAEM,MAAM,cAAc,GAAG,CAAC,KAAa,EAAE,SAAe,EAAe,EAAE;IAC5E,uCACK,IAAA,YAAI,EAAC,SAAS,CAAC,KAClB,OAAO,EAAE;YACP,IAAI,EAAE,CAAC,KAAK,CAAC;SACd,IACF;AACH,CAAC,CAAA;AAPY,QAAA,cAAc,kBAO1B;AAED,SAAgB,OAAO,CACrB,OAAiD,EAAE;;IAEnD,MAAM,IAAI,GAAG,IAAA,YAAI,EAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAC5B,OAAO,IAAI,CAAC,QAAQ,CAAA;IAEpB,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;QACjB,IAAI,CAAC,OAAO,GAAG,IAAA,iBAAW,EAAC,IAAI,CAAC,CAAA;KACjC;IAED,uCACK,IAAI,KACP,kBAAkB,EAAE,KAAK,EACzB,MAAM,EAAE,MAAA,IAAI,CAAC,OAAO,0CAAE,MAAM,EAC5B,QAAQ,EAAE,MAAA,IAAI,CAAC,OAAO,0CAAE,QAAS,EACjC,YAAY,EAAE,MAAA,IAAI,CAAC,OAAO,0CAAE,YAAa,EACzC,iBAAiB,EAAE;YACjB,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,OAAO,EAAE,IAAI,CAAC,UAAU;SACzB,IACF;AACH,CAAC;AArBD,0BAqBC"}
1
+ {"version":3,"file":"users.js","sourceRoot":"","sources":["../../../../../tests/core/utilities/structures/users.ts"],"names":[],"mappings":";;;AAOA,qCAA+B;AAC/B,+BAAmC;AAEnC,mCAAyC;AAAhC,8FAAA,IAAI,OAAA;AAAE,kGAAA,QAAQ,OAAA;AAEhB,MAAM,SAAS,GAAG,CAAC,SAAe,EAAa,EAAE;IACtD,uCACK,IAAA,aAAI,EAAC,SAAS,CAAC,KAClB,KAAK,EAAE;YACL,MAAM,EAAE,IAAI;SACb,EACD,OAAO,EAAE;YACP,MAAM,EAAE,IAAI;SACb,IACF;AACH,CAAC,CAAA;AAVY,QAAA,SAAS,aAUrB;AAEM,MAAM,aAAa,GAAG,CAAC,SAAe,EAAiB,EAAE;IAC9D,uCACK,IAAA,aAAI,EAAC,SAAS,CAAC,KAClB,KAAK,EAAE;YACL,MAAM,EAAE,IAAI;SACb,IACF;AACH,CAAC,CAAA;AAPY,QAAA,aAAa,iBAOzB;AAEM,MAAM,WAAW,GAAG,CAAC,SAAe,EAAe,EAAE;IAC1D,uCACK,IAAA,aAAI,EAAC,SAAS,CAAC,KAClB,OAAO,EAAE;YACP,MAAM,EAAE,IAAI;SACb,IACF;AACH,CAAC,CAAA;AAPY,QAAA,WAAW,eAOvB;AAEM,MAAM,cAAc,GAAG,CAAC,KAAa,EAAE,SAAe,EAAe,EAAE;IAC5E,uCACK,IAAA,aAAI,EAAC,SAAS,CAAC,KAClB,OAAO,EAAE;YACP,IAAI,EAAE,CAAC,KAAK,CAAC;SACd,IACF;AACH,CAAC,CAAA;AAPY,QAAA,cAAc,kBAO1B;AAED,SAAgB,OAAO,CACrB,OAAiD,EAAE;;IAEnD,MAAM,IAAI,GAAG,IAAA,aAAI,EAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAC5B,OAAO,IAAI,CAAC,QAAQ,CAAA;IAEpB,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;QACjB,IAAI,CAAC,OAAO,GAAG,IAAA,iBAAW,EAAC,IAAI,CAAC,CAAA;KACjC;IAED,uCACK,IAAI,KACP,kBAAkB,EAAE,KAAK,EACzB,MAAM,EAAE,MAAA,IAAI,CAAC,OAAO,0CAAE,MAAM,EAC5B,QAAQ,EAAE,MAAA,IAAI,CAAC,OAAO,0CAAE,QAAS,EACjC,YAAY,EAAE,MAAA,IAAI,CAAC,OAAO,0CAAE,YAAa,EACzC,iBAAiB,EAAE;YACjB,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,OAAO,EAAE,IAAI,CAAC,UAAU;SACzB,IACF;AACH,CAAC;AArBD,0BAqBC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@budibase/backend-core",
3
- "version": "2.10.12-alpha.7",
3
+ "version": "2.10.13",
4
4
  "description": "Budibase backend core libraries used in server and worker",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/src/index.d.ts",
@@ -23,8 +23,8 @@
23
23
  "dependencies": {
24
24
  "@budibase/nano": "10.1.2",
25
25
  "@budibase/pouchdb-replication-stream": "1.2.10",
26
- "@budibase/shared-core": "2.10.12-alpha.7",
27
- "@budibase/types": "2.10.12-alpha.7",
26
+ "@budibase/shared-core": "2.10.13",
27
+ "@budibase/types": "2.10.13",
28
28
  "@techpass/passport-openidconnect": "0.3.2",
29
29
  "aws-cloudfront-sign": "2.2.0",
30
30
  "aws-sdk": "2.1030.0",
@@ -104,5 +104,5 @@
104
104
  }
105
105
  }
106
106
  },
107
- "gitHead": "e2871f7aa235a78a2ddfe0f812230b29f0d7eb2c"
107
+ "gitHead": "7e1cbbee9097e5eb78fa3be111833c1a5378cb84"
108
108
  }
package/src/cache/user.ts CHANGED
@@ -6,7 +6,6 @@ import env from "../environment"
6
6
  import * as accounts from "../accounts"
7
7
  import { UserDB } from "../users"
8
8
  import { sdk } from "@budibase/shared-core"
9
- import { User } from "@budibase/types"
10
9
 
11
10
  const EXPIRY_SECONDS = 3600
12
11
 
@@ -28,35 +27,6 @@ async function populateFromDB(userId: string, tenantId: string) {
28
27
  return user
29
28
  }
30
29
 
31
- async function populateUsersFromDB(
32
- userIds: string[]
33
- ): Promise<{ users: User[]; notFoundIds?: string[] }> {
34
- const getUsersResponse = await UserDB.bulkGet(userIds)
35
-
36
- // Handle missed user ids
37
- const notFoundIds = userIds.filter((uid, i) => !getUsersResponse[i])
38
-
39
- const users = getUsersResponse.filter(x => x)
40
-
41
- await Promise.all(
42
- users.map(async (user: any) => {
43
- user.budibaseAccess = true
44
- if (!env.SELF_HOSTED && !env.DISABLE_ACCOUNT_PORTAL) {
45
- const account = await accounts.getAccount(user.email)
46
- if (account) {
47
- user.account = account
48
- user.accountPortalAccess = true
49
- }
50
- }
51
- })
52
- )
53
-
54
- if (notFoundIds.length) {
55
- return { users, notFoundIds }
56
- }
57
- return { users }
58
- }
59
-
60
30
  /**
61
31
  * Get the requested user by id.
62
32
  * Use redis cache to first read the user.
@@ -107,36 +77,6 @@ export async function getUser(
107
77
  return user
108
78
  }
109
79
 
110
- /**
111
- * Get the requested users by id.
112
- * Use redis cache to first read the users.
113
- * If not present fallback to loading the users directly and re-caching.
114
- * @param {*} userIds the ids of the user to get
115
- * @param {*} tenantId the tenant of the users to get
116
- * @returns
117
- */
118
- export async function getUsers(
119
- userIds: string[]
120
- ): Promise<{ users: User[]; notFoundIds?: string[] }> {
121
- const client = await redis.getUserClient()
122
- // try cache
123
- let usersFromCache = await client.bulkGet(userIds)
124
- const missingUsersFromCache = userIds.filter(uid => !usersFromCache[uid])
125
- const users = Object.values(usersFromCache)
126
- let notFoundIds
127
-
128
- if (missingUsersFromCache.length) {
129
- const usersFromDb = await populateUsersFromDB(missingUsersFromCache)
130
-
131
- notFoundIds = usersFromDb.notFoundIds
132
- for (const userToCache of usersFromDb.users) {
133
- await client.store(userToCache._id!, userToCache, EXPIRY_SECONDS)
134
- }
135
- users.push(...usersFromDb.users)
136
- }
137
- return { users, notFoundIds: notFoundIds }
138
- }
139
-
140
80
  export async function invalidateUser(userId: string) {
141
81
  const client = await redis.getUserClient()
142
82
  await client.delete(userId)
@@ -102,7 +102,6 @@ describe("sso", () => {
102
102
 
103
103
  // modified external id to match user format
104
104
  ssoUser._id = "us_" + details.userId
105
- delete ssoUser.userId
106
105
 
107
106
  // new sso user won't have a password
108
107
  delete ssoUser.password
@@ -250,7 +250,7 @@ class RedisWrapper {
250
250
  const prefixedKeys = keys.map(key => addDbPrefix(db, key))
251
251
  let response = await this.getClient().mget(prefixedKeys)
252
252
  if (Array.isArray(response)) {
253
- let final: Record<string, any> = {}
253
+ let final: any = {}
254
254
  let count = 0
255
255
  for (let result of response) {
256
256
  if (result) {
@@ -0,0 +1,19 @@
1
+ import { User } from "@budibase/types"
2
+ import { generator } from "./generator"
3
+ import { uuid } from "./common"
4
+
5
+ export const newEmail = () => {
6
+ return `${uuid()}@test.com`
7
+ }
8
+
9
+ export const user = (userProps?: any): User => {
10
+ return {
11
+ email: newEmail(),
12
+ password: "test",
13
+ roles: { app_test: "admin" },
14
+ firstName: generator.first(),
15
+ lastName: generator.last(),
16
+ pictureUrl: "http://test.com",
17
+ ...userProps,
18
+ }
19
+ }
@@ -13,7 +13,8 @@ import {
13
13
  } from "@budibase/types"
14
14
  import { generator } from "./generator"
15
15
  import { email, uuid } from "./common"
16
- import * as users from "./users"
16
+ import * as shared from "./shared"
17
+ import { user } from "./shared"
17
18
  import sample from "lodash/sample"
18
19
 
19
20
  export function OAuth(): OAuth2 {
@@ -25,7 +26,7 @@ export function OAuth(): OAuth2 {
25
26
 
26
27
  export function authDetails(userDoc?: User): SSOAuthDetails {
27
28
  if (!userDoc) {
28
- userDoc = users.user()
29
+ userDoc = user()
29
30
  }
30
31
 
31
32
  const userId = userDoc._id || uuid()
@@ -51,7 +52,7 @@ export function providerType(): SSOProviderType {
51
52
 
52
53
  export function ssoProfile(user?: User): SSOProfile {
53
54
  if (!user) {
54
- user = users.user()
55
+ user = shared.user()
55
56
  }
56
57
  return {
57
58
  id: user._id!,
@@ -4,33 +4,11 @@ import {
4
4
  BuilderUser,
5
5
  SSOAuthDetails,
6
6
  SSOUser,
7
- User,
8
7
  } from "@budibase/types"
8
+ import { user } from "./shared"
9
9
  import { authDetails } from "./sso"
10
- import { uuid } from "./common"
11
- import { generator } from "./generator"
12
- import { tenant } from "."
13
- import { generateGlobalUserID } from "../../../../src/docIds"
14
10
 
15
- export const newEmail = () => {
16
- return `${uuid()}@test.com`
17
- }
18
-
19
- export const user = (userProps?: Partial<Omit<User, "userId">>): User => {
20
- const userId = userProps?._id || generateGlobalUserID()
21
- return {
22
- _id: userId,
23
- userId,
24
- email: newEmail(),
25
- password: "test",
26
- roles: { app_test: "admin" },
27
- firstName: generator.first(),
28
- lastName: generator.last(),
29
- pictureUrl: "http://test.com",
30
- tenantId: tenant.id(),
31
- ...userProps,
32
- }
33
- }
11
+ export { user, newEmail } from "./shared"
34
12
 
35
13
  export const adminUser = (userProps?: any): AdminUser => {
36
14
  return {
@@ -1,145 +0,0 @@
1
- import { User } from "@budibase/types"
2
- import { generator, structures } from "../../../tests"
3
- import { DBTestConfiguration } from "../../../tests/extra"
4
- import { getUsers } from "../user"
5
- import { getGlobalDB } from "../../context"
6
- import _ from "lodash"
7
-
8
- import * as redis from "../../redis/init"
9
- import { UserDB } from "../../users"
10
-
11
- const config = new DBTestConfiguration()
12
-
13
- describe("user cache", () => {
14
- describe("getUsers", () => {
15
- const users: User[] = []
16
- beforeAll(async () => {
17
- const userCount = 10
18
- const userIds = generator.arrayOf(() => generator.guid(), {
19
- min: userCount,
20
- max: userCount,
21
- })
22
-
23
- await config.doInTenant(async () => {
24
- const db = getGlobalDB()
25
- for (const userId of userIds) {
26
- const user = structures.users.user({ _id: userId })
27
- await db.put(user)
28
- users.push(user)
29
- }
30
- })
31
- })
32
-
33
- beforeEach(async () => {
34
- jest.clearAllMocks()
35
-
36
- const redisClient = await redis.getUserClient()
37
- await redisClient.clear()
38
- })
39
-
40
- it("when no user is in cache, all of them are retrieved from db", async () => {
41
- const usersToRequest = _.sampleSize(users, 5)
42
-
43
- const userIdsToRequest = usersToRequest.map(x => x._id!)
44
-
45
- jest.spyOn(UserDB, "bulkGet")
46
-
47
- const results = await config.doInTenant(() => getUsers(userIdsToRequest))
48
-
49
- expect(results.users).toHaveLength(5)
50
- expect(results).toEqual({
51
- users: usersToRequest.map(u => ({
52
- ...u,
53
- budibaseAccess: true,
54
- _rev: expect.any(String),
55
- })),
56
- })
57
-
58
- expect(UserDB.bulkGet).toBeCalledTimes(1)
59
- expect(UserDB.bulkGet).toBeCalledWith(userIdsToRequest)
60
- })
61
-
62
- it("on a second all, all of them are retrieved from cache", async () => {
63
- const usersToRequest = _.sampleSize(users, 5)
64
-
65
- const userIdsToRequest = usersToRequest.map(x => x._id!)
66
-
67
- jest.spyOn(UserDB, "bulkGet")
68
-
69
- await config.doInTenant(() => getUsers(userIdsToRequest))
70
- const resultsFromCache = await config.doInTenant(() =>
71
- getUsers(userIdsToRequest)
72
- )
73
-
74
- expect(resultsFromCache.users).toHaveLength(5)
75
- expect(resultsFromCache).toEqual({
76
- users: expect.arrayContaining(
77
- usersToRequest.map(u => ({
78
- ...u,
79
- budibaseAccess: true,
80
- _rev: expect.any(String),
81
- }))
82
- ),
83
- })
84
-
85
- expect(UserDB.bulkGet).toBeCalledTimes(1)
86
- })
87
-
88
- it("when some users are cached, only the missing ones are retrieved from db", async () => {
89
- const usersToRequest = _.sampleSize(users, 5)
90
-
91
- const userIdsToRequest = usersToRequest.map(x => x._id!)
92
-
93
- jest.spyOn(UserDB, "bulkGet")
94
-
95
- await config.doInTenant(() =>
96
- getUsers([userIdsToRequest[0], userIdsToRequest[3]])
97
- )
98
- ;(UserDB.bulkGet as jest.Mock).mockClear()
99
-
100
- const results = await config.doInTenant(() => getUsers(userIdsToRequest))
101
-
102
- expect(results.users).toHaveLength(5)
103
- expect(results).toEqual({
104
- users: expect.arrayContaining(
105
- usersToRequest.map(u => ({
106
- ...u,
107
- budibaseAccess: true,
108
- _rev: expect.any(String),
109
- }))
110
- ),
111
- })
112
-
113
- expect(UserDB.bulkGet).toBeCalledTimes(1)
114
- expect(UserDB.bulkGet).toBeCalledWith([
115
- userIdsToRequest[1],
116
- userIdsToRequest[2],
117
- userIdsToRequest[4],
118
- ])
119
- })
120
-
121
- it("requesting existing and unexisting ids will return found ones", async () => {
122
- const usersToRequest = _.sampleSize(users, 3)
123
- const missingIds = [generator.guid(), generator.guid()]
124
-
125
- const userIdsToRequest = _.shuffle([
126
- ...missingIds,
127
- ...usersToRequest.map(x => x._id!),
128
- ])
129
-
130
- const results = await config.doInTenant(() => getUsers(userIdsToRequest))
131
-
132
- expect(results.users).toHaveLength(3)
133
- expect(results).toEqual({
134
- users: expect.arrayContaining(
135
- usersToRequest.map(u => ({
136
- ...u,
137
- budibaseAccess: true,
138
- _rev: expect.any(String),
139
- }))
140
- ),
141
- notFoundIds: expect.arrayContaining(missingIds),
142
- })
143
- })
144
- })
145
- })