@budibase/backend-core 3.2.5 → 3.2.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (276) hide show
  1. package/dist/index.js +7 -1
  2. package/dist/index.js.map +2 -2
  3. package/dist/index.js.meta.json +1 -1
  4. package/dist/package.json +11 -4
  5. package/dist/plugins.js.meta.json +1 -1
  6. package/dist/src/environment.d.ts +1 -0
  7. package/dist/src/environment.js +6 -1
  8. package/dist/src/environment.js.map +1 -1
  9. package/package.json +11 -4
  10. package/src/accounts/accounts.ts +0 -82
  11. package/src/accounts/api.ts +0 -59
  12. package/src/accounts/index.ts +0 -1
  13. package/src/auth/auth.ts +0 -210
  14. package/src/auth/index.ts +0 -1
  15. package/src/auth/tests/auth.spec.ts +0 -14
  16. package/src/blacklist/blacklist.ts +0 -54
  17. package/src/blacklist/index.ts +0 -1
  18. package/src/blacklist/tests/blacklist.spec.ts +0 -46
  19. package/src/cache/appMetadata.ts +0 -88
  20. package/src/cache/base/index.ts +0 -150
  21. package/src/cache/docWritethrough.ts +0 -105
  22. package/src/cache/generic.ts +0 -33
  23. package/src/cache/index.ts +0 -8
  24. package/src/cache/invite.ts +0 -86
  25. package/src/cache/passwordReset.ts +0 -49
  26. package/src/cache/tests/docWritethrough.spec.ts +0 -296
  27. package/src/cache/tests/user.spec.ts +0 -145
  28. package/src/cache/tests/writethrough.spec.ts +0 -139
  29. package/src/cache/user.ts +0 -154
  30. package/src/cache/writethrough.ts +0 -133
  31. package/src/configs/configs.ts +0 -263
  32. package/src/configs/index.ts +0 -1
  33. package/src/configs/tests/configs.spec.ts +0 -184
  34. package/src/constants/db.ts +0 -75
  35. package/src/constants/index.ts +0 -2
  36. package/src/constants/misc.ts +0 -36
  37. package/src/context/Context.ts +0 -14
  38. package/src/context/identity.ts +0 -58
  39. package/src/context/index.ts +0 -3
  40. package/src/context/mainContext.ts +0 -422
  41. package/src/context/tests/index.spec.ts +0 -255
  42. package/src/context/types.ts +0 -26
  43. package/src/db/Replication.ts +0 -94
  44. package/src/db/couch/DatabaseImpl.ts +0 -511
  45. package/src/db/couch/connections.ts +0 -89
  46. package/src/db/couch/index.ts +0 -4
  47. package/src/db/couch/pouchDB.ts +0 -97
  48. package/src/db/couch/pouchDump.ts +0 -0
  49. package/src/db/couch/tests/DatabaseImpl.spec.ts +0 -118
  50. package/src/db/couch/utils.ts +0 -55
  51. package/src/db/db.ts +0 -34
  52. package/src/db/errors.ts +0 -14
  53. package/src/db/index.ts +0 -12
  54. package/src/db/instrumentation.ts +0 -199
  55. package/src/db/lucene.ts +0 -721
  56. package/src/db/searchIndexes/index.ts +0 -1
  57. package/src/db/searchIndexes/searchIndexes.ts +0 -62
  58. package/src/db/tests/DatabaseImpl.spec.ts +0 -55
  59. package/src/db/tests/connections.spec.ts +0 -22
  60. package/src/db/tests/index.spec.ts +0 -32
  61. package/src/db/tests/lucene.spec.ts +0 -400
  62. package/src/db/tests/pouch.spec.js +0 -62
  63. package/src/db/tests/utils.spec.ts +0 -63
  64. package/src/db/utils.ts +0 -208
  65. package/src/db/views.ts +0 -245
  66. package/src/docIds/conversions.ts +0 -60
  67. package/src/docIds/ids.ts +0 -126
  68. package/src/docIds/index.ts +0 -2
  69. package/src/docIds/newid.ts +0 -5
  70. package/src/docIds/params.ts +0 -189
  71. package/src/docUpdates/index.ts +0 -24
  72. package/src/environment.ts +0 -293
  73. package/src/errors/errors.ts +0 -119
  74. package/src/errors/index.ts +0 -1
  75. package/src/events/analytics.ts +0 -6
  76. package/src/events/asyncEvents/index.ts +0 -2
  77. package/src/events/asyncEvents/publisher.ts +0 -12
  78. package/src/events/asyncEvents/queue.ts +0 -22
  79. package/src/events/backfill.ts +0 -183
  80. package/src/events/documentId.ts +0 -56
  81. package/src/events/events.ts +0 -47
  82. package/src/events/identification.ts +0 -311
  83. package/src/events/index.ts +0 -15
  84. package/src/events/processors/AnalyticsProcessor.ts +0 -64
  85. package/src/events/processors/AuditLogsProcessor.ts +0 -92
  86. package/src/events/processors/LoggingProcessor.ts +0 -36
  87. package/src/events/processors/Processors.ts +0 -52
  88. package/src/events/processors/async/DocumentUpdateProcessor.ts +0 -38
  89. package/src/events/processors/index.ts +0 -19
  90. package/src/events/processors/posthog/PosthogProcessor.ts +0 -118
  91. package/src/events/processors/posthog/index.ts +0 -3
  92. package/src/events/processors/posthog/rateLimiting.ts +0 -106
  93. package/src/events/processors/posthog/tests/PosthogProcessor.spec.ts +0 -164
  94. package/src/events/processors/types.ts +0 -1
  95. package/src/events/publishers/account.ts +0 -41
  96. package/src/events/publishers/ai.ts +0 -21
  97. package/src/events/publishers/app.ts +0 -168
  98. package/src/events/publishers/auditLog.ts +0 -26
  99. package/src/events/publishers/auth.ts +0 -73
  100. package/src/events/publishers/automation.ts +0 -110
  101. package/src/events/publishers/backfill.ts +0 -74
  102. package/src/events/publishers/backup.ts +0 -42
  103. package/src/events/publishers/datasource.ts +0 -48
  104. package/src/events/publishers/email.ts +0 -17
  105. package/src/events/publishers/environmentVariable.ts +0 -38
  106. package/src/events/publishers/group.ts +0 -99
  107. package/src/events/publishers/index.ts +0 -25
  108. package/src/events/publishers/installation.ts +0 -38
  109. package/src/events/publishers/layout.ts +0 -26
  110. package/src/events/publishers/license.ts +0 -84
  111. package/src/events/publishers/org.ts +0 -37
  112. package/src/events/publishers/plugin.ts +0 -47
  113. package/src/events/publishers/query.ts +0 -89
  114. package/src/events/publishers/role.ts +0 -62
  115. package/src/events/publishers/rows.ts +0 -29
  116. package/src/events/publishers/screen.ts +0 -36
  117. package/src/events/publishers/serve.ts +0 -43
  118. package/src/events/publishers/table.ts +0 -70
  119. package/src/events/publishers/user.ts +0 -202
  120. package/src/events/publishers/view.ts +0 -107
  121. package/src/features/features.ts +0 -277
  122. package/src/features/index.ts +0 -2
  123. package/src/features/tests/features.spec.ts +0 -267
  124. package/src/features/tests/utils.ts +0 -64
  125. package/src/helpers.ts +0 -9
  126. package/src/index.ts +0 -59
  127. package/src/installation.ts +0 -115
  128. package/src/logging/alerts.ts +0 -26
  129. package/src/logging/correlation/correlation.ts +0 -15
  130. package/src/logging/correlation/index.ts +0 -1
  131. package/src/logging/correlation/middleware.ts +0 -18
  132. package/src/logging/index.ts +0 -4
  133. package/src/logging/pino/logger.ts +0 -239
  134. package/src/logging/pino/middleware.ts +0 -48
  135. package/src/logging/system.ts +0 -81
  136. package/src/logging/tests/system.spec.ts +0 -61
  137. package/src/middleware/adminOnly.ts +0 -9
  138. package/src/middleware/auditLog.ts +0 -6
  139. package/src/middleware/authenticated.ts +0 -247
  140. package/src/middleware/builderOnly.ts +0 -21
  141. package/src/middleware/builderOrAdmin.ts +0 -21
  142. package/src/middleware/contentSecurityPolicy.ts +0 -113
  143. package/src/middleware/csrf.ts +0 -81
  144. package/src/middleware/errorHandling.ts +0 -43
  145. package/src/middleware/index.ts +0 -24
  146. package/src/middleware/internalApi.ts +0 -23
  147. package/src/middleware/ip.ts +0 -12
  148. package/src/middleware/joi-validator.ts +0 -58
  149. package/src/middleware/matchers.ts +0 -39
  150. package/src/middleware/passport/datasource/google.ts +0 -102
  151. package/src/middleware/passport/local.ts +0 -54
  152. package/src/middleware/passport/sso/google.ts +0 -77
  153. package/src/middleware/passport/sso/oidc.ts +0 -152
  154. package/src/middleware/passport/sso/sso.ts +0 -138
  155. package/src/middleware/passport/sso/tests/google.spec.ts +0 -68
  156. package/src/middleware/passport/sso/tests/oidc.spec.ts +0 -144
  157. package/src/middleware/passport/sso/tests/sso.spec.ts +0 -197
  158. package/src/middleware/passport/utils.ts +0 -38
  159. package/src/middleware/querystringToBody.ts +0 -28
  160. package/src/middleware/tenancy.ts +0 -36
  161. package/src/middleware/tests/builder.spec.ts +0 -181
  162. package/src/middleware/tests/contentSecurityPolicy.spec.ts +0 -75
  163. package/src/middleware/tests/matchers.spec.ts +0 -100
  164. package/src/migrations/definitions.ts +0 -40
  165. package/src/migrations/index.ts +0 -2
  166. package/src/migrations/migrations.ts +0 -186
  167. package/src/migrations/tests/__snapshots__/migrations.spec.ts.snap +0 -11
  168. package/src/migrations/tests/migrations.spec.ts +0 -64
  169. package/src/objectStore/buckets/app.ts +0 -53
  170. package/src/objectStore/buckets/global.ts +0 -29
  171. package/src/objectStore/buckets/index.ts +0 -3
  172. package/src/objectStore/buckets/plugins.ts +0 -71
  173. package/src/objectStore/buckets/tests/app.spec.ts +0 -161
  174. package/src/objectStore/buckets/tests/global.spec.ts +0 -74
  175. package/src/objectStore/buckets/tests/plugins.spec.ts +0 -111
  176. package/src/objectStore/cloudfront.ts +0 -41
  177. package/src/objectStore/index.ts +0 -3
  178. package/src/objectStore/objectStore.ts +0 -585
  179. package/src/objectStore/utils.ts +0 -113
  180. package/src/platform/index.ts +0 -3
  181. package/src/platform/platformDb.ts +0 -6
  182. package/src/platform/tenants.ts +0 -101
  183. package/src/platform/tests/tenants.spec.ts +0 -26
  184. package/src/platform/users.ts +0 -129
  185. package/src/plugin/index.ts +0 -1
  186. package/src/plugin/tests/validation.spec.ts +0 -209
  187. package/src/plugin/utils.ts +0 -175
  188. package/src/queue/constants.ts +0 -8
  189. package/src/queue/inMemoryQueue.ts +0 -189
  190. package/src/queue/index.ts +0 -2
  191. package/src/queue/listeners.ts +0 -199
  192. package/src/queue/queue.ts +0 -84
  193. package/src/redis/index.ts +0 -6
  194. package/src/redis/init.ts +0 -118
  195. package/src/redis/redis.ts +0 -358
  196. package/src/redis/redlockImpl.ts +0 -155
  197. package/src/redis/tests/redis.spec.ts +0 -207
  198. package/src/redis/tests/redlockImpl.spec.ts +0 -105
  199. package/src/redis/utils.ts +0 -128
  200. package/src/security/auth.ts +0 -24
  201. package/src/security/encryption.ts +0 -185
  202. package/src/security/index.ts +0 -1
  203. package/src/security/permissions.ts +0 -166
  204. package/src/security/roles.ts +0 -655
  205. package/src/security/secrets.ts +0 -20
  206. package/src/security/sessions.ts +0 -123
  207. package/src/security/tests/auth.spec.ts +0 -45
  208. package/src/security/tests/encryption.spec.ts +0 -31
  209. package/src/security/tests/permissions.spec.ts +0 -146
  210. package/src/security/tests/secrets.spec.ts +0 -35
  211. package/src/security/tests/sessions.spec.ts +0 -12
  212. package/src/sql/designDoc.ts +0 -17
  213. package/src/sql/index.ts +0 -5
  214. package/src/sql/sql.ts +0 -1854
  215. package/src/sql/sqlTable.ts +0 -319
  216. package/src/sql/utils.ts +0 -193
  217. package/src/tenancy/db.ts +0 -6
  218. package/src/tenancy/index.ts +0 -2
  219. package/src/tenancy/tenancy.ts +0 -148
  220. package/src/tenancy/tests/tenancy.spec.ts +0 -184
  221. package/src/timers/index.ts +0 -1
  222. package/src/timers/timers.ts +0 -22
  223. package/src/users/db.ts +0 -582
  224. package/src/users/events.ts +0 -176
  225. package/src/users/index.ts +0 -4
  226. package/src/users/lookup.ts +0 -99
  227. package/src/users/test/db.spec.ts +0 -188
  228. package/src/users/test/utils.spec.ts +0 -67
  229. package/src/users/users.ts +0 -353
  230. package/src/users/utils.ts +0 -81
  231. package/src/utils/Duration.ts +0 -56
  232. package/src/utils/hashing.ts +0 -15
  233. package/src/utils/index.ts +0 -4
  234. package/src/utils/stringUtils.ts +0 -8
  235. package/src/utils/tests/Duration.spec.ts +0 -19
  236. package/src/utils/tests/utils.spec.ts +0 -204
  237. package/src/utils/utils.ts +0 -249
  238. package/tests/core/logging.ts +0 -34
  239. package/tests/core/users/users.spec.js +0 -53
  240. package/tests/core/utilities/index.ts +0 -7
  241. package/tests/core/utilities/jestUtils.ts +0 -33
  242. package/tests/core/utilities/mocks/alerts.ts +0 -4
  243. package/tests/core/utilities/mocks/date.ts +0 -3
  244. package/tests/core/utilities/mocks/events.ts +0 -132
  245. package/tests/core/utilities/mocks/index.ts +0 -9
  246. package/tests/core/utilities/mocks/licenses.ts +0 -119
  247. package/tests/core/utilities/queue.ts +0 -9
  248. package/tests/core/utilities/structures/Chance.ts +0 -20
  249. package/tests/core/utilities/structures/accounts.ts +0 -80
  250. package/tests/core/utilities/structures/apps.ts +0 -21
  251. package/tests/core/utilities/structures/common.ts +0 -7
  252. package/tests/core/utilities/structures/db.ts +0 -12
  253. package/tests/core/utilities/structures/documents/index.ts +0 -1
  254. package/tests/core/utilities/structures/documents/platform/index.ts +0 -1
  255. package/tests/core/utilities/structures/documents/platform/installation.ts +0 -12
  256. package/tests/core/utilities/structures/generator.ts +0 -3
  257. package/tests/core/utilities/structures/index.ts +0 -15
  258. package/tests/core/utilities/structures/koa.ts +0 -16
  259. package/tests/core/utilities/structures/licenses.ts +0 -190
  260. package/tests/core/utilities/structures/plugins.ts +0 -19
  261. package/tests/core/utilities/structures/quotas.ts +0 -72
  262. package/tests/core/utilities/structures/scim.ts +0 -80
  263. package/tests/core/utilities/structures/sso.ts +0 -118
  264. package/tests/core/utilities/structures/tenants.ts +0 -5
  265. package/tests/core/utilities/structures/userGroups.ts +0 -10
  266. package/tests/core/utilities/structures/users.ts +0 -89
  267. package/tests/core/utilities/testContainerUtils.ts +0 -165
  268. package/tests/core/utilities/utils/index.ts +0 -2
  269. package/tests/core/utilities/utils/queue.ts +0 -27
  270. package/tests/core/utilities/utils/time.ts +0 -3
  271. package/tests/extra/DBTestConfiguration.ts +0 -36
  272. package/tests/extra/index.ts +0 -2
  273. package/tests/extra/testEnv.ts +0 -95
  274. package/tests/index.ts +0 -2
  275. package/tests/jestEnv.ts +0 -10
  276. package/tests/jestSetup.ts +0 -36
@@ -1,655 +0,0 @@
1
- import semver from "semver"
2
- import {
3
- prefixRoleID,
4
- getRoleParams,
5
- DocumentType,
6
- SEPARATOR,
7
- doWithDB,
8
- } from "../db"
9
- import { getAppDB } from "../context"
10
- import {
11
- Screen,
12
- Role as RoleDoc,
13
- RoleUIMetadata,
14
- Database,
15
- App,
16
- BuiltinPermissionID,
17
- PermissionLevel,
18
- } from "@budibase/types"
19
- import cloneDeep from "lodash/fp/cloneDeep"
20
- import { RoleColor, helpers } from "@budibase/shared-core"
21
- import { uniqBy } from "lodash"
22
- import { default as env } from "../environment"
23
-
24
- export const BUILTIN_ROLE_IDS = {
25
- ADMIN: "ADMIN",
26
- POWER: "POWER",
27
- BASIC: "BASIC",
28
- PUBLIC: "PUBLIC",
29
- }
30
-
31
- const BUILTIN_IDS = {
32
- ...BUILTIN_ROLE_IDS,
33
- BUILDER: "BUILDER",
34
- }
35
-
36
- export const RoleIDVersion = {
37
- // original version, with a UUID based ID
38
- UUID: undefined,
39
- // new version - with name based ID
40
- NAME: "name",
41
- }
42
-
43
- function rolesInList(roleIds: string[], ids: string | string[]) {
44
- if (Array.isArray(ids)) {
45
- return ids.filter(id => roleIds.includes(id)).length === ids.length
46
- } else {
47
- return roleIds.includes(ids)
48
- }
49
- }
50
-
51
- export class Role implements RoleDoc {
52
- _id: string
53
- _rev?: string
54
- name: string
55
- permissionId: BuiltinPermissionID
56
- inherits?: string | string[]
57
- version?: string
58
- permissions: Record<string, PermissionLevel[]> = {}
59
- uiMetadata?: RoleUIMetadata
60
-
61
- constructor(
62
- id: string,
63
- name: string,
64
- permissionId: BuiltinPermissionID,
65
- uiMetadata?: RoleUIMetadata
66
- ) {
67
- this._id = id
68
- this.name = name
69
- this.uiMetadata = uiMetadata
70
- this.permissionId = permissionId
71
- // version for managing the ID - removing the role_ when responding
72
- this.version = RoleIDVersion.NAME
73
- }
74
-
75
- addInheritance(inherits?: string | string[]) {
76
- // make sure IDs are correct format
77
- if (inherits && typeof inherits === "string") {
78
- inherits = prefixRoleIDNoBuiltin(inherits)
79
- } else if (inherits && Array.isArray(inherits)) {
80
- inherits = inherits.map(prefixRoleIDNoBuiltin)
81
- }
82
- this.inherits = inherits
83
- return this
84
- }
85
- }
86
-
87
- export class RoleHierarchyTraversal {
88
- allRoles: RoleDoc[]
89
- opts?: { defaultPublic?: boolean }
90
-
91
- constructor(allRoles: RoleDoc[], opts?: { defaultPublic?: boolean }) {
92
- this.allRoles = allRoles
93
- this.opts = opts
94
- }
95
-
96
- walk(role: RoleDoc): RoleDoc[] {
97
- const opts = this.opts,
98
- allRoles = this.allRoles
99
- // this will be a full walked list of roles - which may contain duplicates
100
- let roleList: RoleDoc[] = []
101
- if (!role || !role._id) {
102
- return roleList
103
- }
104
- roleList.push(role)
105
- if (Array.isArray(role.inherits)) {
106
- for (let roleId of role.inherits) {
107
- const foundRole = findRole(roleId, allRoles, opts)
108
- if (foundRole) {
109
- roleList = roleList.concat(this.walk(foundRole))
110
- }
111
- }
112
- } else {
113
- const foundRoleIds: string[] = []
114
- let currentRole: RoleDoc | undefined = role
115
- while (
116
- currentRole &&
117
- currentRole.inherits &&
118
- !rolesInList(foundRoleIds, currentRole.inherits)
119
- ) {
120
- if (Array.isArray(currentRole.inherits)) {
121
- return roleList.concat(this.walk(currentRole))
122
- } else {
123
- foundRoleIds.push(currentRole.inherits)
124
- currentRole = findRole(currentRole.inherits, allRoles, opts)
125
- if (currentRole) {
126
- roleList.push(currentRole)
127
- }
128
- }
129
- // loop now found - stop iterating
130
- if (helpers.roles.checkForRoleInheritanceLoops(roleList)) {
131
- break
132
- }
133
- }
134
- }
135
- return uniqBy(roleList, role => role._id)
136
- }
137
- }
138
-
139
- const BUILTIN_ROLES = {
140
- ADMIN: new Role(
141
- BUILTIN_IDS.ADMIN,
142
- BUILTIN_IDS.ADMIN,
143
- BuiltinPermissionID.ADMIN,
144
- {
145
- displayName: "App admin",
146
- description: "Can do everything",
147
- color: RoleColor.ADMIN,
148
- }
149
- ).addInheritance(BUILTIN_IDS.POWER),
150
- POWER: new Role(
151
- BUILTIN_IDS.POWER,
152
- BUILTIN_IDS.POWER,
153
- BuiltinPermissionID.POWER,
154
- {
155
- displayName: "App power user",
156
- description: "An app user with more access",
157
- color: RoleColor.POWER,
158
- }
159
- ).addInheritance(BUILTIN_IDS.BASIC),
160
- BASIC: new Role(
161
- BUILTIN_IDS.BASIC,
162
- BUILTIN_IDS.BASIC,
163
- BuiltinPermissionID.WRITE,
164
- {
165
- displayName: "App user",
166
- description: "Any logged in user",
167
- color: RoleColor.BASIC,
168
- }
169
- ).addInheritance(BUILTIN_IDS.PUBLIC),
170
- PUBLIC: new Role(
171
- BUILTIN_IDS.PUBLIC,
172
- BUILTIN_IDS.PUBLIC,
173
- BuiltinPermissionID.PUBLIC,
174
- {
175
- displayName: "Public user",
176
- description: "Accessible to anyone",
177
- color: RoleColor.PUBLIC,
178
- }
179
- ),
180
- BUILDER: new Role(
181
- BUILTIN_IDS.BUILDER,
182
- BUILTIN_IDS.BUILDER,
183
- BuiltinPermissionID.ADMIN,
184
- {
185
- displayName: "Builder user",
186
- description: "Users that can edit this app",
187
- color: RoleColor.BUILDER,
188
- }
189
- ),
190
- }
191
-
192
- export function getBuiltinRoles(): { [key: string]: RoleDoc } {
193
- return cloneDeep(BUILTIN_ROLES)
194
- }
195
-
196
- export function isBuiltin(role: string) {
197
- return Object.values(BUILTIN_ROLE_IDS).includes(role)
198
- }
199
-
200
- export function prefixRoleIDNoBuiltin(roleId: string) {
201
- if (isBuiltin(roleId)) {
202
- return roleId
203
- } else {
204
- return prefixRoleID(roleId)
205
- }
206
- }
207
-
208
- export function getBuiltinRole(roleId: string): Role | undefined {
209
- const role = Object.values(BUILTIN_ROLES).find(role =>
210
- roleId.includes(role._id)
211
- )
212
- if (!role) {
213
- return undefined
214
- }
215
- return cloneDeep(role)
216
- }
217
-
218
- export function validInherits(
219
- allRoles: RoleDoc[],
220
- inherits?: string | string[]
221
- ): boolean {
222
- if (!inherits) {
223
- return false
224
- }
225
- const find = (id: string) => allRoles.find(r => roleIDsAreEqual(r._id!, id))
226
- if (Array.isArray(inherits)) {
227
- const filtered = inherits.filter(roleId => find(roleId))
228
- return inherits.length !== 0 && filtered.length === inherits.length
229
- } else {
230
- return !!find(inherits)
231
- }
232
- }
233
-
234
- /**
235
- * Works through the inheritance ranks to see how far up the builtin stack this ID is.
236
- */
237
- export function builtinRoleToNumber(id: string) {
238
- const builtins = getBuiltinRoles()
239
- const MAX = Object.values(builtins).length + 1
240
- if (
241
- roleIDsAreEqual(id, BUILTIN_IDS.ADMIN) ||
242
- roleIDsAreEqual(id, BUILTIN_IDS.BUILDER)
243
- ) {
244
- return MAX
245
- }
246
- let role = builtins[id],
247
- count = 0
248
- do {
249
- if (!role) {
250
- break
251
- }
252
- if (Array.isArray(role.inherits)) {
253
- throw new Error("Built-in roles don't support multi-inheritance")
254
- } else {
255
- role = builtins[role.inherits!]
256
- }
257
- count++
258
- } while (role !== null)
259
- return count
260
- }
261
-
262
- /**
263
- * Converts any role to a number, but has to be async to get the roles from db.
264
- */
265
- export async function roleToNumber(id: string) {
266
- if (isBuiltin(id)) {
267
- return builtinRoleToNumber(id)
268
- }
269
- const hierarchy = (await getUserRoleHierarchy(id, {
270
- defaultPublic: true,
271
- })) as RoleDoc[]
272
- const findNumber = (role: RoleDoc): number => {
273
- if (!role.inherits) {
274
- return 0
275
- }
276
- if (Array.isArray(role.inherits)) {
277
- // find the built-in roles, get their number, sort it, then get the last one
278
- const highestBuiltin: number | undefined = role.inherits
279
- .map(roleId => {
280
- const foundRole = hierarchy.find(role =>
281
- roleIDsAreEqual(role._id!, roleId)
282
- )
283
- if (foundRole) {
284
- return findNumber(foundRole) + 1
285
- }
286
- })
287
- .filter(number => number)
288
- .sort()
289
- .pop()
290
- if (highestBuiltin != undefined) {
291
- return highestBuiltin
292
- }
293
- } else if (isBuiltin(role.inherits)) {
294
- return builtinRoleToNumber(role.inherits) + 1
295
- }
296
- return 0
297
- }
298
- return Math.max(...hierarchy.map(findNumber))
299
- }
300
-
301
- /**
302
- * Returns whichever builtin roleID is lower.
303
- */
304
- export function lowerBuiltinRoleID(roleId1?: string, roleId2?: string): string {
305
- if (!roleId1) {
306
- return roleId2 as string
307
- }
308
- if (!roleId2) {
309
- return roleId1 as string
310
- }
311
- return builtinRoleToNumber(roleId1) > builtinRoleToNumber(roleId2)
312
- ? roleId2
313
- : roleId1
314
- }
315
-
316
- export function roleIDsAreEqual(roleId1: string, roleId2: string) {
317
- // make sure both role IDs are prefixed correctly
318
- return prefixRoleID(roleId1) === prefixRoleID(roleId2)
319
- }
320
-
321
- export function externalRole(role: RoleDoc): RoleDoc {
322
- let _id: string | undefined
323
- if (role._id) {
324
- _id = getExternalRoleID(role._id)
325
- }
326
- return {
327
- ...role,
328
- _id,
329
- inherits: getExternalRoleIDs(role.inherits, role.version),
330
- }
331
- }
332
-
333
- /**
334
- * Given a list of roles, this will pick the role out, accounting for built ins.
335
- */
336
- export function findRole(
337
- roleId: string,
338
- roles: RoleDoc[],
339
- opts?: { defaultPublic?: boolean }
340
- ): RoleDoc | undefined {
341
- // built in roles mostly come from the in-code implementation,
342
- // but can be extended by a doc stored about them (e.g. permissions)
343
- let role: RoleDoc | undefined = getBuiltinRole(roleId)
344
- if (!role) {
345
- // make sure has the prefix (if it has it then it won't be added)
346
- roleId = prefixRoleID(roleId)
347
- }
348
- const dbRole = roles.find(
349
- role => role._id && roleIDsAreEqual(role._id, roleId)
350
- )
351
- if (!dbRole && !isBuiltin(roleId) && opts?.defaultPublic) {
352
- return cloneDeep(BUILTIN_ROLES.PUBLIC)
353
- }
354
- // combine the roles
355
- role = Object.assign(role || {}, dbRole)
356
- // finalise the ID
357
- if (role?._id) {
358
- role._id = getExternalRoleID(role._id, role.version)
359
- }
360
- return Object.keys(role).length === 0 ? undefined : role
361
- }
362
-
363
- /**
364
- * Gets the role object, this is mainly useful for two purposes, to check if the level exists and
365
- * to check if the role inherits any others.
366
- * @param roleId The level ID to lookup.
367
- * @param opts options for the function, like whether to halt errors, instead return public.
368
- * @returns The role object, which may contain an "inherits" property.
369
- */
370
- export async function getRole(
371
- roleId: string,
372
- opts?: { defaultPublic?: boolean }
373
- ): Promise<RoleDoc | undefined> {
374
- const db = getAppDB()
375
- const roleList = []
376
- if (!isBuiltin(roleId)) {
377
- const role = await db.tryGet<RoleDoc>(getDBRoleID(roleId))
378
- if (role) {
379
- roleList.push(role)
380
- }
381
- }
382
- return findRole(roleId, roleList, opts)
383
- }
384
-
385
- export async function saveRoles(roles: RoleDoc[]) {
386
- const db = getAppDB()
387
- await db.bulkDocs(
388
- roles
389
- .filter(role => role._id)
390
- .map(role => ({
391
- ...role,
392
- _id: prefixRoleID(role._id!),
393
- }))
394
- )
395
- }
396
-
397
- /**
398
- * Simple function to get all the roles based on the top level user role ID.
399
- */
400
- async function getAllUserRoles(
401
- userRoleId: string,
402
- opts?: { defaultPublic?: boolean }
403
- ): Promise<RoleDoc[]> {
404
- const allRoles = await getAllRoles()
405
- // admins have access to all roles
406
- if (roleIDsAreEqual(userRoleId, BUILTIN_IDS.ADMIN)) {
407
- return allRoles
408
- }
409
-
410
- // get all the inherited roles
411
- const foundRole = findRole(userRoleId, allRoles, opts)
412
- let roles: RoleDoc[] = []
413
- if (foundRole) {
414
- const traversal = new RoleHierarchyTraversal(allRoles, opts)
415
- roles = traversal.walk(foundRole)
416
- }
417
- return roles
418
- }
419
-
420
- export async function getUserRoleIdHierarchy(
421
- userRoleId: string
422
- ): Promise<string[]> {
423
- const roles = await getUserRoleHierarchy(userRoleId)
424
- return roles.map(role => role._id!)
425
- }
426
-
427
- /**
428
- * Returns an ordered array of the user's inherited role IDs, this can be used
429
- * to determine if a user can access something that requires a specific role.
430
- * @param userRoleId The user's role ID, this can be found in their access token.
431
- * @param opts optional - if want to default to public use this.
432
- * @returns returns an ordered array of the roles, with the first being their
433
- * highest level of access and the last being the lowest level.
434
- */
435
- export async function getUserRoleHierarchy(
436
- userRoleId: string,
437
- opts?: { defaultPublic?: boolean }
438
- ) {
439
- // special case, if they don't have a role then they are a public user
440
- return getAllUserRoles(userRoleId, opts)
441
- }
442
-
443
- // this function checks that the provided permissions are in an array format
444
- // some templates/older apps will use a simple string instead of array for roles
445
- // convert the string to an array using the theory that write is higher than read
446
- export function checkForRoleResourceArray(
447
- rolePerms: Record<string, PermissionLevel[]>,
448
- resourceId: string
449
- ): Record<string, PermissionLevel[]> {
450
- if (rolePerms && !Array.isArray(rolePerms[resourceId])) {
451
- const permLevel = rolePerms[resourceId] as any
452
- rolePerms[resourceId] = [permLevel]
453
- if (permLevel === PermissionLevel.WRITE) {
454
- rolePerms[resourceId].push(PermissionLevel.READ)
455
- }
456
- }
457
- return rolePerms
458
- }
459
-
460
- export async function getAllRoleIds(appId: string): Promise<string[]> {
461
- const roles = await getAllRoles(appId)
462
- return roles.map(role => role._id!)
463
- }
464
-
465
- /**
466
- * Given an app ID this will retrieve all of the roles that are currently within that app.
467
- * @return An array of the role objects that were found.
468
- */
469
- export async function getAllRoles(appId?: string): Promise<RoleDoc[]> {
470
- if (appId) {
471
- return doWithDB(appId, internal)
472
- } else {
473
- let appDB
474
- try {
475
- appDB = getAppDB()
476
- } catch (error) {
477
- // We don't have any apps, so we'll just use the built-in roles
478
- }
479
- return internal(appDB)
480
- }
481
- async function internal(db: Database | undefined) {
482
- let roles: RoleDoc[] = []
483
- if (db) {
484
- const body = await db.allDocs(
485
- getRoleParams(null, {
486
- include_docs: true,
487
- })
488
- )
489
- roles = body.rows.map((row: any) => row.doc)
490
- roles.forEach(
491
- role => (role._id = getExternalRoleID(role._id!, role.version))
492
- )
493
- }
494
- const builtinRoles = getBuiltinRoles()
495
-
496
- // exclude internal roles like builder
497
- let externalBuiltinRoles = []
498
-
499
- if (!db || (await shouldIncludePowerRole(db))) {
500
- externalBuiltinRoles = [
501
- BUILTIN_IDS.ADMIN,
502
- BUILTIN_IDS.POWER,
503
- BUILTIN_IDS.BASIC,
504
- BUILTIN_IDS.PUBLIC,
505
- ]
506
- } else {
507
- externalBuiltinRoles = [
508
- BUILTIN_IDS.ADMIN,
509
- BUILTIN_IDS.BASIC,
510
- BUILTIN_IDS.PUBLIC,
511
- ]
512
- }
513
-
514
- // need to combine builtin with any DB record of them (for sake of permissions)
515
- for (let builtinRoleId of externalBuiltinRoles) {
516
- const builtinRole = builtinRoles[builtinRoleId]
517
- const dbBuiltin = roles.filter(dbRole =>
518
- roleIDsAreEqual(dbRole._id!, builtinRoleId)
519
- )[0]
520
- if (dbBuiltin == null) {
521
- roles.push(builtinRole || builtinRoles.BASIC)
522
- } else {
523
- // remove role and all back after combining with the builtin
524
- roles = roles.filter(role => role._id !== dbBuiltin._id)
525
- dbBuiltin._id = getExternalRoleID(builtinRole._id!, dbBuiltin.version)
526
- roles.push({
527
- ...builtinRole,
528
- ...dbBuiltin,
529
- name: builtinRole.name,
530
- _id: getExternalRoleID(builtinRole._id!, builtinRole.version),
531
- })
532
- }
533
- }
534
- // check permissions
535
- for (let role of roles) {
536
- if (!role.permissions) {
537
- continue
538
- }
539
- for (let resourceId of Object.keys(role.permissions)) {
540
- role.permissions = checkForRoleResourceArray(
541
- role.permissions,
542
- resourceId
543
- )
544
- }
545
- }
546
- return roles
547
- }
548
- }
549
-
550
- async function shouldIncludePowerRole(db: Database) {
551
- const app = await db.tryGet<App>(DocumentType.APP_METADATA)
552
- const creationVersion = app?.creationVersion
553
- if (!creationVersion || !semver.valid(creationVersion)) {
554
- // Old apps don't have creationVersion, so we should include it for backward compatibility
555
- return true
556
- }
557
-
558
- const isGreaterThan3x = semver.gte(
559
- creationVersion,
560
- env.MIN_VERSION_WITHOUT_POWER_ROLE
561
- )
562
- return !isGreaterThan3x
563
- }
564
-
565
- export class AccessController {
566
- userHierarchies: { [key: string]: string[] }
567
- constructor() {
568
- this.userHierarchies = {}
569
- }
570
-
571
- async hasAccess(tryingRoleId?: string, userRoleId?: string) {
572
- // special cases, the screen has no role, the roles are the same or the user
573
- // is currently in the builder
574
- if (
575
- tryingRoleId == null ||
576
- tryingRoleId === "" ||
577
- roleIDsAreEqual(tryingRoleId, BUILTIN_IDS.BUILDER) ||
578
- roleIDsAreEqual(userRoleId!, tryingRoleId) ||
579
- roleIDsAreEqual(userRoleId!, BUILTIN_IDS.BUILDER)
580
- ) {
581
- return true
582
- }
583
- let roleIds = userRoleId ? this.userHierarchies[userRoleId] : null
584
- if (!roleIds && userRoleId) {
585
- roleIds = await getUserRoleIdHierarchy(userRoleId)
586
- this.userHierarchies[userRoleId] = roleIds
587
- }
588
-
589
- return (
590
- roleIds?.find(roleId => roleIDsAreEqual(roleId, tryingRoleId)) !==
591
- undefined
592
- )
593
- }
594
-
595
- async checkScreensAccess(screens: Screen[], userRoleId: string) {
596
- let accessibleScreens = []
597
- // don't want to handle this with Promise.all as this would mean all custom roles would be
598
- // retrieved at same time, it is likely a custom role will be re-used and therefore want
599
- // to work in sync for performance save
600
- for (let screen of screens) {
601
- const accessible = await this.checkScreenAccess(screen, userRoleId)
602
- if (accessible) {
603
- accessibleScreens.push(accessible)
604
- }
605
- }
606
- return accessibleScreens
607
- }
608
-
609
- async checkScreenAccess(screen: Screen, userRoleId: string) {
610
- const roleId = screen && screen.routing ? screen.routing.roleId : undefined
611
- if (await this.hasAccess(roleId, userRoleId)) {
612
- return screen
613
- }
614
- return null
615
- }
616
- }
617
-
618
- /**
619
- * Adds the "role_" for builtin role IDs which are to be written to the DB (for permissions).
620
- */
621
- export function getDBRoleID(roleName: string) {
622
- if (roleName?.startsWith(DocumentType.ROLE)) {
623
- return roleName
624
- }
625
- return prefixRoleID(roleName)
626
- }
627
-
628
- /**
629
- * Remove the "role_" from builtin role IDs that have been written to the DB (for permissions).
630
- */
631
- export function getExternalRoleID(roleId: string, version?: string) {
632
- // for built-in roles we want to remove the DB role ID element (role_)
633
- if (
634
- roleId.startsWith(`${DocumentType.ROLE}${SEPARATOR}`) &&
635
- (isBuiltin(roleId) || version === RoleIDVersion.NAME)
636
- ) {
637
- const parts = roleId.split(SEPARATOR)
638
- parts.shift()
639
- return parts.join(SEPARATOR)
640
- }
641
- return roleId
642
- }
643
-
644
- export function getExternalRoleIDs(
645
- roleIds: string | string[] | undefined,
646
- version?: string
647
- ) {
648
- if (!roleIds) {
649
- return roleIds
650
- } else if (typeof roleIds === "string") {
651
- return getExternalRoleID(roleIds, version)
652
- } else {
653
- return roleIds.map(roleId => getExternalRoleID(roleId, version))
654
- }
655
- }
@@ -1,20 +0,0 @@
1
- import environment, { SECRETS } from "../environment"
2
-
3
- export function stringContainsSecret(str: string) {
4
- if (str.includes("-----BEGIN PRIVATE KEY-----")) {
5
- return true
6
- }
7
-
8
- for (const key of SECRETS) {
9
- const value = environment[key]
10
- if (typeof value !== "string" || value === "") {
11
- continue
12
- }
13
-
14
- if (str.includes(value)) {
15
- return true
16
- }
17
- }
18
-
19
- return false
20
- }