@budibase/backend-core 2.9.19-alpha.0 → 2.9.20
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 +324 -266
- package/dist/index.js.map +4 -4
- package/dist/index.js.meta.json +1 -1
- package/dist/package.json +19 -4
- package/dist/plugins.js +1 -1
- package/dist/plugins.js.map +1 -1
- package/dist/plugins.js.meta.json +1 -1
- package/dist/src/security/permissions.d.ts +1 -1
- package/dist/tests.js +260 -222
- package/dist/tests.js.map +4 -4
- package/dist/tests.js.meta.json +1 -1
- package/package.json +19 -4
- package/__mocks__/aws-sdk.ts +0 -18
- package/dist/tsconfig.build.tsbuildinfo +0 -1
- package/jest-testcontainers-config.js +0 -8
- package/jest.config.ts +0 -35
- package/scripts/build.js +0 -6
- package/scripts/test.sh +0 -13
- package/src/accounts/accounts.ts +0 -82
- package/src/accounts/api.ts +0 -59
- package/src/accounts/index.ts +0 -1
- package/src/auth/auth.ts +0 -208
- package/src/auth/index.ts +0 -1
- package/src/auth/tests/auth.spec.ts +0 -14
- package/src/blacklist/blacklist.ts +0 -54
- package/src/blacklist/index.ts +0 -1
- package/src/blacklist/tests/blacklist.spec.ts +0 -46
- package/src/cache/appMetadata.ts +0 -88
- package/src/cache/base/index.ts +0 -92
- package/src/cache/generic.ts +0 -30
- package/src/cache/index.ts +0 -5
- package/src/cache/tests/writethrough.spec.ts +0 -138
- package/src/cache/user.ts +0 -69
- package/src/cache/writethrough.ts +0 -133
- package/src/configs/configs.ts +0 -257
- package/src/configs/index.ts +0 -1
- package/src/configs/tests/configs.spec.ts +0 -184
- package/src/constants/db.ts +0 -63
- package/src/constants/index.ts +0 -2
- package/src/constants/misc.ts +0 -50
- package/src/context/Context.ts +0 -14
- package/src/context/identity.ts +0 -58
- package/src/context/index.ts +0 -3
- package/src/context/mainContext.ts +0 -310
- package/src/context/tests/index.spec.ts +0 -147
- package/src/context/types.ts +0 -11
- package/src/db/Replication.ts +0 -84
- package/src/db/constants.ts +0 -10
- package/src/db/couch/DatabaseImpl.ts +0 -238
- package/src/db/couch/connections.ts +0 -77
- package/src/db/couch/index.ts +0 -5
- package/src/db/couch/pouchDB.ts +0 -97
- package/src/db/couch/pouchDump.ts +0 -0
- package/src/db/couch/utils.ts +0 -50
- package/src/db/db.ts +0 -39
- package/src/db/errors.ts +0 -14
- package/src/db/index.ts +0 -12
- package/src/db/lucene.ts +0 -732
- package/src/db/searchIndexes/index.ts +0 -1
- package/src/db/searchIndexes/searchIndexes.ts +0 -62
- package/src/db/tests/index.spec.js +0 -25
- package/src/db/tests/lucene.spec.ts +0 -298
- package/src/db/tests/pouch.spec.js +0 -62
- package/src/db/tests/utils.spec.ts +0 -63
- package/src/db/utils.ts +0 -207
- package/src/db/views.ts +0 -241
- package/src/docIds/conversions.ts +0 -59
- package/src/docIds/ids.ts +0 -113
- package/src/docIds/index.ts +0 -2
- package/src/docIds/newid.ts +0 -5
- package/src/docIds/params.ts +0 -174
- package/src/docUpdates/index.ts +0 -29
- package/src/environment.ts +0 -201
- package/src/errors/errors.ts +0 -119
- package/src/errors/index.ts +0 -1
- package/src/events/analytics.ts +0 -6
- package/src/events/asyncEvents/index.ts +0 -2
- package/src/events/asyncEvents/publisher.ts +0 -12
- package/src/events/asyncEvents/queue.ts +0 -22
- package/src/events/backfill.ts +0 -183
- package/src/events/documentId.ts +0 -56
- package/src/events/events.ts +0 -40
- package/src/events/identification.ts +0 -310
- package/src/events/index.ts +0 -14
- package/src/events/processors/AnalyticsProcessor.ts +0 -64
- package/src/events/processors/AuditLogsProcessor.ts +0 -93
- package/src/events/processors/LoggingProcessor.ts +0 -37
- package/src/events/processors/Processors.ts +0 -52
- package/src/events/processors/async/DocumentUpdateProcessor.ts +0 -43
- package/src/events/processors/index.ts +0 -19
- package/src/events/processors/posthog/PosthogProcessor.ts +0 -118
- package/src/events/processors/posthog/index.ts +0 -2
- package/src/events/processors/posthog/rateLimiting.ts +0 -106
- package/src/events/processors/posthog/tests/PosthogProcessor.spec.ts +0 -168
- package/src/events/processors/types.ts +0 -1
- package/src/events/publishers/account.ts +0 -35
- package/src/events/publishers/app.ts +0 -155
- package/src/events/publishers/auditLog.ts +0 -26
- package/src/events/publishers/auth.ts +0 -73
- package/src/events/publishers/automation.ts +0 -110
- package/src/events/publishers/backfill.ts +0 -74
- package/src/events/publishers/backup.ts +0 -42
- package/src/events/publishers/datasource.ts +0 -48
- package/src/events/publishers/email.ts +0 -17
- package/src/events/publishers/environmentVariable.ts +0 -38
- package/src/events/publishers/group.ts +0 -99
- package/src/events/publishers/index.ts +0 -24
- package/src/events/publishers/installation.ts +0 -38
- package/src/events/publishers/layout.ts +0 -26
- package/src/events/publishers/license.ts +0 -84
- package/src/events/publishers/org.ts +0 -37
- package/src/events/publishers/plugin.ts +0 -47
- package/src/events/publishers/query.ts +0 -88
- package/src/events/publishers/role.ts +0 -62
- package/src/events/publishers/rows.ts +0 -29
- package/src/events/publishers/screen.ts +0 -36
- package/src/events/publishers/serve.ts +0 -43
- package/src/events/publishers/table.ts +0 -70
- package/src/events/publishers/user.ts +0 -202
- package/src/events/publishers/view.ts +0 -107
- package/src/featureFlags/index.ts +0 -77
- package/src/featureFlags/tests/featureFlags.spec.ts +0 -85
- package/src/helpers.ts +0 -9
- package/src/index.ts +0 -53
- package/src/installation.ts +0 -107
- package/src/logging/alerts.ts +0 -26
- package/src/logging/correlation/correlation.ts +0 -13
- package/src/logging/correlation/index.ts +0 -1
- package/src/logging/correlation/middleware.ts +0 -17
- package/src/logging/index.ts +0 -4
- package/src/logging/pino/logger.ts +0 -232
- package/src/logging/pino/middleware.ts +0 -45
- package/src/logging/system.ts +0 -81
- package/src/logging/tests/system.spec.ts +0 -61
- package/src/middleware/adminOnly.ts +0 -9
- package/src/middleware/auditLog.ts +0 -6
- package/src/middleware/authenticated.ts +0 -193
- package/src/middleware/builderOnly.ts +0 -20
- package/src/middleware/builderOrAdmin.ts +0 -20
- package/src/middleware/csrf.ts +0 -81
- package/src/middleware/errorHandling.ts +0 -29
- package/src/middleware/index.ts +0 -21
- package/src/middleware/internalApi.ts +0 -23
- package/src/middleware/joi-validator.ts +0 -45
- package/src/middleware/matchers.ts +0 -47
- package/src/middleware/passport/datasource/google.ts +0 -95
- package/src/middleware/passport/local.ts +0 -54
- package/src/middleware/passport/sso/google.ts +0 -77
- package/src/middleware/passport/sso/oidc.ts +0 -154
- package/src/middleware/passport/sso/sso.ts +0 -165
- package/src/middleware/passport/sso/tests/google.spec.ts +0 -67
- package/src/middleware/passport/sso/tests/oidc.spec.ts +0 -152
- package/src/middleware/passport/sso/tests/sso.spec.ts +0 -197
- package/src/middleware/passport/utils.ts +0 -38
- package/src/middleware/querystringToBody.ts +0 -28
- package/src/middleware/tenancy.ts +0 -36
- package/src/middleware/tests/builder.spec.ts +0 -180
- package/src/middleware/tests/matchers.spec.ts +0 -134
- package/src/migrations/definitions.ts +0 -40
- package/src/migrations/index.ts +0 -2
- package/src/migrations/migrations.ts +0 -191
- package/src/migrations/tests/__snapshots__/migrations.spec.ts.snap +0 -11
- package/src/migrations/tests/migrations.spec.ts +0 -64
- package/src/objectStore/buckets/app.ts +0 -40
- package/src/objectStore/buckets/global.ts +0 -29
- package/src/objectStore/buckets/index.ts +0 -3
- package/src/objectStore/buckets/plugins.ts +0 -71
- package/src/objectStore/buckets/tests/app.spec.ts +0 -171
- package/src/objectStore/buckets/tests/global.spec.ts +0 -74
- package/src/objectStore/buckets/tests/plugins.spec.ts +0 -111
- package/src/objectStore/cloudfront.ts +0 -41
- package/src/objectStore/index.ts +0 -3
- package/src/objectStore/objectStore.ts +0 -440
- package/src/objectStore/utils.ts +0 -27
- package/src/platform/index.ts +0 -3
- package/src/platform/platformDb.ts +0 -6
- package/src/platform/tenants.ts +0 -101
- package/src/platform/tests/tenants.spec.ts +0 -26
- package/src/platform/users.ts +0 -90
- package/src/plugin/index.ts +0 -1
- package/src/plugin/tests/validation.spec.ts +0 -83
- package/src/plugin/utils.ts +0 -156
- package/src/queue/constants.ts +0 -6
- package/src/queue/inMemoryQueue.ts +0 -141
- package/src/queue/index.ts +0 -2
- package/src/queue/listeners.ts +0 -195
- package/src/queue/queue.ts +0 -54
- package/src/redis/index.ts +0 -6
- package/src/redis/init.ts +0 -86
- package/src/redis/redis.ts +0 -308
- package/src/redis/redlockImpl.ts +0 -139
- package/src/redis/utils.ts +0 -117
- package/src/security/encryption.ts +0 -179
- package/src/security/permissions.ts +0 -159
- package/src/security/roles.ts +0 -420
- package/src/security/sessions.ts +0 -120
- package/src/security/tests/encryption.spec.ts +0 -31
- package/src/security/tests/permissions.spec.ts +0 -145
- package/src/security/tests/sessions.spec.ts +0 -12
- package/src/tenancy/db.ts +0 -6
- package/src/tenancy/index.ts +0 -2
- package/src/tenancy/tenancy.ts +0 -140
- package/src/tenancy/tests/tenancy.spec.ts +0 -184
- package/src/timers/index.ts +0 -1
- package/src/timers/timers.ts +0 -22
- package/src/users/db.ts +0 -460
- package/src/users/events.ts +0 -176
- package/src/users/index.ts +0 -4
- package/src/users/lookup.ts +0 -102
- package/src/users/users.ts +0 -276
- package/src/users/utils.ts +0 -55
- package/src/utils/hashing.ts +0 -14
- package/src/utils/index.ts +0 -3
- package/src/utils/stringUtils.ts +0 -8
- package/src/utils/tests/utils.spec.ts +0 -191
- package/src/utils/utils.ts +0 -239
- package/tests/core/logging.ts +0 -34
- package/tests/core/utilities/index.ts +0 -6
- package/tests/core/utilities/jestUtils.ts +0 -30
- package/tests/core/utilities/mocks/alerts.ts +0 -3
- package/tests/core/utilities/mocks/date.ts +0 -2
- package/tests/core/utilities/mocks/events.ts +0 -131
- package/tests/core/utilities/mocks/fetch.ts +0 -17
- package/tests/core/utilities/mocks/index.ts +0 -10
- package/tests/core/utilities/mocks/licenses.ts +0 -107
- package/tests/core/utilities/mocks/posthog.ts +0 -7
- package/tests/core/utilities/structures/Chance.ts +0 -20
- package/tests/core/utilities/structures/accounts.ts +0 -115
- package/tests/core/utilities/structures/apps.ts +0 -21
- package/tests/core/utilities/structures/common.ts +0 -7
- package/tests/core/utilities/structures/db.ts +0 -12
- package/tests/core/utilities/structures/documents/index.ts +0 -1
- package/tests/core/utilities/structures/documents/platform/index.ts +0 -1
- package/tests/core/utilities/structures/documents/platform/installation.ts +0 -12
- package/tests/core/utilities/structures/generator.ts +0 -2
- package/tests/core/utilities/structures/index.ts +0 -15
- package/tests/core/utilities/structures/koa.ts +0 -16
- package/tests/core/utilities/structures/licenses.ts +0 -167
- package/tests/core/utilities/structures/plugins.ts +0 -19
- package/tests/core/utilities/structures/quotas.ts +0 -67
- package/tests/core/utilities/structures/scim.ts +0 -80
- package/tests/core/utilities/structures/shared.ts +0 -19
- package/tests/core/utilities/structures/sso.ts +0 -119
- package/tests/core/utilities/structures/tenants.ts +0 -5
- package/tests/core/utilities/structures/userGroups.ts +0 -10
- package/tests/core/utilities/structures/users.ts +0 -73
- package/tests/core/utilities/testContainerUtils.ts +0 -98
- package/tests/core/utilities/utils/index.ts +0 -1
- package/tests/core/utilities/utils/time.ts +0 -3
- package/tests/extra/DBTestConfiguration.ts +0 -36
- package/tests/extra/index.ts +0 -2
- package/tests/extra/testEnv.ts +0 -95
- package/tests/index.ts +0 -1
- package/tests/jestEnv.ts +0 -6
- package/tests/jestSetup.ts +0 -28
- package/tsconfig.build.json +0 -29
- package/tsconfig.json +0 -4
package/src/security/roles.ts
DELETED
|
@@ -1,420 +0,0 @@
|
|
|
1
|
-
import { BuiltinPermissionID, PermissionLevel } from "./permissions"
|
|
2
|
-
import { prefixRoleID, getRoleParams, DocumentType, SEPARATOR } from "../db"
|
|
3
|
-
import { getAppDB } from "../context"
|
|
4
|
-
import { doWithDB } from "../db"
|
|
5
|
-
import { Screen, Role as RoleDoc } from "@budibase/types"
|
|
6
|
-
import cloneDeep from "lodash/fp/cloneDeep"
|
|
7
|
-
|
|
8
|
-
export const BUILTIN_ROLE_IDS = {
|
|
9
|
-
ADMIN: "ADMIN",
|
|
10
|
-
POWER: "POWER",
|
|
11
|
-
BASIC: "BASIC",
|
|
12
|
-
PUBLIC: "PUBLIC",
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
const BUILTIN_IDS = {
|
|
16
|
-
...BUILTIN_ROLE_IDS,
|
|
17
|
-
BUILDER: "BUILDER",
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
// exclude internal roles like builder
|
|
21
|
-
const EXTERNAL_BUILTIN_ROLE_IDS = [
|
|
22
|
-
BUILTIN_IDS.ADMIN,
|
|
23
|
-
BUILTIN_IDS.POWER,
|
|
24
|
-
BUILTIN_IDS.BASIC,
|
|
25
|
-
BUILTIN_IDS.PUBLIC,
|
|
26
|
-
]
|
|
27
|
-
|
|
28
|
-
export const RoleIDVersion = {
|
|
29
|
-
// original version, with a UUID based ID
|
|
30
|
-
UUID: undefined,
|
|
31
|
-
// new version - with name based ID
|
|
32
|
-
NAME: "name",
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export class Role implements RoleDoc {
|
|
36
|
-
_id: string
|
|
37
|
-
_rev?: string
|
|
38
|
-
name: string
|
|
39
|
-
permissionId: string
|
|
40
|
-
inherits?: string
|
|
41
|
-
version?: string
|
|
42
|
-
permissions = {}
|
|
43
|
-
|
|
44
|
-
constructor(id: string, name: string, permissionId: string) {
|
|
45
|
-
this._id = id
|
|
46
|
-
this.name = name
|
|
47
|
-
this.permissionId = permissionId
|
|
48
|
-
// version for managing the ID - removing the role_ when responding
|
|
49
|
-
this.version = RoleIDVersion.NAME
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
addInheritance(inherits: string) {
|
|
53
|
-
this.inherits = inherits
|
|
54
|
-
return this
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
const BUILTIN_ROLES = {
|
|
59
|
-
ADMIN: new Role(
|
|
60
|
-
BUILTIN_IDS.ADMIN,
|
|
61
|
-
"Admin",
|
|
62
|
-
BuiltinPermissionID.ADMIN
|
|
63
|
-
).addInheritance(BUILTIN_IDS.POWER),
|
|
64
|
-
POWER: new Role(
|
|
65
|
-
BUILTIN_IDS.POWER,
|
|
66
|
-
"Power",
|
|
67
|
-
BuiltinPermissionID.POWER
|
|
68
|
-
).addInheritance(BUILTIN_IDS.BASIC),
|
|
69
|
-
BASIC: new Role(
|
|
70
|
-
BUILTIN_IDS.BASIC,
|
|
71
|
-
"Basic",
|
|
72
|
-
BuiltinPermissionID.WRITE
|
|
73
|
-
).addInheritance(BUILTIN_IDS.PUBLIC),
|
|
74
|
-
PUBLIC: new Role(BUILTIN_IDS.PUBLIC, "Public", BuiltinPermissionID.PUBLIC),
|
|
75
|
-
BUILDER: new Role(BUILTIN_IDS.BUILDER, "Builder", BuiltinPermissionID.ADMIN),
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
export function getBuiltinRoles(): { [key: string]: RoleDoc } {
|
|
79
|
-
return cloneDeep(BUILTIN_ROLES)
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
export const BUILTIN_ROLE_ID_ARRAY = Object.values(BUILTIN_ROLES).map(
|
|
83
|
-
role => role._id
|
|
84
|
-
)
|
|
85
|
-
|
|
86
|
-
export const BUILTIN_ROLE_NAME_ARRAY = Object.values(BUILTIN_ROLES).map(
|
|
87
|
-
role => role.name
|
|
88
|
-
)
|
|
89
|
-
|
|
90
|
-
export function isBuiltin(role?: string) {
|
|
91
|
-
return BUILTIN_ROLE_ID_ARRAY.some(builtin => role?.includes(builtin))
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* Works through the inheritance ranks to see how far up the builtin stack this ID is.
|
|
96
|
-
*/
|
|
97
|
-
export function builtinRoleToNumber(id?: string) {
|
|
98
|
-
if (!id) {
|
|
99
|
-
return 0
|
|
100
|
-
}
|
|
101
|
-
const builtins = getBuiltinRoles()
|
|
102
|
-
const MAX = Object.values(builtins).length + 1
|
|
103
|
-
if (id === BUILTIN_IDS.ADMIN || id === BUILTIN_IDS.BUILDER) {
|
|
104
|
-
return MAX
|
|
105
|
-
}
|
|
106
|
-
let role = builtins[id],
|
|
107
|
-
count = 0
|
|
108
|
-
do {
|
|
109
|
-
if (!role) {
|
|
110
|
-
break
|
|
111
|
-
}
|
|
112
|
-
role = builtins[role.inherits!]
|
|
113
|
-
count++
|
|
114
|
-
} while (role !== null)
|
|
115
|
-
return count
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* Converts any role to a number, but has to be async to get the roles from db.
|
|
120
|
-
*/
|
|
121
|
-
export async function roleToNumber(id?: string) {
|
|
122
|
-
if (isBuiltin(id)) {
|
|
123
|
-
return builtinRoleToNumber(id)
|
|
124
|
-
}
|
|
125
|
-
const hierarchy = (await getUserRoleHierarchy(id)) as RoleDoc[]
|
|
126
|
-
for (let role of hierarchy) {
|
|
127
|
-
if (isBuiltin(role?.inherits)) {
|
|
128
|
-
return builtinRoleToNumber(role.inherits) + 1
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
return 0
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
/**
|
|
135
|
-
* Returns whichever builtin roleID is lower.
|
|
136
|
-
*/
|
|
137
|
-
export function lowerBuiltinRoleID(roleId1?: string, roleId2?: string): string {
|
|
138
|
-
if (!roleId1) {
|
|
139
|
-
return roleId2 as string
|
|
140
|
-
}
|
|
141
|
-
if (!roleId2) {
|
|
142
|
-
return roleId1 as string
|
|
143
|
-
}
|
|
144
|
-
return builtinRoleToNumber(roleId1) > builtinRoleToNumber(roleId2)
|
|
145
|
-
? roleId2
|
|
146
|
-
: roleId1
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
/**
|
|
150
|
-
* Gets the role object, this is mainly useful for two purposes, to check if the level exists and
|
|
151
|
-
* to check if the role inherits any others.
|
|
152
|
-
* @param {string|null} roleId The level ID to lookup.
|
|
153
|
-
* @param {object|null} opts options for the function, like whether to halt errors, instead return public.
|
|
154
|
-
* @returns {Promise<Role|object|null>} The role object, which may contain an "inherits" property.
|
|
155
|
-
*/
|
|
156
|
-
export async function getRole(
|
|
157
|
-
roleId?: string,
|
|
158
|
-
opts?: { defaultPublic?: boolean }
|
|
159
|
-
): Promise<RoleDoc | undefined> {
|
|
160
|
-
if (!roleId) {
|
|
161
|
-
return undefined
|
|
162
|
-
}
|
|
163
|
-
let role: any = {}
|
|
164
|
-
// built in roles mostly come from the in-code implementation,
|
|
165
|
-
// but can be extended by a doc stored about them (e.g. permissions)
|
|
166
|
-
if (isBuiltin(roleId)) {
|
|
167
|
-
role = cloneDeep(
|
|
168
|
-
Object.values(BUILTIN_ROLES).find(role => role._id === roleId)
|
|
169
|
-
)
|
|
170
|
-
} else {
|
|
171
|
-
// make sure has the prefix (if it has it then it won't be added)
|
|
172
|
-
roleId = prefixRoleID(roleId)
|
|
173
|
-
}
|
|
174
|
-
try {
|
|
175
|
-
const db = getAppDB()
|
|
176
|
-
const dbRole = await db.get(getDBRoleID(roleId))
|
|
177
|
-
role = Object.assign(role, dbRole)
|
|
178
|
-
// finalise the ID
|
|
179
|
-
role._id = getExternalRoleID(role._id, role.version)
|
|
180
|
-
} catch (err) {
|
|
181
|
-
if (!isBuiltin(roleId) && opts?.defaultPublic) {
|
|
182
|
-
return cloneDeep(BUILTIN_ROLES.PUBLIC)
|
|
183
|
-
}
|
|
184
|
-
// only throw an error if there is no role at all
|
|
185
|
-
if (Object.keys(role).length === 0) {
|
|
186
|
-
throw err
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
return role
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
/**
|
|
193
|
-
* Simple function to get all the roles based on the top level user role ID.
|
|
194
|
-
*/
|
|
195
|
-
async function getAllUserRoles(userRoleId?: string): Promise<RoleDoc[]> {
|
|
196
|
-
// admins have access to all roles
|
|
197
|
-
if (userRoleId === BUILTIN_IDS.ADMIN) {
|
|
198
|
-
return getAllRoles()
|
|
199
|
-
}
|
|
200
|
-
let currentRole = await getRole(userRoleId)
|
|
201
|
-
let roles = currentRole ? [currentRole] : []
|
|
202
|
-
let roleIds = [userRoleId]
|
|
203
|
-
// get all the inherited roles
|
|
204
|
-
while (
|
|
205
|
-
currentRole &&
|
|
206
|
-
currentRole.inherits &&
|
|
207
|
-
roleIds.indexOf(currentRole.inherits) === -1
|
|
208
|
-
) {
|
|
209
|
-
roleIds.push(currentRole.inherits)
|
|
210
|
-
currentRole = await getRole(currentRole.inherits)
|
|
211
|
-
if (currentRole) {
|
|
212
|
-
roles.push(currentRole)
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
return roles
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
/**
|
|
219
|
-
* Returns an ordered array of the user's inherited role IDs, this can be used
|
|
220
|
-
* to determine if a user can access something that requires a specific role.
|
|
221
|
-
* @param {string} userRoleId The user's role ID, this can be found in their access token.
|
|
222
|
-
* @param {object} opts Various options, such as whether to only retrieve the IDs (default true).
|
|
223
|
-
* @returns {Promise<string[]|object[]>} returns an ordered array of the roles, with the first being their
|
|
224
|
-
* highest level of access and the last being the lowest level.
|
|
225
|
-
*/
|
|
226
|
-
export async function getUserRoleHierarchy(
|
|
227
|
-
userRoleId?: string,
|
|
228
|
-
opts = { idOnly: true }
|
|
229
|
-
) {
|
|
230
|
-
// special case, if they don't have a role then they are a public user
|
|
231
|
-
const roles = await getAllUserRoles(userRoleId)
|
|
232
|
-
return opts.idOnly ? roles.map(role => role._id) : roles
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
// this function checks that the provided permissions are in an array format
|
|
236
|
-
// some templates/older apps will use a simple string instead of array for roles
|
|
237
|
-
// convert the string to an array using the theory that write is higher than read
|
|
238
|
-
export function checkForRoleResourceArray(
|
|
239
|
-
rolePerms: { [key: string]: string[] },
|
|
240
|
-
resourceId: string
|
|
241
|
-
) {
|
|
242
|
-
if (rolePerms && !Array.isArray(rolePerms[resourceId])) {
|
|
243
|
-
const permLevel = rolePerms[resourceId] as any
|
|
244
|
-
rolePerms[resourceId] = [permLevel]
|
|
245
|
-
if (permLevel === PermissionLevel.WRITE) {
|
|
246
|
-
rolePerms[resourceId].push(PermissionLevel.READ)
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
return rolePerms
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
/**
|
|
253
|
-
* Given an app ID this will retrieve all of the roles that are currently within that app.
|
|
254
|
-
* @return {Promise<object[]>} An array of the role objects that were found.
|
|
255
|
-
*/
|
|
256
|
-
export async function getAllRoles(appId?: string) {
|
|
257
|
-
if (appId) {
|
|
258
|
-
return doWithDB(appId, internal)
|
|
259
|
-
} else {
|
|
260
|
-
let appDB
|
|
261
|
-
try {
|
|
262
|
-
appDB = getAppDB()
|
|
263
|
-
} catch (error) {
|
|
264
|
-
// We don't have any apps, so we'll just use the built-in roles
|
|
265
|
-
}
|
|
266
|
-
return internal(appDB)
|
|
267
|
-
}
|
|
268
|
-
async function internal(db: any) {
|
|
269
|
-
let roles: RoleDoc[] = []
|
|
270
|
-
if (db) {
|
|
271
|
-
const body = await db.allDocs(
|
|
272
|
-
getRoleParams(null, {
|
|
273
|
-
include_docs: true,
|
|
274
|
-
})
|
|
275
|
-
)
|
|
276
|
-
roles = body.rows.map((row: any) => row.doc)
|
|
277
|
-
roles.forEach(
|
|
278
|
-
role => (role._id = getExternalRoleID(role._id!, role.version))
|
|
279
|
-
)
|
|
280
|
-
}
|
|
281
|
-
const builtinRoles = getBuiltinRoles()
|
|
282
|
-
|
|
283
|
-
// need to combine builtin with any DB record of them (for sake of permissions)
|
|
284
|
-
for (let builtinRoleId of EXTERNAL_BUILTIN_ROLE_IDS) {
|
|
285
|
-
const builtinRole = builtinRoles[builtinRoleId]
|
|
286
|
-
const dbBuiltin = roles.filter(
|
|
287
|
-
dbRole =>
|
|
288
|
-
getExternalRoleID(dbRole._id!, dbRole.version) === builtinRoleId
|
|
289
|
-
)[0]
|
|
290
|
-
if (dbBuiltin == null) {
|
|
291
|
-
roles.push(builtinRole || builtinRoles.BASIC)
|
|
292
|
-
} else {
|
|
293
|
-
// remove role and all back after combining with the builtin
|
|
294
|
-
roles = roles.filter(role => role._id !== dbBuiltin._id)
|
|
295
|
-
dbBuiltin._id = getExternalRoleID(dbBuiltin._id!, dbBuiltin.version)
|
|
296
|
-
roles.push(Object.assign(builtinRole, dbBuiltin))
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
// check permissions
|
|
300
|
-
for (let role of roles) {
|
|
301
|
-
if (!role.permissions) {
|
|
302
|
-
continue
|
|
303
|
-
}
|
|
304
|
-
for (let resourceId of Object.keys(role.permissions)) {
|
|
305
|
-
role.permissions = checkForRoleResourceArray(
|
|
306
|
-
role.permissions,
|
|
307
|
-
resourceId
|
|
308
|
-
)
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
return roles
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
/**
|
|
316
|
-
* This retrieves the required role for a resource
|
|
317
|
-
* @param permLevel The level of request
|
|
318
|
-
* @param resourceId The resource being requested
|
|
319
|
-
* @param subResourceId The sub resource being requested
|
|
320
|
-
* @return {Promise<{permissions}|Object>} returns the permissions required to access.
|
|
321
|
-
*/
|
|
322
|
-
export async function getRequiredResourceRole(
|
|
323
|
-
permLevel: string,
|
|
324
|
-
{ resourceId, subResourceId }: { resourceId?: string; subResourceId?: string }
|
|
325
|
-
) {
|
|
326
|
-
const roles = await getAllRoles()
|
|
327
|
-
let main = [],
|
|
328
|
-
sub = []
|
|
329
|
-
for (let role of roles) {
|
|
330
|
-
// no permissions, ignore it
|
|
331
|
-
if (!role.permissions) {
|
|
332
|
-
continue
|
|
333
|
-
}
|
|
334
|
-
const mainRes = resourceId ? role.permissions[resourceId] : undefined
|
|
335
|
-
const subRes = subResourceId ? role.permissions[subResourceId] : undefined
|
|
336
|
-
if (mainRes && mainRes.indexOf(permLevel) !== -1) {
|
|
337
|
-
main.push(role._id)
|
|
338
|
-
} else if (subRes && subRes.indexOf(permLevel) !== -1) {
|
|
339
|
-
sub.push(role._id)
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
// for now just return the IDs
|
|
343
|
-
return main.concat(sub)
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
export class AccessController {
|
|
347
|
-
userHierarchies: { [key: string]: string[] }
|
|
348
|
-
constructor() {
|
|
349
|
-
this.userHierarchies = {}
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
async hasAccess(tryingRoleId?: string, userRoleId?: string) {
|
|
353
|
-
// special cases, the screen has no role, the roles are the same or the user
|
|
354
|
-
// is currently in the builder
|
|
355
|
-
if (
|
|
356
|
-
tryingRoleId == null ||
|
|
357
|
-
tryingRoleId === "" ||
|
|
358
|
-
tryingRoleId === userRoleId ||
|
|
359
|
-
tryingRoleId === BUILTIN_IDS.BUILDER ||
|
|
360
|
-
userRoleId === BUILTIN_IDS.BUILDER
|
|
361
|
-
) {
|
|
362
|
-
return true
|
|
363
|
-
}
|
|
364
|
-
let roleIds = userRoleId ? this.userHierarchies[userRoleId] : null
|
|
365
|
-
if (!roleIds && userRoleId) {
|
|
366
|
-
roleIds = (await getUserRoleHierarchy(userRoleId, {
|
|
367
|
-
idOnly: true,
|
|
368
|
-
})) as string[]
|
|
369
|
-
this.userHierarchies[userRoleId] = roleIds
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
return roleIds?.indexOf(tryingRoleId) !== -1
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
async checkScreensAccess(screens: Screen[], userRoleId: string) {
|
|
376
|
-
let accessibleScreens = []
|
|
377
|
-
// don't want to handle this with Promise.all as this would mean all custom roles would be
|
|
378
|
-
// retrieved at same time, it is likely a custom role will be re-used and therefore want
|
|
379
|
-
// to work in sync for performance save
|
|
380
|
-
for (let screen of screens) {
|
|
381
|
-
const accessible = await this.checkScreenAccess(screen, userRoleId)
|
|
382
|
-
if (accessible) {
|
|
383
|
-
accessibleScreens.push(accessible)
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
return accessibleScreens
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
async checkScreenAccess(screen: Screen, userRoleId: string) {
|
|
390
|
-
const roleId = screen && screen.routing ? screen.routing.roleId : undefined
|
|
391
|
-
if (await this.hasAccess(roleId, userRoleId)) {
|
|
392
|
-
return screen
|
|
393
|
-
}
|
|
394
|
-
return null
|
|
395
|
-
}
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
/**
|
|
399
|
-
* Adds the "role_" for builtin role IDs which are to be written to the DB (for permissions).
|
|
400
|
-
*/
|
|
401
|
-
export function getDBRoleID(roleName: string) {
|
|
402
|
-
if (roleName?.startsWith(DocumentType.ROLE)) {
|
|
403
|
-
return roleName
|
|
404
|
-
}
|
|
405
|
-
return prefixRoleID(roleName)
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
/**
|
|
409
|
-
* Remove the "role_" from builtin role IDs that have been written to the DB (for permissions).
|
|
410
|
-
*/
|
|
411
|
-
export function getExternalRoleID(roleId: string, version?: string) {
|
|
412
|
-
// for built-in roles we want to remove the DB role ID element (role_)
|
|
413
|
-
if (
|
|
414
|
-
(roleId.startsWith(DocumentType.ROLE) && isBuiltin(roleId)) ||
|
|
415
|
-
version === RoleIDVersion.NAME
|
|
416
|
-
) {
|
|
417
|
-
return roleId.split(`${DocumentType.ROLE}${SEPARATOR}`)[1]
|
|
418
|
-
}
|
|
419
|
-
return roleId
|
|
420
|
-
}
|
package/src/security/sessions.ts
DELETED
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
const redis = require("../redis/init")
|
|
2
|
-
const { v4: uuidv4 } = require("uuid")
|
|
3
|
-
const { logWarn } = require("../logging")
|
|
4
|
-
import env from "../environment"
|
|
5
|
-
import {
|
|
6
|
-
Session,
|
|
7
|
-
ScannedSession,
|
|
8
|
-
SessionKey,
|
|
9
|
-
CreateSession,
|
|
10
|
-
} from "@budibase/types"
|
|
11
|
-
|
|
12
|
-
// a week in seconds
|
|
13
|
-
const EXPIRY_SECONDS = 86400 * 7
|
|
14
|
-
|
|
15
|
-
function makeSessionID(userId: string, sessionId: string) {
|
|
16
|
-
return `${userId}/${sessionId}`
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export async function getSessionsForUser(userId: string): Promise<Session[]> {
|
|
20
|
-
if (!userId) {
|
|
21
|
-
console.trace("Cannot get sessions for undefined userId")
|
|
22
|
-
return []
|
|
23
|
-
}
|
|
24
|
-
const client = await redis.getSessionClient()
|
|
25
|
-
const sessions: ScannedSession[] = await client.scan(userId)
|
|
26
|
-
return sessions.map(session => session.value)
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export async function invalidateSessions(
|
|
30
|
-
userId: string,
|
|
31
|
-
opts: { sessionIds?: string[]; reason?: string } = {}
|
|
32
|
-
) {
|
|
33
|
-
try {
|
|
34
|
-
const reason = opts?.reason || "unknown"
|
|
35
|
-
let sessionIds: string[] = opts.sessionIds || []
|
|
36
|
-
let sessionKeys: SessionKey[]
|
|
37
|
-
|
|
38
|
-
// If no sessionIds, get all the sessions for the user
|
|
39
|
-
if (sessionIds.length === 0) {
|
|
40
|
-
const sessions = await getSessionsForUser(userId)
|
|
41
|
-
sessionKeys = sessions.map(session => ({
|
|
42
|
-
key: makeSessionID(session.userId, session.sessionId),
|
|
43
|
-
}))
|
|
44
|
-
} else {
|
|
45
|
-
// use the passed array of sessionIds
|
|
46
|
-
sessionIds = Array.isArray(sessionIds) ? sessionIds : [sessionIds]
|
|
47
|
-
sessionKeys = sessionIds.map(sessionId => ({
|
|
48
|
-
key: makeSessionID(userId, sessionId),
|
|
49
|
-
}))
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
if (sessionKeys && sessionKeys.length > 0) {
|
|
53
|
-
const client = await redis.getSessionClient()
|
|
54
|
-
const promises = []
|
|
55
|
-
for (let sessionKey of sessionKeys) {
|
|
56
|
-
promises.push(client.delete(sessionKey.key))
|
|
57
|
-
}
|
|
58
|
-
if (!env.isTest()) {
|
|
59
|
-
logWarn(
|
|
60
|
-
`Invalidating sessions for ${userId} (reason: ${reason}) - ${sessionKeys
|
|
61
|
-
.map(sessionKey => sessionKey.key)
|
|
62
|
-
.join(", ")}`
|
|
63
|
-
)
|
|
64
|
-
}
|
|
65
|
-
await Promise.all(promises)
|
|
66
|
-
}
|
|
67
|
-
} catch (err) {
|
|
68
|
-
console.error(`Error invalidating sessions: ${err}`)
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
export async function createASession(
|
|
73
|
-
userId: string,
|
|
74
|
-
createSession: CreateSession
|
|
75
|
-
) {
|
|
76
|
-
// invalidate all other sessions
|
|
77
|
-
await invalidateSessions(userId, { reason: "creation" })
|
|
78
|
-
|
|
79
|
-
const client = await redis.getSessionClient()
|
|
80
|
-
const sessionId = createSession.sessionId
|
|
81
|
-
const csrfToken = createSession.csrfToken ? createSession.csrfToken : uuidv4()
|
|
82
|
-
const key = makeSessionID(userId, sessionId)
|
|
83
|
-
|
|
84
|
-
const session: Session = {
|
|
85
|
-
...createSession,
|
|
86
|
-
csrfToken,
|
|
87
|
-
createdAt: new Date().toISOString(),
|
|
88
|
-
lastAccessedAt: new Date().toISOString(),
|
|
89
|
-
userId,
|
|
90
|
-
}
|
|
91
|
-
await client.store(key, session, EXPIRY_SECONDS)
|
|
92
|
-
return session
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
export async function updateSessionTTL(session: Session) {
|
|
96
|
-
const client = await redis.getSessionClient()
|
|
97
|
-
const key = makeSessionID(session.userId, session.sessionId)
|
|
98
|
-
session.lastAccessedAt = new Date().toISOString()
|
|
99
|
-
await client.store(key, session, EXPIRY_SECONDS)
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
export async function endSession(userId: string, sessionId: string) {
|
|
103
|
-
const client = await redis.getSessionClient()
|
|
104
|
-
await client.delete(makeSessionID(userId, sessionId))
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
export async function getSession(
|
|
108
|
-
userId: string,
|
|
109
|
-
sessionId: string
|
|
110
|
-
): Promise<Session> {
|
|
111
|
-
if (!userId || !sessionId) {
|
|
112
|
-
throw new Error(`Invalid session details - ${userId} - ${sessionId}`)
|
|
113
|
-
}
|
|
114
|
-
const client = await redis.getSessionClient()
|
|
115
|
-
const session = await client.get(makeSessionID(userId, sessionId))
|
|
116
|
-
if (!session) {
|
|
117
|
-
throw new Error(`Session not found - ${userId} - ${sessionId}`)
|
|
118
|
-
}
|
|
119
|
-
return session
|
|
120
|
-
}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { encrypt, decrypt, SecretOption, getSecret } from "../encryption"
|
|
2
|
-
import env from "../../environment"
|
|
3
|
-
|
|
4
|
-
describe("encryption", () => {
|
|
5
|
-
it("should throw an error if API encryption key is not set", () => {
|
|
6
|
-
const jwt = getSecret(SecretOption.API)
|
|
7
|
-
expect(jwt).toBe(env.JWT_SECRET)
|
|
8
|
-
})
|
|
9
|
-
|
|
10
|
-
it("should throw an error if encryption key is not set", () => {
|
|
11
|
-
expect(() => getSecret(SecretOption.ENCRYPTION)).toThrow(
|
|
12
|
-
'Secret "ENCRYPTION_KEY" has not been set in environment.'
|
|
13
|
-
)
|
|
14
|
-
})
|
|
15
|
-
|
|
16
|
-
it("should encrypt and decrypt a string using API encryption key", () => {
|
|
17
|
-
env._set("API_ENCRYPTION_KEY", "api_secret")
|
|
18
|
-
const plaintext = "budibase"
|
|
19
|
-
const apiEncrypted = encrypt(plaintext, SecretOption.API)
|
|
20
|
-
const decrypted = decrypt(apiEncrypted, SecretOption.API)
|
|
21
|
-
expect(decrypted).toEqual(plaintext)
|
|
22
|
-
})
|
|
23
|
-
|
|
24
|
-
it("should encrypt and decrypt a string using encryption key", () => {
|
|
25
|
-
env._set("ENCRYPTION_KEY", "normal_secret")
|
|
26
|
-
const plaintext = "budibase"
|
|
27
|
-
const encryptionEncrypted = encrypt(plaintext, SecretOption.ENCRYPTION)
|
|
28
|
-
const decrypted = decrypt(encryptionEncrypted, SecretOption.ENCRYPTION)
|
|
29
|
-
expect(decrypted).toEqual(plaintext)
|
|
30
|
-
})
|
|
31
|
-
})
|
|
@@ -1,145 +0,0 @@
|
|
|
1
|
-
import cloneDeep from "lodash/cloneDeep"
|
|
2
|
-
import * as permissions from "../permissions"
|
|
3
|
-
import { BUILTIN_ROLE_IDS } from "../roles"
|
|
4
|
-
|
|
5
|
-
describe("levelToNumber", () => {
|
|
6
|
-
it("should return 0 for EXECUTE", () => {
|
|
7
|
-
expect(permissions.levelToNumber(permissions.PermissionLevel.EXECUTE)).toBe(
|
|
8
|
-
0
|
|
9
|
-
)
|
|
10
|
-
})
|
|
11
|
-
|
|
12
|
-
it("should return 1 for READ", () => {
|
|
13
|
-
expect(permissions.levelToNumber(permissions.PermissionLevel.READ)).toBe(1)
|
|
14
|
-
})
|
|
15
|
-
|
|
16
|
-
it("should return 2 for WRITE", () => {
|
|
17
|
-
expect(permissions.levelToNumber(permissions.PermissionLevel.WRITE)).toBe(2)
|
|
18
|
-
})
|
|
19
|
-
|
|
20
|
-
it("should return 3 for ADMIN", () => {
|
|
21
|
-
expect(permissions.levelToNumber(permissions.PermissionLevel.ADMIN)).toBe(3)
|
|
22
|
-
})
|
|
23
|
-
|
|
24
|
-
it("should return -1 for an unknown permission level", () => {
|
|
25
|
-
expect(
|
|
26
|
-
permissions.levelToNumber("unknown" as permissions.PermissionLevel)
|
|
27
|
-
).toBe(-1)
|
|
28
|
-
})
|
|
29
|
-
})
|
|
30
|
-
describe("getAllowedLevels", () => {
|
|
31
|
-
it('should return ["execute"] for EXECUTE', () => {
|
|
32
|
-
expect(
|
|
33
|
-
permissions.getAllowedLevels(permissions.PermissionLevel.EXECUTE)
|
|
34
|
-
).toEqual([permissions.PermissionLevel.EXECUTE])
|
|
35
|
-
})
|
|
36
|
-
|
|
37
|
-
it('should return ["execute", "read"] for READ', () => {
|
|
38
|
-
expect(
|
|
39
|
-
permissions.getAllowedLevels(permissions.PermissionLevel.READ)
|
|
40
|
-
).toEqual([
|
|
41
|
-
permissions.PermissionLevel.EXECUTE,
|
|
42
|
-
permissions.PermissionLevel.READ,
|
|
43
|
-
])
|
|
44
|
-
})
|
|
45
|
-
|
|
46
|
-
it('should return ["execute", "read", "write"] for WRITE', () => {
|
|
47
|
-
expect(
|
|
48
|
-
permissions.getAllowedLevels(permissions.PermissionLevel.WRITE)
|
|
49
|
-
).toEqual([
|
|
50
|
-
permissions.PermissionLevel.EXECUTE,
|
|
51
|
-
permissions.PermissionLevel.READ,
|
|
52
|
-
permissions.PermissionLevel.WRITE,
|
|
53
|
-
])
|
|
54
|
-
})
|
|
55
|
-
|
|
56
|
-
it('should return ["execute", "read", "write"] for ADMIN', () => {
|
|
57
|
-
expect(
|
|
58
|
-
permissions.getAllowedLevels(permissions.PermissionLevel.ADMIN)
|
|
59
|
-
).toEqual([
|
|
60
|
-
permissions.PermissionLevel.EXECUTE,
|
|
61
|
-
permissions.PermissionLevel.READ,
|
|
62
|
-
permissions.PermissionLevel.WRITE,
|
|
63
|
-
])
|
|
64
|
-
})
|
|
65
|
-
|
|
66
|
-
it("should return [] for an unknown permission level", () => {
|
|
67
|
-
expect(
|
|
68
|
-
permissions.getAllowedLevels("unknown" as permissions.PermissionLevel)
|
|
69
|
-
).toEqual([])
|
|
70
|
-
})
|
|
71
|
-
})
|
|
72
|
-
|
|
73
|
-
describe("doesHaveBasePermission", () => {
|
|
74
|
-
it("should return true if base permission has the required level", () => {
|
|
75
|
-
const permType = permissions.PermissionType.USER
|
|
76
|
-
const permLevel = permissions.PermissionLevel.READ
|
|
77
|
-
const rolesHierarchy = [
|
|
78
|
-
{
|
|
79
|
-
roleId: BUILTIN_ROLE_IDS.ADMIN,
|
|
80
|
-
permissionId: permissions.BuiltinPermissionID.ADMIN,
|
|
81
|
-
},
|
|
82
|
-
]
|
|
83
|
-
expect(
|
|
84
|
-
permissions.doesHaveBasePermission(permType, permLevel, rolesHierarchy)
|
|
85
|
-
).toBe(true)
|
|
86
|
-
})
|
|
87
|
-
|
|
88
|
-
it("should return false if base permission does not have the required level", () => {
|
|
89
|
-
const permType = permissions.PermissionType.APP
|
|
90
|
-
const permLevel = permissions.PermissionLevel.READ
|
|
91
|
-
const rolesHierarchy = [
|
|
92
|
-
{
|
|
93
|
-
roleId: BUILTIN_ROLE_IDS.PUBLIC,
|
|
94
|
-
permissionId: permissions.BuiltinPermissionID.PUBLIC,
|
|
95
|
-
},
|
|
96
|
-
]
|
|
97
|
-
expect(
|
|
98
|
-
permissions.doesHaveBasePermission(permType, permLevel, rolesHierarchy)
|
|
99
|
-
).toBe(false)
|
|
100
|
-
})
|
|
101
|
-
})
|
|
102
|
-
|
|
103
|
-
describe("isPermissionLevelHigherThanRead", () => {
|
|
104
|
-
it("should return true if level is higher than read", () => {
|
|
105
|
-
expect(
|
|
106
|
-
permissions.isPermissionLevelHigherThanRead(
|
|
107
|
-
permissions.PermissionLevel.WRITE
|
|
108
|
-
)
|
|
109
|
-
).toBe(true)
|
|
110
|
-
})
|
|
111
|
-
|
|
112
|
-
it("should return false if level is read or lower", () => {
|
|
113
|
-
expect(
|
|
114
|
-
permissions.isPermissionLevelHigherThanRead(
|
|
115
|
-
permissions.PermissionLevel.READ
|
|
116
|
-
)
|
|
117
|
-
).toBe(false)
|
|
118
|
-
})
|
|
119
|
-
})
|
|
120
|
-
|
|
121
|
-
describe("getBuiltinPermissions", () => {
|
|
122
|
-
it("returns a clone of the builtin permissions", () => {
|
|
123
|
-
const builtins = permissions.getBuiltinPermissions()
|
|
124
|
-
expect(builtins).toEqual(cloneDeep(permissions.BUILTIN_PERMISSIONS))
|
|
125
|
-
expect(builtins).not.toBe(permissions.BUILTIN_PERMISSIONS)
|
|
126
|
-
})
|
|
127
|
-
})
|
|
128
|
-
|
|
129
|
-
describe("getBuiltinPermissionByID", () => {
|
|
130
|
-
it("returns correct permission object for valid ID", () => {
|
|
131
|
-
const expectedPermission = {
|
|
132
|
-
_id: permissions.BuiltinPermissionID.PUBLIC,
|
|
133
|
-
name: "Public",
|
|
134
|
-
permissions: [
|
|
135
|
-
new permissions.Permission(
|
|
136
|
-
permissions.PermissionType.WEBHOOK,
|
|
137
|
-
permissions.PermissionLevel.EXECUTE
|
|
138
|
-
),
|
|
139
|
-
],
|
|
140
|
-
}
|
|
141
|
-
expect(permissions.getBuiltinPermissionByID("public")).toEqual(
|
|
142
|
-
expectedPermission
|
|
143
|
-
)
|
|
144
|
-
})
|
|
145
|
-
})
|