@budibase/worker 2.8.31-alpha.0 → 2.8.31
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/jest.config.ts +2 -0
- package/nodemon.json +6 -9
- package/package.json +27 -12
- package/scripts/test.sh +2 -2
- package/src/api/controllers/global/auth.ts +5 -5
- package/src/api/controllers/global/configs.ts +3 -3
- package/src/api/controllers/global/email.ts +3 -3
- package/src/api/controllers/global/roles.ts +7 -7
- package/src/api/controllers/global/self.ts +4 -4
- package/src/api/controllers/global/users.ts +14 -14
- package/src/api/routes/global/tests/auth.spec.ts +3 -3
- package/src/api/routes/global/tests/scim.spec.ts +2 -2
- package/src/api/routes/global/tests/self.spec.ts +2 -2
- package/src/api/routes/global/tests/users.spec.ts +2 -2
- package/src/api/routes/index.ts +0 -8
- package/src/api/routes/system/tests/status.spec.ts +4 -7
- package/src/environment.ts +1 -5
- package/src/initPro.ts +8 -1
- package/src/migrations/functions/globalInfoSyncUsers.ts +1 -1
- package/src/sdk/auth/auth.ts +9 -8
- package/src/sdk/users/events.ts +176 -0
- package/src/sdk/users/index.ts +0 -5
- package/src/sdk/users/tests/users.spec.ts +8 -8
- package/src/sdk/users/users.ts +590 -7
- package/src/tests/TestConfiguration.ts +4 -4
- package/src/tests/api/users.ts +0 -20
- package/src/tests/mocks/index.ts +1 -1
- package/tsconfig.json +4 -2
- package/src/api/controllers/system/logs.ts +0 -13
- package/src/api/routes/global/tests/appBuilder.spec.ts +0 -62
- package/src/api/routes/system/logs.ts +0 -9
package/jest.config.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { Config } from "@jest/types"
|
|
2
2
|
import * as fs from "fs"
|
|
3
|
+
const preset = require("ts-jest/jest-preset")
|
|
3
4
|
|
|
4
5
|
const config: Config.InitialOptions = {
|
|
6
|
+
...preset,
|
|
5
7
|
preset: "@trendyol/jest-testcontainers",
|
|
6
8
|
setupFiles: ["./src/tests/jestEnv.ts"],
|
|
7
9
|
setupFilesAfterEnv: ["./src/tests/jestSetup.ts"],
|
package/nodemon.json
CHANGED
|
@@ -1,13 +1,10 @@
|
|
|
1
1
|
{
|
|
2
|
-
"watch": [
|
|
3
|
-
"src",
|
|
4
|
-
"../backend-core",
|
|
5
|
-
"../pro",
|
|
6
|
-
"../types",
|
|
7
|
-
"../shared-core",
|
|
8
|
-
"../string-templates"
|
|
9
|
-
],
|
|
2
|
+
"watch": ["src", "../backend-core", "../pro"],
|
|
10
3
|
"ext": "js,ts,json",
|
|
11
|
-
"ignore": [
|
|
4
|
+
"ignore": [
|
|
5
|
+
"src/**/*.spec.ts",
|
|
6
|
+
"src/**/*.spec.js",
|
|
7
|
+
"../backend-core/dist/**/*"
|
|
8
|
+
],
|
|
12
9
|
"exec": "yarn build && node dist/index.js"
|
|
13
10
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@budibase/worker",
|
|
3
3
|
"email": "hi@budibase.com",
|
|
4
|
-
"version": "2.8.31
|
|
4
|
+
"version": "2.8.31",
|
|
5
5
|
"description": "Budibase background service",
|
|
6
6
|
"main": "src/index.ts",
|
|
7
7
|
"repository": {
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"scripts": {
|
|
15
15
|
"prebuild": "rimraf dist/",
|
|
16
16
|
"build": "node ../../scripts/build.js",
|
|
17
|
-
"check:types": "tsc -p tsconfig.json --noEmit
|
|
17
|
+
"check:types": "tsc -p tsconfig.build.json --noEmit",
|
|
18
18
|
"build:dev": "yarn prebuild && tsc --build --watch --preserveWatchOutput",
|
|
19
19
|
"run:docker": "node dist/index.js",
|
|
20
20
|
"debug": "yarn build && node --expose-gc --inspect=9223 dist/index.js",
|
|
@@ -38,10 +38,10 @@
|
|
|
38
38
|
"author": "Budibase",
|
|
39
39
|
"license": "GPL-3.0",
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@budibase/backend-core": "2.8.31
|
|
42
|
-
"@budibase/pro": "2.8.31
|
|
43
|
-
"@budibase/string-templates": "2.8.31
|
|
44
|
-
"@budibase/types": "2.8.31
|
|
41
|
+
"@budibase/backend-core": "2.8.31",
|
|
42
|
+
"@budibase/pro": "2.8.31",
|
|
43
|
+
"@budibase/string-templates": "2.8.31",
|
|
44
|
+
"@budibase/types": "2.8.31",
|
|
45
45
|
"@koa/router": "8.0.8",
|
|
46
46
|
"@sentry/node": "6.17.7",
|
|
47
47
|
"@techpass/passport-openidconnect": "0.3.2",
|
|
@@ -74,10 +74,10 @@
|
|
|
74
74
|
"server-destroy": "1.0.1"
|
|
75
75
|
},
|
|
76
76
|
"devDependencies": {
|
|
77
|
-
"@swc/core": "1.3.
|
|
78
|
-
"@swc/jest": "0.2.
|
|
79
|
-
"@trendyol/jest-testcontainers": "2.1.1",
|
|
80
|
-
"@types/jest": "
|
|
77
|
+
"@swc/core": "^1.3.25",
|
|
78
|
+
"@swc/jest": "^0.2.24",
|
|
79
|
+
"@trendyol/jest-testcontainers": "^2.1.1",
|
|
80
|
+
"@types/jest": "28.1.1",
|
|
81
81
|
"@types/jsonwebtoken": "8.5.1",
|
|
82
82
|
"@types/koa": "2.13.4",
|
|
83
83
|
"@types/koa__router": "8.0.8",
|
|
@@ -91,17 +91,32 @@
|
|
|
91
91
|
"@typescript-eslint/parser": "5.45.0",
|
|
92
92
|
"copyfiles": "2.4.1",
|
|
93
93
|
"eslint": "6.8.0",
|
|
94
|
-
"jest": "
|
|
94
|
+
"jest": "28.1.1",
|
|
95
95
|
"lodash": "4.17.21",
|
|
96
96
|
"nodemon": "2.0.15",
|
|
97
97
|
"pouchdb-adapter-memory": "7.2.2",
|
|
98
98
|
"rimraf": "3.0.2",
|
|
99
99
|
"supertest": "6.2.2",
|
|
100
100
|
"timekeeper": "2.2.0",
|
|
101
|
+
"ts-jest": "28.0.4",
|
|
101
102
|
"ts-node": "10.8.1",
|
|
102
103
|
"tsconfig-paths": "4.0.0",
|
|
103
104
|
"typescript": "4.7.3",
|
|
104
105
|
"update-dotenv": "1.1.1"
|
|
105
106
|
},
|
|
106
|
-
"
|
|
107
|
+
"nx": {
|
|
108
|
+
"targets": {
|
|
109
|
+
"dev:builder": {
|
|
110
|
+
"dependsOn": [
|
|
111
|
+
{
|
|
112
|
+
"projects": [
|
|
113
|
+
"@budibase/backend-core"
|
|
114
|
+
],
|
|
115
|
+
"target": "build"
|
|
116
|
+
}
|
|
117
|
+
]
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
},
|
|
121
|
+
"gitHead": "4613b17c1e76328bf279998c821a17195fbaab37"
|
|
107
122
|
}
|
package/scripts/test.sh
CHANGED
|
@@ -4,8 +4,8 @@ set -e
|
|
|
4
4
|
if [[ -n $CI ]]
|
|
5
5
|
then
|
|
6
6
|
# --runInBand performs better in ci where resources are limited
|
|
7
|
-
echo "jest --coverage --runInBand --forceExit
|
|
8
|
-
jest --coverage --runInBand --forceExit
|
|
7
|
+
echo "jest --coverage --runInBand --forceExit"
|
|
8
|
+
jest --coverage --runInBand --forceExit
|
|
9
9
|
else
|
|
10
10
|
# --maxWorkers performs better in development
|
|
11
11
|
echo "jest --coverage --maxWorkers=2 --forceExit"
|
|
@@ -55,8 +55,8 @@ async function passportCallback(
|
|
|
55
55
|
export const login = async (ctx: Ctx<LoginRequest>, next: any) => {
|
|
56
56
|
const email = ctx.request.body.username
|
|
57
57
|
|
|
58
|
-
const user = await userSdk.
|
|
59
|
-
if (user && (await userSdk.
|
|
58
|
+
const user = await userSdk.getUserByEmail(email)
|
|
59
|
+
if (user && (await userSdk.isPreventPasswordActions(user))) {
|
|
60
60
|
ctx.throw(403, "Invalid credentials")
|
|
61
61
|
}
|
|
62
62
|
|
|
@@ -174,7 +174,7 @@ export const googlePreAuth = async (ctx: any, next: any) => {
|
|
|
174
174
|
const strategy = await google.strategyFactory(
|
|
175
175
|
config,
|
|
176
176
|
callbackUrl,
|
|
177
|
-
userSdk.
|
|
177
|
+
userSdk.save
|
|
178
178
|
)
|
|
179
179
|
|
|
180
180
|
return passport.authenticate(strategy, {
|
|
@@ -193,7 +193,7 @@ export const googleCallback = async (ctx: any, next: any) => {
|
|
|
193
193
|
const strategy = await google.strategyFactory(
|
|
194
194
|
config,
|
|
195
195
|
callbackUrl,
|
|
196
|
-
userSdk.
|
|
196
|
+
userSdk.save
|
|
197
197
|
)
|
|
198
198
|
|
|
199
199
|
return passport.authenticate(
|
|
@@ -228,7 +228,7 @@ export const oidcStrategyFactory = async (ctx: any, configId: any) => {
|
|
|
228
228
|
|
|
229
229
|
//Remote Config
|
|
230
230
|
const enrichedConfig = await oidc.fetchStrategyConfig(config, callbackUrl)
|
|
231
|
-
return oidc.strategyFactory(enrichedConfig, userSdk.
|
|
231
|
+
return oidc.strategyFactory(enrichedConfig, userSdk.save)
|
|
232
232
|
}
|
|
233
233
|
|
|
234
234
|
/**
|
|
@@ -507,17 +507,17 @@ export async function configChecklist(ctx: Ctx) {
|
|
|
507
507
|
smtp: {
|
|
508
508
|
checked: !!smtpConfig,
|
|
509
509
|
label: "Set up email",
|
|
510
|
-
link: "/builder/portal/
|
|
510
|
+
link: "/builder/portal/manage/email",
|
|
511
511
|
},
|
|
512
512
|
adminUser: {
|
|
513
513
|
checked: userExists,
|
|
514
514
|
label: "Create your first user",
|
|
515
|
-
link: "/builder/portal/
|
|
515
|
+
link: "/builder/portal/manage/users",
|
|
516
516
|
},
|
|
517
517
|
sso: {
|
|
518
518
|
checked: !!googleConfig || !!oidcConfig,
|
|
519
519
|
label: "Set up single sign-on",
|
|
520
|
-
link: "/builder/portal/
|
|
520
|
+
link: "/builder/portal/manage/auth",
|
|
521
521
|
},
|
|
522
522
|
}
|
|
523
523
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { sendEmail as sendEmailFn } from "../../../utilities/email"
|
|
2
2
|
import { tenancy } from "@budibase/backend-core"
|
|
3
|
-
import { BBContext
|
|
3
|
+
import { BBContext } from "@budibase/types"
|
|
4
4
|
|
|
5
5
|
export async function sendEmail(ctx: BBContext) {
|
|
6
6
|
let {
|
|
@@ -16,10 +16,10 @@ export async function sendEmail(ctx: BBContext) {
|
|
|
16
16
|
automation,
|
|
17
17
|
invite,
|
|
18
18
|
} = ctx.request.body
|
|
19
|
-
let user
|
|
19
|
+
let user
|
|
20
20
|
if (userId) {
|
|
21
21
|
const db = tenancy.getGlobalDB()
|
|
22
|
-
user = await db.get
|
|
22
|
+
user = await db.get(userId)
|
|
23
23
|
}
|
|
24
24
|
const response = await sendEmailFn(email, purpose, {
|
|
25
25
|
workspaceId,
|
|
@@ -5,10 +5,10 @@ import {
|
|
|
5
5
|
cache,
|
|
6
6
|
tenancy,
|
|
7
7
|
} from "@budibase/backend-core"
|
|
8
|
-
import
|
|
9
|
-
import {
|
|
8
|
+
import { BBContext, App } from "@budibase/types"
|
|
9
|
+
import { allUsers } from "../../../sdk/users"
|
|
10
10
|
|
|
11
|
-
export async function fetch(ctx:
|
|
11
|
+
export async function fetch(ctx: BBContext) {
|
|
12
12
|
const tenantId = ctx.user!.tenantId
|
|
13
13
|
// always use the dev apps as they'll be most up to date (true)
|
|
14
14
|
const apps = (await dbCore.getAllApps({ tenantId, all: true })) as App[]
|
|
@@ -31,11 +31,11 @@ export async function fetch(ctx: Ctx) {
|
|
|
31
31
|
ctx.body = response
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
export async function find(ctx:
|
|
34
|
+
export async function find(ctx: BBContext) {
|
|
35
35
|
const appId = ctx.params.appId
|
|
36
36
|
await context.doInAppContext(dbCore.getDevAppID(appId), async () => {
|
|
37
37
|
const db = context.getAppDB()
|
|
38
|
-
const app = await db.get
|
|
38
|
+
const app = await db.get(dbCore.DocumentType.APP_METADATA)
|
|
39
39
|
ctx.body = {
|
|
40
40
|
roles: await roles.getAllRoles(),
|
|
41
41
|
name: app.name,
|
|
@@ -45,10 +45,10 @@ export async function find(ctx: Ctx) {
|
|
|
45
45
|
})
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
export async function removeAppRole(ctx:
|
|
48
|
+
export async function removeAppRole(ctx: BBContext) {
|
|
49
49
|
const { appId } = ctx.params
|
|
50
50
|
const db = tenancy.getGlobalDB()
|
|
51
|
-
const users = await
|
|
51
|
+
const users = await allUsers()
|
|
52
52
|
const bulk = []
|
|
53
53
|
const cacheInvalidations = []
|
|
54
54
|
for (let user of users) {
|
|
@@ -44,7 +44,7 @@ export async function generateAPIKey(ctx: any) {
|
|
|
44
44
|
const id = dbCore.generateDevInfoID(userId)
|
|
45
45
|
let devInfo
|
|
46
46
|
try {
|
|
47
|
-
devInfo = await db.get
|
|
47
|
+
devInfo = await db.get(id)
|
|
48
48
|
} catch (err) {
|
|
49
49
|
devInfo = { _id: id, userId }
|
|
50
50
|
}
|
|
@@ -91,7 +91,7 @@ export async function getSelf(ctx: any) {
|
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
// get the main body of the user
|
|
94
|
-
const user = await userSdk.
|
|
94
|
+
const user = await userSdk.getUser(userId)
|
|
95
95
|
ctx.body = await groups.enrichUserRolesFromGroups(user)
|
|
96
96
|
|
|
97
97
|
// add the feature flags for this tenant
|
|
@@ -106,12 +106,12 @@ export async function updateSelf(
|
|
|
106
106
|
) {
|
|
107
107
|
const update = ctx.request.body
|
|
108
108
|
|
|
109
|
-
let user = await userSdk.
|
|
109
|
+
let user = await userSdk.getUser(ctx.user._id!)
|
|
110
110
|
user = {
|
|
111
111
|
...user,
|
|
112
112
|
...update,
|
|
113
113
|
}
|
|
114
|
-
user = await userSdk.
|
|
114
|
+
user = await userSdk.save(user, { requirePassword: false })
|
|
115
115
|
|
|
116
116
|
if (update.password) {
|
|
117
117
|
// Log all other sessions out apart from the current one
|
|
@@ -41,7 +41,7 @@ export const save = async (ctx: UserCtx<User, SaveUserResponse>) => {
|
|
|
41
41
|
const currentUserId = ctx.user?._id
|
|
42
42
|
const requestUser = ctx.request.body
|
|
43
43
|
|
|
44
|
-
const user = await userSdk.
|
|
44
|
+
const user = await userSdk.save(requestUser, { currentUserId })
|
|
45
45
|
|
|
46
46
|
ctx.body = {
|
|
47
47
|
_id: user._id!,
|
|
@@ -57,7 +57,7 @@ const bulkDelete = async (userIds: string[], currentUserId: string) => {
|
|
|
57
57
|
if (userIds?.indexOf(currentUserId) !== -1) {
|
|
58
58
|
throw new Error("Unable to delete self.")
|
|
59
59
|
}
|
|
60
|
-
return await userSdk.
|
|
60
|
+
return await userSdk.bulkDelete(userIds)
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
const bulkCreate = async (users: User[], groupIds: string[]) => {
|
|
@@ -66,7 +66,7 @@ const bulkCreate = async (users: User[], groupIds: string[]) => {
|
|
|
66
66
|
"Max limit for upload is 1000 users. Please reduce file size and try again."
|
|
67
67
|
)
|
|
68
68
|
}
|
|
69
|
-
return await userSdk.
|
|
69
|
+
return await userSdk.bulkCreate(users, groupIds)
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
export const bulkUpdate = async (
|
|
@@ -141,7 +141,7 @@ export const adminUser = async (
|
|
|
141
141
|
// always bust checklist beforehand, if an error occurs but can proceed, don't get
|
|
142
142
|
// stuck in a cycle
|
|
143
143
|
await cache.bustCache(cache.CacheKey.CHECKLIST)
|
|
144
|
-
const finalUser = await userSdk.
|
|
144
|
+
const finalUser = await userSdk.save(user, {
|
|
145
145
|
hashPassword,
|
|
146
146
|
requirePassword,
|
|
147
147
|
})
|
|
@@ -167,7 +167,7 @@ export const adminUser = async (
|
|
|
167
167
|
export const countByApp = async (ctx: any) => {
|
|
168
168
|
const appId = ctx.params.appId
|
|
169
169
|
try {
|
|
170
|
-
ctx.body = await userSdk.
|
|
170
|
+
ctx.body = await userSdk.countUsersByApp(appId)
|
|
171
171
|
} catch (err: any) {
|
|
172
172
|
ctx.throw(err.status || 400, err)
|
|
173
173
|
}
|
|
@@ -179,7 +179,7 @@ export const destroy = async (ctx: any) => {
|
|
|
179
179
|
ctx.throw(400, "Unable to delete self.")
|
|
180
180
|
}
|
|
181
181
|
|
|
182
|
-
await userSdk.
|
|
182
|
+
await userSdk.destroy(id)
|
|
183
183
|
|
|
184
184
|
ctx.body = {
|
|
185
185
|
message: `User ${id} deleted.`,
|
|
@@ -188,7 +188,7 @@ export const destroy = async (ctx: any) => {
|
|
|
188
188
|
|
|
189
189
|
export const getAppUsers = async (ctx: Ctx<SearchUsersRequest>) => {
|
|
190
190
|
const body = ctx.request.body
|
|
191
|
-
const users = await userSdk.
|
|
191
|
+
const users = await userSdk.getUsersByAppAccess(body?.appId)
|
|
192
192
|
|
|
193
193
|
ctx.body = { data: users }
|
|
194
194
|
}
|
|
@@ -212,7 +212,7 @@ export const search = async (ctx: Ctx<SearchUsersRequest>) => {
|
|
|
212
212
|
|
|
213
213
|
// called internally by app server user fetch
|
|
214
214
|
export const fetch = async (ctx: any) => {
|
|
215
|
-
const all = await userSdk.
|
|
215
|
+
const all = await userSdk.allUsers()
|
|
216
216
|
// user hashed password shouldn't ever be returned
|
|
217
217
|
for (let user of all) {
|
|
218
218
|
if (user) {
|
|
@@ -224,12 +224,12 @@ export const fetch = async (ctx: any) => {
|
|
|
224
224
|
|
|
225
225
|
// called internally by app server user find
|
|
226
226
|
export const find = async (ctx: any) => {
|
|
227
|
-
ctx.body = await userSdk.
|
|
227
|
+
ctx.body = await userSdk.getUser(ctx.params.id)
|
|
228
228
|
}
|
|
229
229
|
|
|
230
230
|
export const tenantUserLookup = async (ctx: any) => {
|
|
231
231
|
const id = ctx.params.id
|
|
232
|
-
const user = await userSdk.
|
|
232
|
+
const user = await userSdk.getPlatformUser(id)
|
|
233
233
|
if (user) {
|
|
234
234
|
ctx.body = user
|
|
235
235
|
} else {
|
|
@@ -252,7 +252,7 @@ export const onboardUsers = async (ctx: Ctx<InviteUsersRequest>) => {
|
|
|
252
252
|
// @ts-ignore
|
|
253
253
|
const { users, groups, roles } = request.create
|
|
254
254
|
const assignUsers = users.map((user: User) => (user.roles = roles))
|
|
255
|
-
onboardingResponse = await userSdk.
|
|
255
|
+
onboardingResponse = await userSdk.bulkCreate(assignUsers, groups)
|
|
256
256
|
ctx.body = onboardingResponse
|
|
257
257
|
} else if (emailConfigured) {
|
|
258
258
|
onboardingResponse = await inviteMultiple(ctx)
|
|
@@ -277,7 +277,7 @@ export const onboardUsers = async (ctx: Ctx<InviteUsersRequest>) => {
|
|
|
277
277
|
tenantId: tenancy.getTenantId(),
|
|
278
278
|
}
|
|
279
279
|
})
|
|
280
|
-
let bulkCreateReponse = await userSdk.
|
|
280
|
+
let bulkCreateReponse = await userSdk.bulkCreate(users, [])
|
|
281
281
|
|
|
282
282
|
// Apply temporary credentials
|
|
283
283
|
let createWithCredentials = {
|
|
@@ -410,9 +410,9 @@ export const inviteAccept = async (
|
|
|
410
410
|
...info,
|
|
411
411
|
}
|
|
412
412
|
|
|
413
|
-
const saved = await userSdk.
|
|
413
|
+
const saved = await userSdk.save(request)
|
|
414
414
|
const db = tenancy.getGlobalDB()
|
|
415
|
-
const user = await db.get
|
|
415
|
+
const user = await db.get(saved._id)
|
|
416
416
|
await events.user.inviteAccepted(user)
|
|
417
417
|
return saved
|
|
418
418
|
})
|
|
@@ -41,7 +41,7 @@ describe("/api/global/auth", () => {
|
|
|
41
41
|
|
|
42
42
|
async function createSSOUser() {
|
|
43
43
|
return config.doInTenant(async () => {
|
|
44
|
-
return userSdk.
|
|
44
|
+
return userSdk.save(structures.users.ssoUser(), {
|
|
45
45
|
requirePassword: false,
|
|
46
46
|
})
|
|
47
47
|
})
|
|
@@ -206,7 +206,7 @@ describe("/api/global/auth", () => {
|
|
|
206
206
|
const newPassword = "newpassword"
|
|
207
207
|
const res = await config.api.auth.updatePassword(code!, newPassword)
|
|
208
208
|
|
|
209
|
-
user =
|
|
209
|
+
user = await config.getUser(user.email)
|
|
210
210
|
delete user.password
|
|
211
211
|
|
|
212
212
|
expect(res.body).toEqual({ message: "password reset successfully." })
|
|
@@ -245,7 +245,7 @@ describe("/api/global/auth", () => {
|
|
|
245
245
|
const ssoUser = user as SSOUser
|
|
246
246
|
ssoUser.providerType = structures.sso.providerType()
|
|
247
247
|
delete ssoUser.password
|
|
248
|
-
await config.doInTenant(() => userSdk.
|
|
248
|
+
await config.doInTenant(() => userSdk.save(ssoUser))
|
|
249
249
|
|
|
250
250
|
await testSSOUser(code!)
|
|
251
251
|
})
|
|
@@ -314,7 +314,7 @@ describe("scim", () => {
|
|
|
314
314
|
|
|
315
315
|
const user = await config.getUser(email)
|
|
316
316
|
expect(user).toBeDefined()
|
|
317
|
-
expect(user
|
|
317
|
+
expect(user.email).toEqual(email)
|
|
318
318
|
})
|
|
319
319
|
|
|
320
320
|
it("if multiple emails are provided, the first primary one is used as email", async () => {
|
|
@@ -345,7 +345,7 @@ describe("scim", () => {
|
|
|
345
345
|
|
|
346
346
|
const user = await config.getUser(email)
|
|
347
347
|
expect(user).toBeDefined()
|
|
348
|
-
expect(user
|
|
348
|
+
expect(user.email).toEqual(email)
|
|
349
349
|
})
|
|
350
350
|
|
|
351
351
|
it("if no email is provided and the user name is not an email, an exception is thrown", async () => {
|
|
@@ -36,7 +36,7 @@ describe("/api/global/self", () => {
|
|
|
36
36
|
})
|
|
37
37
|
.expect(200)
|
|
38
38
|
|
|
39
|
-
const dbUser =
|
|
39
|
+
const dbUser = await config.getUser(user.email)
|
|
40
40
|
|
|
41
41
|
user._rev = dbUser._rev
|
|
42
42
|
user.dayPassRecordedAt = mocks.date.MOCK_DATE.toISOString()
|
|
@@ -58,7 +58,7 @@ describe("/api/global/self", () => {
|
|
|
58
58
|
})
|
|
59
59
|
.expect(200)
|
|
60
60
|
|
|
61
|
-
const dbUser =
|
|
61
|
+
const dbUser = await config.getUser(user.email)
|
|
62
62
|
|
|
63
63
|
user._rev = dbUser._rev
|
|
64
64
|
user.dayPassRecordedAt = mocks.date.MOCK_DATE.toISOString()
|
|
@@ -66,7 +66,7 @@ describe("/api/global/users", () => {
|
|
|
66
66
|
expect(res.body._id).toBeDefined()
|
|
67
67
|
const user = await config.getUser(email)
|
|
68
68
|
expect(user).toBeDefined()
|
|
69
|
-
expect(user
|
|
69
|
+
expect(user._id).toEqual(res.body._id)
|
|
70
70
|
expect(events.user.inviteAccepted).toBeCalledTimes(1)
|
|
71
71
|
expect(events.user.inviteAccepted).toBeCalledWith(user)
|
|
72
72
|
})
|
|
@@ -480,7 +480,7 @@ describe("/api/global/users", () => {
|
|
|
480
480
|
function createSSOUser() {
|
|
481
481
|
return config.doInTenant(() => {
|
|
482
482
|
const user = structures.users.ssoUser()
|
|
483
|
-
return userSdk.
|
|
483
|
+
return userSdk.save(user, { requirePassword: false })
|
|
484
484
|
})
|
|
485
485
|
}
|
|
486
486
|
|
package/src/api/routes/index.ts
CHANGED
|
@@ -16,14 +16,10 @@ import licenseRoutes from "./global/license"
|
|
|
16
16
|
import migrationRoutes from "./system/migrations"
|
|
17
17
|
import accountRoutes from "./system/accounts"
|
|
18
18
|
import restoreRoutes from "./system/restore"
|
|
19
|
-
import systemLogRoutes from "./system/logs"
|
|
20
|
-
|
|
21
|
-
import env from "../../environment"
|
|
22
19
|
|
|
23
20
|
export const routes: Router[] = [
|
|
24
21
|
configRoutes,
|
|
25
22
|
userRoutes,
|
|
26
|
-
pro.users,
|
|
27
23
|
workspaceRoutes,
|
|
28
24
|
authRoutes,
|
|
29
25
|
templateRoutes,
|
|
@@ -42,7 +38,3 @@ export const routes: Router[] = [
|
|
|
42
38
|
eventRoutes,
|
|
43
39
|
pro.scim,
|
|
44
40
|
]
|
|
45
|
-
|
|
46
|
-
if (env.SELF_HOSTED) {
|
|
47
|
-
routes.push(systemLogRoutes)
|
|
48
|
-
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { HealthStatusResponse } from "@budibase/types"
|
|
2
1
|
import { TestConfiguration } from "../../../../tests"
|
|
3
2
|
import { accounts as _accounts } from "@budibase/backend-core"
|
|
4
3
|
const accounts = jest.mocked(_accounts)
|
|
@@ -32,15 +31,13 @@ describe("/api/system/status", () => {
|
|
|
32
31
|
})
|
|
33
32
|
|
|
34
33
|
it("returns status in cloud", async () => {
|
|
35
|
-
const value
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
login: false,
|
|
39
|
-
search: false,
|
|
34
|
+
const value = {
|
|
35
|
+
health: {
|
|
36
|
+
passing: false,
|
|
40
37
|
},
|
|
41
38
|
}
|
|
42
39
|
|
|
43
|
-
accounts.getStatus.
|
|
40
|
+
accounts.getStatus.mockReturnValueOnce(Promise.resolve(value))
|
|
44
41
|
|
|
45
42
|
const res = await config.api.status.getStatus()
|
|
46
43
|
|
package/src/environment.ts
CHANGED
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
import { ServiceType } from "@budibase/types"
|
|
3
|
-
import { join } from "path"
|
|
4
|
-
|
|
5
|
-
coreEnv._set("SERVICE_TYPE", ServiceType.WORKER)
|
|
1
|
+
const { join } = require("path")
|
|
6
2
|
|
|
7
3
|
function isDev() {
|
|
8
4
|
return process.env.NODE_ENV !== "production"
|
package/src/initPro.ts
CHANGED
|
@@ -2,5 +2,12 @@ import { sdk as proSdk } from "@budibase/pro"
|
|
|
2
2
|
import * as userSdk from "./sdk/users"
|
|
3
3
|
|
|
4
4
|
export const initPro = async () => {
|
|
5
|
-
await proSdk.init({
|
|
5
|
+
await proSdk.init({
|
|
6
|
+
scimUserServiceConfig: {
|
|
7
|
+
functions: {
|
|
8
|
+
saveUser: userSdk.save,
|
|
9
|
+
removeUser: (id: string) => userSdk.destroy(id),
|
|
10
|
+
},
|
|
11
|
+
},
|
|
12
|
+
})
|
|
6
13
|
}
|
|
@@ -10,7 +10,7 @@ import { platform } from "@budibase/backend-core"
|
|
|
10
10
|
* Re-sync the global-db users to the global-info db users
|
|
11
11
|
*/
|
|
12
12
|
export const run = async (globalDb: any) => {
|
|
13
|
-
const users = (await usersSdk.
|
|
13
|
+
const users = (await usersSdk.allUsers()) as User[]
|
|
14
14
|
const promises = []
|
|
15
15
|
for (let user of users) {
|
|
16
16
|
promises.push(
|
package/src/sdk/auth/auth.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
auth as authCore,
|
|
3
|
-
env as coreEnv,
|
|
4
|
-
events,
|
|
5
|
-
HTTPError,
|
|
6
|
-
sessions,
|
|
7
3
|
tenancy,
|
|
8
4
|
utils as coreUtils,
|
|
5
|
+
sessions,
|
|
6
|
+
events,
|
|
7
|
+
HTTPError,
|
|
8
|
+
env as coreEnv,
|
|
9
9
|
} from "@budibase/backend-core"
|
|
10
10
|
import { PlatformLogoutOpts, User } from "@budibase/types"
|
|
11
11
|
import jwt from "jsonwebtoken"
|
|
@@ -20,7 +20,7 @@ export async function loginUser(user: User) {
|
|
|
20
20
|
const sessionId = coreUtils.newid()
|
|
21
21
|
const tenantId = tenancy.getTenantId()
|
|
22
22
|
await sessions.createASession(user._id!, { sessionId, tenantId })
|
|
23
|
-
|
|
23
|
+
const token = jwt.sign(
|
|
24
24
|
{
|
|
25
25
|
userId: user._id,
|
|
26
26
|
sessionId,
|
|
@@ -28,6 +28,7 @@ export async function loginUser(user: User) {
|
|
|
28
28
|
},
|
|
29
29
|
coreEnv.JWT_SECRET!
|
|
30
30
|
)
|
|
31
|
+
return token
|
|
31
32
|
}
|
|
32
33
|
|
|
33
34
|
export async function logout(opts: PlatformLogoutOpts) {
|
|
@@ -57,7 +58,7 @@ export const reset = async (email: string) => {
|
|
|
57
58
|
}
|
|
58
59
|
|
|
59
60
|
// exit if user has sso
|
|
60
|
-
if (await userSdk.
|
|
61
|
+
if (await userSdk.isPreventPasswordActions(user)) {
|
|
61
62
|
return
|
|
62
63
|
}
|
|
63
64
|
|
|
@@ -75,9 +76,9 @@ export const reset = async (email: string) => {
|
|
|
75
76
|
export const resetUpdate = async (resetCode: string, password: string) => {
|
|
76
77
|
const { userId } = await redis.checkResetPasswordCode(resetCode)
|
|
77
78
|
|
|
78
|
-
let user = await userSdk.
|
|
79
|
+
let user = await userSdk.getUser(userId)
|
|
79
80
|
user.password = password
|
|
80
|
-
user = await userSdk.
|
|
81
|
+
user = await userSdk.save(user)
|
|
81
82
|
|
|
82
83
|
// remove password from the user before sending events
|
|
83
84
|
delete user.password
|