@budibase/backend-core 3.2.4 → 3.2.6

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 (272) hide show
  1. package/dist/index.js.map +1 -1
  2. package/dist/index.js.meta.json +1 -1
  3. package/dist/package.json +11 -4
  4. package/dist/plugins.js.meta.json +1 -1
  5. package/package.json +11 -4
  6. package/src/accounts/accounts.ts +0 -82
  7. package/src/accounts/api.ts +0 -59
  8. package/src/accounts/index.ts +0 -1
  9. package/src/auth/auth.ts +0 -210
  10. package/src/auth/index.ts +0 -1
  11. package/src/auth/tests/auth.spec.ts +0 -14
  12. package/src/blacklist/blacklist.ts +0 -54
  13. package/src/blacklist/index.ts +0 -1
  14. package/src/blacklist/tests/blacklist.spec.ts +0 -46
  15. package/src/cache/appMetadata.ts +0 -88
  16. package/src/cache/base/index.ts +0 -150
  17. package/src/cache/docWritethrough.ts +0 -105
  18. package/src/cache/generic.ts +0 -33
  19. package/src/cache/index.ts +0 -8
  20. package/src/cache/invite.ts +0 -86
  21. package/src/cache/passwordReset.ts +0 -49
  22. package/src/cache/tests/docWritethrough.spec.ts +0 -296
  23. package/src/cache/tests/user.spec.ts +0 -145
  24. package/src/cache/tests/writethrough.spec.ts +0 -139
  25. package/src/cache/user.ts +0 -154
  26. package/src/cache/writethrough.ts +0 -133
  27. package/src/configs/configs.ts +0 -263
  28. package/src/configs/index.ts +0 -1
  29. package/src/configs/tests/configs.spec.ts +0 -184
  30. package/src/constants/db.ts +0 -75
  31. package/src/constants/index.ts +0 -2
  32. package/src/constants/misc.ts +0 -36
  33. package/src/context/Context.ts +0 -14
  34. package/src/context/identity.ts +0 -58
  35. package/src/context/index.ts +0 -3
  36. package/src/context/mainContext.ts +0 -422
  37. package/src/context/tests/index.spec.ts +0 -255
  38. package/src/context/types.ts +0 -26
  39. package/src/db/Replication.ts +0 -94
  40. package/src/db/couch/DatabaseImpl.ts +0 -511
  41. package/src/db/couch/connections.ts +0 -89
  42. package/src/db/couch/index.ts +0 -4
  43. package/src/db/couch/pouchDB.ts +0 -97
  44. package/src/db/couch/pouchDump.ts +0 -0
  45. package/src/db/couch/tests/DatabaseImpl.spec.ts +0 -118
  46. package/src/db/couch/utils.ts +0 -55
  47. package/src/db/db.ts +0 -34
  48. package/src/db/errors.ts +0 -14
  49. package/src/db/index.ts +0 -12
  50. package/src/db/instrumentation.ts +0 -199
  51. package/src/db/lucene.ts +0 -721
  52. package/src/db/searchIndexes/index.ts +0 -1
  53. package/src/db/searchIndexes/searchIndexes.ts +0 -62
  54. package/src/db/tests/DatabaseImpl.spec.ts +0 -55
  55. package/src/db/tests/connections.spec.ts +0 -22
  56. package/src/db/tests/index.spec.ts +0 -32
  57. package/src/db/tests/lucene.spec.ts +0 -400
  58. package/src/db/tests/pouch.spec.js +0 -62
  59. package/src/db/tests/utils.spec.ts +0 -63
  60. package/src/db/utils.ts +0 -208
  61. package/src/db/views.ts +0 -245
  62. package/src/docIds/conversions.ts +0 -60
  63. package/src/docIds/ids.ts +0 -126
  64. package/src/docIds/index.ts +0 -2
  65. package/src/docIds/newid.ts +0 -5
  66. package/src/docIds/params.ts +0 -189
  67. package/src/docUpdates/index.ts +0 -24
  68. package/src/environment.ts +0 -293
  69. package/src/errors/errors.ts +0 -119
  70. package/src/errors/index.ts +0 -1
  71. package/src/events/analytics.ts +0 -6
  72. package/src/events/asyncEvents/index.ts +0 -2
  73. package/src/events/asyncEvents/publisher.ts +0 -12
  74. package/src/events/asyncEvents/queue.ts +0 -22
  75. package/src/events/backfill.ts +0 -183
  76. package/src/events/documentId.ts +0 -56
  77. package/src/events/events.ts +0 -47
  78. package/src/events/identification.ts +0 -311
  79. package/src/events/index.ts +0 -15
  80. package/src/events/processors/AnalyticsProcessor.ts +0 -64
  81. package/src/events/processors/AuditLogsProcessor.ts +0 -92
  82. package/src/events/processors/LoggingProcessor.ts +0 -36
  83. package/src/events/processors/Processors.ts +0 -52
  84. package/src/events/processors/async/DocumentUpdateProcessor.ts +0 -38
  85. package/src/events/processors/index.ts +0 -19
  86. package/src/events/processors/posthog/PosthogProcessor.ts +0 -118
  87. package/src/events/processors/posthog/index.ts +0 -3
  88. package/src/events/processors/posthog/rateLimiting.ts +0 -106
  89. package/src/events/processors/posthog/tests/PosthogProcessor.spec.ts +0 -164
  90. package/src/events/processors/types.ts +0 -1
  91. package/src/events/publishers/account.ts +0 -41
  92. package/src/events/publishers/ai.ts +0 -21
  93. package/src/events/publishers/app.ts +0 -168
  94. package/src/events/publishers/auditLog.ts +0 -26
  95. package/src/events/publishers/auth.ts +0 -73
  96. package/src/events/publishers/automation.ts +0 -110
  97. package/src/events/publishers/backfill.ts +0 -74
  98. package/src/events/publishers/backup.ts +0 -42
  99. package/src/events/publishers/datasource.ts +0 -48
  100. package/src/events/publishers/email.ts +0 -17
  101. package/src/events/publishers/environmentVariable.ts +0 -38
  102. package/src/events/publishers/group.ts +0 -99
  103. package/src/events/publishers/index.ts +0 -25
  104. package/src/events/publishers/installation.ts +0 -38
  105. package/src/events/publishers/layout.ts +0 -26
  106. package/src/events/publishers/license.ts +0 -84
  107. package/src/events/publishers/org.ts +0 -37
  108. package/src/events/publishers/plugin.ts +0 -47
  109. package/src/events/publishers/query.ts +0 -89
  110. package/src/events/publishers/role.ts +0 -62
  111. package/src/events/publishers/rows.ts +0 -29
  112. package/src/events/publishers/screen.ts +0 -36
  113. package/src/events/publishers/serve.ts +0 -43
  114. package/src/events/publishers/table.ts +0 -70
  115. package/src/events/publishers/user.ts +0 -202
  116. package/src/events/publishers/view.ts +0 -107
  117. package/src/features/features.ts +0 -277
  118. package/src/features/index.ts +0 -2
  119. package/src/features/tests/features.spec.ts +0 -267
  120. package/src/features/tests/utils.ts +0 -64
  121. package/src/helpers.ts +0 -9
  122. package/src/index.ts +0 -59
  123. package/src/installation.ts +0 -115
  124. package/src/logging/alerts.ts +0 -26
  125. package/src/logging/correlation/correlation.ts +0 -15
  126. package/src/logging/correlation/index.ts +0 -1
  127. package/src/logging/correlation/middleware.ts +0 -18
  128. package/src/logging/index.ts +0 -4
  129. package/src/logging/pino/logger.ts +0 -239
  130. package/src/logging/pino/middleware.ts +0 -48
  131. package/src/logging/system.ts +0 -81
  132. package/src/logging/tests/system.spec.ts +0 -61
  133. package/src/middleware/adminOnly.ts +0 -9
  134. package/src/middleware/auditLog.ts +0 -6
  135. package/src/middleware/authenticated.ts +0 -247
  136. package/src/middleware/builderOnly.ts +0 -21
  137. package/src/middleware/builderOrAdmin.ts +0 -21
  138. package/src/middleware/contentSecurityPolicy.ts +0 -113
  139. package/src/middleware/csrf.ts +0 -81
  140. package/src/middleware/errorHandling.ts +0 -43
  141. package/src/middleware/index.ts +0 -24
  142. package/src/middleware/internalApi.ts +0 -23
  143. package/src/middleware/ip.ts +0 -12
  144. package/src/middleware/joi-validator.ts +0 -58
  145. package/src/middleware/matchers.ts +0 -39
  146. package/src/middleware/passport/datasource/google.ts +0 -102
  147. package/src/middleware/passport/local.ts +0 -54
  148. package/src/middleware/passport/sso/google.ts +0 -77
  149. package/src/middleware/passport/sso/oidc.ts +0 -152
  150. package/src/middleware/passport/sso/sso.ts +0 -138
  151. package/src/middleware/passport/sso/tests/google.spec.ts +0 -68
  152. package/src/middleware/passport/sso/tests/oidc.spec.ts +0 -144
  153. package/src/middleware/passport/sso/tests/sso.spec.ts +0 -197
  154. package/src/middleware/passport/utils.ts +0 -38
  155. package/src/middleware/querystringToBody.ts +0 -28
  156. package/src/middleware/tenancy.ts +0 -36
  157. package/src/middleware/tests/builder.spec.ts +0 -181
  158. package/src/middleware/tests/contentSecurityPolicy.spec.ts +0 -75
  159. package/src/middleware/tests/matchers.spec.ts +0 -100
  160. package/src/migrations/definitions.ts +0 -40
  161. package/src/migrations/index.ts +0 -2
  162. package/src/migrations/migrations.ts +0 -186
  163. package/src/migrations/tests/__snapshots__/migrations.spec.ts.snap +0 -11
  164. package/src/migrations/tests/migrations.spec.ts +0 -64
  165. package/src/objectStore/buckets/app.ts +0 -53
  166. package/src/objectStore/buckets/global.ts +0 -29
  167. package/src/objectStore/buckets/index.ts +0 -3
  168. package/src/objectStore/buckets/plugins.ts +0 -71
  169. package/src/objectStore/buckets/tests/app.spec.ts +0 -161
  170. package/src/objectStore/buckets/tests/global.spec.ts +0 -74
  171. package/src/objectStore/buckets/tests/plugins.spec.ts +0 -111
  172. package/src/objectStore/cloudfront.ts +0 -41
  173. package/src/objectStore/index.ts +0 -3
  174. package/src/objectStore/objectStore.ts +0 -585
  175. package/src/objectStore/utils.ts +0 -113
  176. package/src/platform/index.ts +0 -3
  177. package/src/platform/platformDb.ts +0 -6
  178. package/src/platform/tenants.ts +0 -101
  179. package/src/platform/tests/tenants.spec.ts +0 -26
  180. package/src/platform/users.ts +0 -129
  181. package/src/plugin/index.ts +0 -1
  182. package/src/plugin/tests/validation.spec.ts +0 -209
  183. package/src/plugin/utils.ts +0 -175
  184. package/src/queue/constants.ts +0 -8
  185. package/src/queue/inMemoryQueue.ts +0 -189
  186. package/src/queue/index.ts +0 -2
  187. package/src/queue/listeners.ts +0 -199
  188. package/src/queue/queue.ts +0 -84
  189. package/src/redis/index.ts +0 -6
  190. package/src/redis/init.ts +0 -118
  191. package/src/redis/redis.ts +0 -358
  192. package/src/redis/redlockImpl.ts +0 -155
  193. package/src/redis/tests/redis.spec.ts +0 -207
  194. package/src/redis/tests/redlockImpl.spec.ts +0 -105
  195. package/src/redis/utils.ts +0 -128
  196. package/src/security/auth.ts +0 -24
  197. package/src/security/encryption.ts +0 -185
  198. package/src/security/index.ts +0 -1
  199. package/src/security/permissions.ts +0 -166
  200. package/src/security/roles.ts +0 -655
  201. package/src/security/secrets.ts +0 -20
  202. package/src/security/sessions.ts +0 -123
  203. package/src/security/tests/auth.spec.ts +0 -45
  204. package/src/security/tests/encryption.spec.ts +0 -31
  205. package/src/security/tests/permissions.spec.ts +0 -146
  206. package/src/security/tests/secrets.spec.ts +0 -35
  207. package/src/security/tests/sessions.spec.ts +0 -12
  208. package/src/sql/designDoc.ts +0 -17
  209. package/src/sql/index.ts +0 -5
  210. package/src/sql/sql.ts +0 -1854
  211. package/src/sql/sqlTable.ts +0 -319
  212. package/src/sql/utils.ts +0 -193
  213. package/src/tenancy/db.ts +0 -6
  214. package/src/tenancy/index.ts +0 -2
  215. package/src/tenancy/tenancy.ts +0 -148
  216. package/src/tenancy/tests/tenancy.spec.ts +0 -184
  217. package/src/timers/index.ts +0 -1
  218. package/src/timers/timers.ts +0 -22
  219. package/src/users/db.ts +0 -582
  220. package/src/users/events.ts +0 -176
  221. package/src/users/index.ts +0 -4
  222. package/src/users/lookup.ts +0 -99
  223. package/src/users/test/db.spec.ts +0 -188
  224. package/src/users/test/utils.spec.ts +0 -67
  225. package/src/users/users.ts +0 -353
  226. package/src/users/utils.ts +0 -81
  227. package/src/utils/Duration.ts +0 -56
  228. package/src/utils/hashing.ts +0 -15
  229. package/src/utils/index.ts +0 -4
  230. package/src/utils/stringUtils.ts +0 -8
  231. package/src/utils/tests/Duration.spec.ts +0 -19
  232. package/src/utils/tests/utils.spec.ts +0 -204
  233. package/src/utils/utils.ts +0 -249
  234. package/tests/core/logging.ts +0 -34
  235. package/tests/core/users/users.spec.js +0 -53
  236. package/tests/core/utilities/index.ts +0 -7
  237. package/tests/core/utilities/jestUtils.ts +0 -33
  238. package/tests/core/utilities/mocks/alerts.ts +0 -4
  239. package/tests/core/utilities/mocks/date.ts +0 -3
  240. package/tests/core/utilities/mocks/events.ts +0 -132
  241. package/tests/core/utilities/mocks/index.ts +0 -9
  242. package/tests/core/utilities/mocks/licenses.ts +0 -119
  243. package/tests/core/utilities/queue.ts +0 -9
  244. package/tests/core/utilities/structures/Chance.ts +0 -20
  245. package/tests/core/utilities/structures/accounts.ts +0 -80
  246. package/tests/core/utilities/structures/apps.ts +0 -21
  247. package/tests/core/utilities/structures/common.ts +0 -7
  248. package/tests/core/utilities/structures/db.ts +0 -12
  249. package/tests/core/utilities/structures/documents/index.ts +0 -1
  250. package/tests/core/utilities/structures/documents/platform/index.ts +0 -1
  251. package/tests/core/utilities/structures/documents/platform/installation.ts +0 -12
  252. package/tests/core/utilities/structures/generator.ts +0 -3
  253. package/tests/core/utilities/structures/index.ts +0 -15
  254. package/tests/core/utilities/structures/koa.ts +0 -16
  255. package/tests/core/utilities/structures/licenses.ts +0 -190
  256. package/tests/core/utilities/structures/plugins.ts +0 -19
  257. package/tests/core/utilities/structures/quotas.ts +0 -72
  258. package/tests/core/utilities/structures/scim.ts +0 -80
  259. package/tests/core/utilities/structures/sso.ts +0 -118
  260. package/tests/core/utilities/structures/tenants.ts +0 -5
  261. package/tests/core/utilities/structures/userGroups.ts +0 -10
  262. package/tests/core/utilities/structures/users.ts +0 -89
  263. package/tests/core/utilities/testContainerUtils.ts +0 -165
  264. package/tests/core/utilities/utils/index.ts +0 -2
  265. package/tests/core/utilities/utils/queue.ts +0 -27
  266. package/tests/core/utilities/utils/time.ts +0 -3
  267. package/tests/extra/DBTestConfiguration.ts +0 -36
  268. package/tests/extra/index.ts +0 -2
  269. package/tests/extra/testEnv.ts +0 -95
  270. package/tests/index.ts +0 -2
  271. package/tests/jestEnv.ts +0 -10
  272. 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
- }