@budibase/worker 2.3.18-alpha.9 → 2.3.18
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/coverage/clover.xml +2199 -0
- package/coverage/coverage-final.json +84 -0
- package/coverage/lcov-report/base.css +224 -0
- package/coverage/lcov-report/block-navigation.js +87 -0
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +431 -0
- package/coverage/lcov-report/prettify.css +1 -0
- package/coverage/lcov-report/prettify.js +2 -0
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +196 -0
- package/coverage/lcov-report/src/api/controllers/global/auth.ts.html +934 -0
- package/coverage/lcov-report/src/api/controllers/global/configs.ts.html +1348 -0
- package/coverage/lcov-report/src/api/controllers/global/email.ts.html +196 -0
- package/coverage/lcov-report/src/api/controllers/global/events.ts.html +136 -0
- package/coverage/lcov-report/src/api/controllers/global/index.html +251 -0
- package/coverage/lcov-report/src/api/controllers/global/license.ts.html +187 -0
- package/coverage/lcov-report/src/api/controllers/global/roles.ts.html +283 -0
- package/coverage/lcov-report/src/api/controllers/global/self.ts.html +577 -0
- package/coverage/lcov-report/src/api/controllers/global/templates.ts.html +316 -0
- package/coverage/lcov-report/src/api/controllers/global/users.ts.html +838 -0
- package/coverage/lcov-report/src/api/controllers/global/workspaces.ts.html +244 -0
- package/coverage/lcov-report/src/api/controllers/system/accounts.ts.html +148 -0
- package/coverage/lcov-report/src/api/controllers/system/environment.ts.html +124 -0
- package/coverage/lcov-report/src/api/controllers/system/index.html +191 -0
- package/coverage/lcov-report/src/api/controllers/system/migrations.ts.html +124 -0
- package/coverage/lcov-report/src/api/controllers/system/restore.ts.html +124 -0
- package/coverage/lcov-report/src/api/controllers/system/status.ts.html +133 -0
- package/coverage/lcov-report/src/api/controllers/system/tenants.ts.html +154 -0
- package/coverage/lcov-report/src/api/index.html +116 -0
- package/coverage/lcov-report/src/api/index.ts.html +595 -0
- package/coverage/lcov-report/src/api/routes/global/auth.ts.html +349 -0
- package/coverage/lcov-report/src/api/routes/global/configs.ts.html +457 -0
- package/coverage/lcov-report/src/api/routes/global/email.ts.html +193 -0
- package/coverage/lcov-report/src/api/routes/global/events.ts.html +109 -0
- package/coverage/lcov-report/src/api/routes/global/index.html +251 -0
- package/coverage/lcov-report/src/api/routes/global/license.ts.html +124 -0
- package/coverage/lcov-report/src/api/routes/global/roles.ts.html +133 -0
- package/coverage/lcov-report/src/api/routes/global/self.ts.html +139 -0
- package/coverage/lcov-report/src/api/routes/global/templates.ts.html +196 -0
- package/coverage/lcov-report/src/api/routes/global/users.ts.html +475 -0
- package/coverage/lcov-report/src/api/routes/global/workspaces.ts.html +196 -0
- package/coverage/lcov-report/src/api/routes/index.html +116 -0
- package/coverage/lcov-report/src/api/routes/index.ts.html +202 -0
- package/coverage/lcov-report/src/api/routes/system/accounts.ts.html +142 -0
- package/coverage/lcov-report/src/api/routes/system/environment.ts.html +109 -0
- package/coverage/lcov-report/src/api/routes/system/index.html +191 -0
- package/coverage/lcov-report/src/api/routes/system/migrations.ts.html +142 -0
- package/coverage/lcov-report/src/api/routes/system/restore.ts.html +109 -0
- package/coverage/lcov-report/src/api/routes/system/status.ts.html +109 -0
- package/coverage/lcov-report/src/api/routes/system/tenants.ts.html +124 -0
- package/coverage/lcov-report/src/api/routes/validation/index.html +131 -0
- package/coverage/lcov-report/src/api/routes/validation/index.ts.html +88 -0
- package/coverage/lcov-report/src/api/routes/validation/users.ts.html +235 -0
- package/coverage/lcov-report/src/constants/index.html +116 -0
- package/coverage/lcov-report/src/constants/index.ts.html +637 -0
- package/coverage/lcov-report/src/constants/templates/index.html +116 -0
- package/coverage/lcov-report/src/constants/templates/index.ts.html +316 -0
- package/coverage/lcov-report/src/db/index.html +116 -0
- package/coverage/lcov-report/src/db/index.ts.html +115 -0
- package/coverage/lcov-report/src/environment.ts.html +388 -0
- package/coverage/lcov-report/src/index.html +131 -0
- package/coverage/lcov-report/src/index.ts.html +394 -0
- package/coverage/lcov-report/src/middleware/cloudRestricted.ts.html +139 -0
- package/coverage/lcov-report/src/middleware/index.html +116 -0
- package/coverage/lcov-report/src/migrations/functions/globalInfoSyncUsers.ts.html +145 -0
- package/coverage/lcov-report/src/migrations/functions/index.html +116 -0
- package/coverage/lcov-report/src/migrations/index.html +116 -0
- package/coverage/lcov-report/src/migrations/index.ts.html +271 -0
- package/coverage/lcov-report/src/sdk/accounts/accounts.ts.html +262 -0
- package/coverage/lcov-report/src/sdk/accounts/index.html +131 -0
- package/coverage/lcov-report/src/sdk/accounts/index.ts.html +88 -0
- package/coverage/lcov-report/src/sdk/index.html +116 -0
- package/coverage/lcov-report/src/sdk/index.ts.html +106 -0
- package/coverage/lcov-report/src/sdk/users/events.ts.html +601 -0
- package/coverage/lcov-report/src/sdk/users/index.html +146 -0
- package/coverage/lcov-report/src/sdk/users/index.ts.html +88 -0
- package/coverage/lcov-report/src/sdk/users/users.ts.html +1999 -0
- package/coverage/lcov-report/src/tests/TestConfiguration.ts.html +1075 -0
- package/coverage/lcov-report/src/tests/api/accounts.ts.html +160 -0
- package/coverage/lcov-report/src/tests/api/auth.ts.html +220 -0
- package/coverage/lcov-report/src/tests/api/base.ts.html +133 -0
- package/coverage/lcov-report/src/tests/api/configs.ts.html +226 -0
- package/coverage/lcov-report/src/tests/api/email.ts.html +148 -0
- package/coverage/lcov-report/src/tests/api/environment.ts.html +130 -0
- package/coverage/lcov-report/src/tests/api/groups.ts.html +163 -0
- package/coverage/lcov-report/src/tests/api/index.html +356 -0
- package/coverage/lcov-report/src/tests/api/index.ts.html +238 -0
- package/coverage/lcov-report/src/tests/api/license.ts.html +136 -0
- package/coverage/lcov-report/src/tests/api/migrations.ts.html +151 -0
- package/coverage/lcov-report/src/tests/api/restore.ts.html +127 -0
- package/coverage/lcov-report/src/tests/api/roles.ts.html +181 -0
- package/coverage/lcov-report/src/tests/api/self.ts.html +163 -0
- package/coverage/lcov-report/src/tests/api/status.ts.html +121 -0
- package/coverage/lcov-report/src/tests/api/templates.ts.html +175 -0
- package/coverage/lcov-report/src/tests/api/tenants.ts.html +130 -0
- package/coverage/lcov-report/src/tests/api/users.ts.html +514 -0
- package/coverage/lcov-report/src/tests/controllers.ts.html +100 -0
- package/coverage/lcov-report/src/tests/index.html +146 -0
- package/coverage/lcov-report/src/tests/index.ts.html +103 -0
- package/coverage/lcov-report/src/tests/mocks/email.ts.html +115 -0
- package/coverage/lcov-report/src/tests/mocks/index.html +131 -0
- package/coverage/lcov-report/src/tests/mocks/index.ts.html +106 -0
- package/coverage/lcov-report/src/tests/structures/configs.ts.html +313 -0
- package/coverage/lcov-report/src/tests/structures/groups.ts.html +118 -0
- package/coverage/lcov-report/src/tests/structures/index.html +161 -0
- package/coverage/lcov-report/src/tests/structures/index.ts.html +151 -0
- package/coverage/lcov-report/src/tests/structures/users.ts.html +196 -0
- package/coverage/lcov-report/src/utilities/appService.ts.html +208 -0
- package/coverage/lcov-report/src/utilities/email.ts.html +850 -0
- package/coverage/lcov-report/src/utilities/fileSystem.ts.html +100 -0
- package/coverage/lcov-report/src/utilities/index.html +206 -0
- package/coverage/lcov-report/src/utilities/index.ts.html +112 -0
- package/coverage/lcov-report/src/utilities/redis.ts.html +424 -0
- package/coverage/lcov-report/src/utilities/templates.ts.html +232 -0
- package/coverage/lcov-report/src/utilities/users.ts.html +133 -0
- package/coverage/lcov.info +4187 -0
- package/jest.config.ts +17 -13
- package/package.json +8 -11
- package/scripts/dev/manage.js +0 -1
- package/src/api/controllers/global/auth.ts +70 -77
- package/src/api/controllers/global/self.ts +44 -28
- package/src/api/controllers/global/users.ts +25 -65
- package/src/api/controllers/system/accounts.ts +5 -7
- package/src/api/controllers/system/tenants.ts +8 -4
- package/src/api/index.ts +20 -4
- package/src/api/routes/global/auth.ts +7 -10
- package/src/api/routes/global/tests/auth.spec.ts +17 -226
- package/src/api/routes/global/tests/configs.spec.ts +5 -5
- package/src/api/routes/global/tests/roles.spec.ts +14 -20
- package/src/api/routes/global/tests/self.spec.ts +4 -3
- package/src/api/routes/global/tests/users.spec.ts +27 -24
- package/src/api/routes/system/tenants.ts +1 -1
- package/src/api/routes/system/tests/accounts.spec.ts +4 -4
- package/src/api/routes/system/tests/migrations.spec.ts +2 -2
- package/src/api/routes/system/tests/restore.spec.ts +2 -2
- package/src/api/routes/system/tests/status.spec.ts +5 -5
- package/src/environment.ts +1 -15
- package/src/index.ts +7 -12
- package/src/middleware/tests/tenancy.spec.ts +4 -4
- package/src/migrations/functions/globalInfoSyncUsers.ts +3 -4
- package/src/sdk/accounts/{metadata.ts → accounts.ts} +1 -0
- package/src/sdk/accounts/index.ts +1 -2
- package/src/sdk/users/events.ts +0 -4
- package/src/sdk/users/index.ts +0 -1
- package/src/sdk/users/users.ts +46 -53
- package/src/tests/TestConfiguration.ts +62 -41
- package/src/tests/api/auth.ts +14 -42
- package/src/tests/api/base.ts +1 -2
- package/src/tests/api/configs.ts +2 -2
- package/src/tests/api/restore.ts +0 -1
- package/src/tests/api/users.ts +2 -2
- package/src/tests/jestEnv.ts +1 -2
- package/src/tests/jestSetup.ts +6 -10
- package/src/tests/structures/index.ts +4 -0
- package/src/tests/structures/users.ts +37 -0
- package/src/utilities/email.ts +3 -3
- package/src/utilities/redis.ts +0 -2
- package/__mocks__/node-fetch.ts +0 -23
- package/jest-testcontainers-config.js +0 -8
- package/scripts/test.sh +0 -12
- package/src/ddApm.ts +0 -7
- package/src/elasticApm.ts +0 -10
- package/src/sdk/auth/auth.ts +0 -86
- package/src/sdk/auth/index.ts +0 -1
- package/src/sdk/tenants/index.ts +0 -1
- package/src/sdk/tenants/tenants.ts +0 -76
- package/src/sdk/users/tests/users.spec.ts +0 -52
- package/src/tests/logging.ts +0 -34
package/jest.config.ts
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import { Config } from "@jest/types"
|
|
2
2
|
import * as fs from "fs"
|
|
3
|
-
const preset = require("ts-jest/jest-preset")
|
|
4
3
|
|
|
5
4
|
const config: Config.InitialOptions = {
|
|
6
|
-
|
|
7
|
-
preset: "@trendyol/jest-testcontainers",
|
|
5
|
+
testEnvironment: "node",
|
|
8
6
|
setupFiles: ["./src/tests/jestEnv.ts"],
|
|
9
7
|
setupFilesAfterEnv: ["./src/tests/jestSetup.ts"],
|
|
10
8
|
collectCoverageFrom: ["src/**/*.{js,ts}"],
|
|
@@ -12,19 +10,25 @@ const config: Config.InitialOptions = {
|
|
|
12
10
|
transform: {
|
|
13
11
|
"^.+\\.ts?$": "@swc/jest",
|
|
14
12
|
},
|
|
15
|
-
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
if (!process.env.CI) {
|
|
16
|
+
// use sources when not in CI
|
|
17
|
+
config.moduleNameMapper = {
|
|
16
18
|
"@budibase/backend-core/(.*)": "<rootDir>/../backend-core/$1",
|
|
17
19
|
"@budibase/backend-core": "<rootDir>/../backend-core/src",
|
|
18
20
|
"@budibase/types": "<rootDir>/../types/src",
|
|
19
|
-
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
"
|
|
26
|
-
|
|
27
|
-
|
|
21
|
+
"^axios.*$": "<rootDir>/node_modules/axios/lib/axios.js",
|
|
22
|
+
}
|
|
23
|
+
// add pro sources if they exist
|
|
24
|
+
if (fs.existsSync("../../../budibase-pro")) {
|
|
25
|
+
config.moduleNameMapper["@budibase/pro/(.*)"] =
|
|
26
|
+
"<rootDir>/../../../budibase-pro/packages/pro/$1"
|
|
27
|
+
config.moduleNameMapper["@budibase/pro"] =
|
|
28
|
+
"<rootDir>/../../../budibase-pro/packages/pro/src"
|
|
29
|
+
}
|
|
30
|
+
} else {
|
|
31
|
+
console.log("Running tests with compiled dependency sources")
|
|
28
32
|
}
|
|
29
33
|
|
|
30
34
|
export default config
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@budibase/worker",
|
|
3
3
|
"email": "hi@budibase.com",
|
|
4
|
-
"version": "2.3.18
|
|
4
|
+
"version": "2.3.18",
|
|
5
5
|
"description": "Budibase background service",
|
|
6
6
|
"main": "src/index.ts",
|
|
7
7
|
"repository": {
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"build:docker": "docker build . -t worker-service --label version=$BUDIBASE_RELEASE_VERSION",
|
|
23
23
|
"dev:stack:init": "node ./scripts/dev/manage.js init",
|
|
24
24
|
"dev:builder": "npm run dev:stack:init && nodemon",
|
|
25
|
-
"test": "
|
|
25
|
+
"test": "jest --coverage --maxWorkers=2",
|
|
26
26
|
"test:watch": "jest --watch",
|
|
27
27
|
"env:multi:enable": "node scripts/multiTenancy.js enable",
|
|
28
28
|
"env:multi:disable": "node scripts/multiTenancy.js disable",
|
|
@@ -36,17 +36,16 @@
|
|
|
36
36
|
"author": "Budibase",
|
|
37
37
|
"license": "GPL-3.0",
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@budibase/backend-core": "2.3.18
|
|
40
|
-
"@budibase/pro": "2.3.
|
|
41
|
-
"@budibase/string-templates": "2.3.18
|
|
42
|
-
"@budibase/types": "2.3.18
|
|
39
|
+
"@budibase/backend-core": "^2.3.18",
|
|
40
|
+
"@budibase/pro": "2.3.17",
|
|
41
|
+
"@budibase/string-templates": "^2.3.18",
|
|
42
|
+
"@budibase/types": "^2.3.18",
|
|
43
43
|
"@koa/router": "8.0.8",
|
|
44
44
|
"@sentry/node": "6.17.7",
|
|
45
45
|
"@techpass/passport-openidconnect": "0.3.2",
|
|
46
46
|
"@types/global-agent": "2.1.1",
|
|
47
47
|
"aws-sdk": "2.1030.0",
|
|
48
48
|
"bcryptjs": "2.4.3",
|
|
49
|
-
"dd-trace": "3.13.2",
|
|
50
49
|
"dotenv": "8.6.0",
|
|
51
50
|
"elastic-apm-node": "3.38.0",
|
|
52
51
|
"global-agent": "3.0.0",
|
|
@@ -73,8 +72,7 @@
|
|
|
73
72
|
"devDependencies": {
|
|
74
73
|
"@swc/core": "^1.3.25",
|
|
75
74
|
"@swc/jest": "^0.2.24",
|
|
76
|
-
"@
|
|
77
|
-
"@types/jest": "28.1.1",
|
|
75
|
+
"@types/jest": "26.0.23",
|
|
78
76
|
"@types/jsonwebtoken": "8.5.1",
|
|
79
77
|
"@types/koa": "2.13.4",
|
|
80
78
|
"@types/koa__router": "8.0.8",
|
|
@@ -82,7 +80,6 @@
|
|
|
82
80
|
"@types/node-fetch": "2.6.1",
|
|
83
81
|
"@types/pouchdb": "6.4.0",
|
|
84
82
|
"@types/server-destroy": "1.0.1",
|
|
85
|
-
"@types/supertest": "2.0.12",
|
|
86
83
|
"@types/uuid": "8.3.4",
|
|
87
84
|
"@typescript-eslint/parser": "5.45.0",
|
|
88
85
|
"copyfiles": "2.4.1",
|
|
@@ -100,5 +97,5 @@
|
|
|
100
97
|
"typescript": "4.7.3",
|
|
101
98
|
"update-dotenv": "1.1.1"
|
|
102
99
|
},
|
|
103
|
-
"gitHead": "
|
|
100
|
+
"gitHead": "7a59ee813fc92b82f415225421ff10e5f53a6b81"
|
|
104
101
|
}
|
package/scripts/dev/manage.js
CHANGED
|
@@ -29,7 +29,6 @@ async function init() {
|
|
|
29
29
|
SERVICE: "worker-service",
|
|
30
30
|
DEPLOYMENT_ENVIRONMENT: "development",
|
|
31
31
|
TENANT_FEATURE_FLAGS: "*:LICENSING,*:USER_GROUPS,*:ONBOARDING_TOUR",
|
|
32
|
-
ENABLE_EMAIL_TEST_MODE: 1,
|
|
33
32
|
}
|
|
34
33
|
let envFile = ""
|
|
35
34
|
Object.keys(envFileJson).forEach(key => {
|
|
@@ -1,55 +1,49 @@
|
|
|
1
1
|
import {
|
|
2
|
-
auth
|
|
2
|
+
auth,
|
|
3
3
|
constants,
|
|
4
4
|
context,
|
|
5
5
|
db as dbCore,
|
|
6
6
|
events,
|
|
7
7
|
tenancy,
|
|
8
|
-
|
|
8
|
+
users as usersCore,
|
|
9
|
+
utils,
|
|
9
10
|
} from "@budibase/backend-core"
|
|
10
|
-
import {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
Ctx,
|
|
14
|
-
LoginRequest,
|
|
15
|
-
SSOUser,
|
|
16
|
-
PasswordResetRequest,
|
|
17
|
-
PasswordResetUpdateRequest,
|
|
18
|
-
} from "@budibase/types"
|
|
11
|
+
import { EmailTemplatePurpose } from "../../../constants"
|
|
12
|
+
import { isEmailConfigured, sendEmail } from "../../../utilities/email"
|
|
13
|
+
import { checkResetPasswordCode } from "../../../utilities/redis"
|
|
19
14
|
import env from "../../../environment"
|
|
15
|
+
import sdk from "../../../sdk"
|
|
16
|
+
import { ConfigType, User } from "@budibase/types"
|
|
20
17
|
|
|
21
|
-
|
|
22
|
-
import * as userSdk from "../../../sdk/users"
|
|
23
|
-
|
|
18
|
+
const { setCookie, getCookie, clearCookie, hash, platformLogout } = utils
|
|
24
19
|
const { Cookie, Header } = constants
|
|
25
|
-
const { passport, ssoCallbackUrl, google, oidc } =
|
|
26
|
-
|
|
20
|
+
const { passport, ssoCallbackUrl, google, oidc } = auth
|
|
21
|
+
|
|
22
|
+
export async function googleCallbackUrl(config?: { callbackURL?: string }) {
|
|
23
|
+
return ssoCallbackUrl(tenancy.getGlobalDB(), config, ConfigType.GOOGLE)
|
|
24
|
+
}
|
|
27
25
|
|
|
28
|
-
|
|
26
|
+
export async function oidcCallbackUrl(config?: { callbackURL?: string }) {
|
|
27
|
+
return ssoCallbackUrl(tenancy.getGlobalDB(), config, ConfigType.OIDC)
|
|
28
|
+
}
|
|
29
29
|
|
|
30
|
-
async function
|
|
31
|
-
ctx: Ctx,
|
|
32
|
-
user: User,
|
|
33
|
-
err: any = null,
|
|
34
|
-
info: { message: string } | null = null
|
|
35
|
-
) {
|
|
30
|
+
async function authInternal(ctx: any, user: any, err: any = null, info = null) {
|
|
36
31
|
if (err) {
|
|
37
32
|
console.error("Authentication error")
|
|
38
33
|
console.error(err)
|
|
39
34
|
console.trace(err)
|
|
40
35
|
return ctx.throw(403, info ? info : "Unauthorized")
|
|
41
36
|
}
|
|
37
|
+
|
|
42
38
|
if (!user) {
|
|
43
39
|
console.error("Authentication error - no user provided")
|
|
44
40
|
return ctx.throw(403, info ? info : "Unauthorized")
|
|
45
41
|
}
|
|
46
42
|
|
|
47
|
-
const token = await authSdk.loginUser(user)
|
|
48
|
-
|
|
49
43
|
// set a cookie for browser access
|
|
50
|
-
setCookie(ctx, token, Cookie.Auth, { sign: false })
|
|
44
|
+
setCookie(ctx, user.token, Cookie.Auth, { sign: false })
|
|
51
45
|
// set the token in a header as well for APIs
|
|
52
|
-
ctx.set(Header.TOKEN, token)
|
|
46
|
+
ctx.set(Header.TOKEN, user.token)
|
|
53
47
|
// get rid of any app cookies on login
|
|
54
48
|
// have to check test because this breaks cypress
|
|
55
49
|
if (!env.isTest()) {
|
|
@@ -57,18 +51,11 @@ async function passportCallback(
|
|
|
57
51
|
}
|
|
58
52
|
}
|
|
59
53
|
|
|
60
|
-
export const
|
|
61
|
-
const email = ctx.request.body.username
|
|
62
|
-
|
|
63
|
-
const user = await userSdk.getUserByEmail(email)
|
|
64
|
-
if (user && (await userSdk.isPreventSSOPasswords(user))) {
|
|
65
|
-
ctx.throw(400, "SSO user cannot login using password")
|
|
66
|
-
}
|
|
67
|
-
|
|
54
|
+
export const authenticate = async (ctx: any, next: any) => {
|
|
68
55
|
return passport.authenticate(
|
|
69
56
|
"local",
|
|
70
57
|
async (err: any, user: User, info: any) => {
|
|
71
|
-
await
|
|
58
|
+
await authInternal(ctx, user, err, info)
|
|
72
59
|
await context.identity.doInUserContext(user, async () => {
|
|
73
60
|
await events.auth.login("local")
|
|
74
61
|
})
|
|
@@ -77,15 +64,6 @@ export const login = async (ctx: Ctx<LoginRequest>, next: any) => {
|
|
|
77
64
|
)(ctx, next)
|
|
78
65
|
}
|
|
79
66
|
|
|
80
|
-
export const logout = async (ctx: any) => {
|
|
81
|
-
if (ctx.user && ctx.user._id) {
|
|
82
|
-
await authSdk.logout({ ctx, userId: ctx.user._id })
|
|
83
|
-
}
|
|
84
|
-
ctx.body = { message: "User logged out." }
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// INIT
|
|
88
|
-
|
|
89
67
|
export const setInitInfo = (ctx: any) => {
|
|
90
68
|
const initInfo = ctx.request.body
|
|
91
69
|
setCookie(ctx, initInfo, Cookie.Init)
|
|
@@ -101,16 +79,32 @@ export const getInitInfo = (ctx: any) => {
|
|
|
101
79
|
}
|
|
102
80
|
}
|
|
103
81
|
|
|
104
|
-
// PASSWORD MANAGEMENT
|
|
105
|
-
|
|
106
82
|
/**
|
|
107
83
|
* Reset the user password, used as part of a forgotten password flow.
|
|
108
84
|
*/
|
|
109
|
-
export const reset = async (ctx:
|
|
85
|
+
export const reset = async (ctx: any) => {
|
|
110
86
|
const { email } = ctx.request.body
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
87
|
+
const configured = await isEmailConfigured()
|
|
88
|
+
if (!configured) {
|
|
89
|
+
ctx.throw(
|
|
90
|
+
400,
|
|
91
|
+
"Please contact your platform administrator, SMTP is not configured."
|
|
92
|
+
)
|
|
93
|
+
}
|
|
94
|
+
try {
|
|
95
|
+
const user = (await usersCore.getGlobalUserByEmail(email)) as User
|
|
96
|
+
// only if user exists, don't error though if they don't
|
|
97
|
+
if (user) {
|
|
98
|
+
await sendEmail(email, EmailTemplatePurpose.PASSWORD_RECOVERY, {
|
|
99
|
+
user,
|
|
100
|
+
subject: "{{ company }} platform password reset",
|
|
101
|
+
})
|
|
102
|
+
await events.user.passwordResetRequested(user)
|
|
103
|
+
}
|
|
104
|
+
} catch (err) {
|
|
105
|
+
console.log(err)
|
|
106
|
+
// don't throw any kind of error to the user, this might give away something
|
|
107
|
+
}
|
|
114
108
|
ctx.body = {
|
|
115
109
|
message: "Please check your email for a reset link.",
|
|
116
110
|
}
|
|
@@ -119,21 +113,32 @@ export const reset = async (ctx: Ctx<PasswordResetRequest>) => {
|
|
|
119
113
|
/**
|
|
120
114
|
* Perform the user password update if the provided reset code is valid.
|
|
121
115
|
*/
|
|
122
|
-
export const resetUpdate = async (ctx:
|
|
116
|
+
export const resetUpdate = async (ctx: any) => {
|
|
123
117
|
const { resetCode, password } = ctx.request.body
|
|
124
118
|
try {
|
|
125
|
-
await
|
|
119
|
+
const { userId } = await checkResetPasswordCode(resetCode)
|
|
120
|
+
const db = tenancy.getGlobalDB()
|
|
121
|
+
const user = await db.get(userId)
|
|
122
|
+
user.password = await hash(password)
|
|
123
|
+
await db.put(user)
|
|
126
124
|
ctx.body = {
|
|
127
125
|
message: "password reset successfully.",
|
|
128
126
|
}
|
|
127
|
+
// remove password from the user before sending events
|
|
128
|
+
delete user.password
|
|
129
|
+
await events.user.passwordReset(user)
|
|
129
130
|
} catch (err) {
|
|
130
|
-
console.
|
|
131
|
-
// hide any details of the error for security
|
|
131
|
+
console.error(err)
|
|
132
132
|
ctx.throw(400, "Cannot reset password.")
|
|
133
133
|
}
|
|
134
134
|
}
|
|
135
135
|
|
|
136
|
-
|
|
136
|
+
export const logout = async (ctx: any) => {
|
|
137
|
+
if (ctx.user && ctx.user._id) {
|
|
138
|
+
await platformLogout({ ctx, userId: ctx.user._id })
|
|
139
|
+
}
|
|
140
|
+
ctx.body = { message: "User logged out." }
|
|
141
|
+
}
|
|
137
142
|
|
|
138
143
|
export const datasourcePreAuth = async (ctx: any, next: any) => {
|
|
139
144
|
const provider = ctx.params.provider
|
|
@@ -161,12 +166,6 @@ export const datasourceAuth = async (ctx: any, next: any) => {
|
|
|
161
166
|
return handler.postAuth(passport, ctx, next)
|
|
162
167
|
}
|
|
163
168
|
|
|
164
|
-
// GOOGLE SSO
|
|
165
|
-
|
|
166
|
-
export async function googleCallbackUrl(config?: { callbackURL?: string }) {
|
|
167
|
-
return ssoCallbackUrl(tenancy.getGlobalDB(), config, ConfigType.GOOGLE)
|
|
168
|
-
}
|
|
169
|
-
|
|
170
169
|
/**
|
|
171
170
|
* The initial call that google authentication makes to take you to the google login screen.
|
|
172
171
|
* On a successful login, you will be redirected to the googleAuth callback route.
|
|
@@ -182,7 +181,7 @@ export const googlePreAuth = async (ctx: any, next: any) => {
|
|
|
182
181
|
const strategy = await google.strategyFactory(
|
|
183
182
|
config,
|
|
184
183
|
callbackUrl,
|
|
185
|
-
|
|
184
|
+
sdk.users.save
|
|
186
185
|
)
|
|
187
186
|
|
|
188
187
|
return passport.authenticate(strategy, {
|
|
@@ -192,7 +191,7 @@ export const googlePreAuth = async (ctx: any, next: any) => {
|
|
|
192
191
|
})(ctx, next)
|
|
193
192
|
}
|
|
194
193
|
|
|
195
|
-
export const
|
|
194
|
+
export const googleAuth = async (ctx: any, next: any) => {
|
|
196
195
|
const db = tenancy.getGlobalDB()
|
|
197
196
|
|
|
198
197
|
const config = await dbCore.getScopedConfig(db, {
|
|
@@ -203,14 +202,14 @@ export const googleCallback = async (ctx: any, next: any) => {
|
|
|
203
202
|
const strategy = await google.strategyFactory(
|
|
204
203
|
config,
|
|
205
204
|
callbackUrl,
|
|
206
|
-
|
|
205
|
+
sdk.users.save
|
|
207
206
|
)
|
|
208
207
|
|
|
209
208
|
return passport.authenticate(
|
|
210
209
|
strategy,
|
|
211
210
|
{ successRedirect: "/", failureRedirect: "/error" },
|
|
212
|
-
async (err: any, user:
|
|
213
|
-
await
|
|
211
|
+
async (err: any, user: User, info: any) => {
|
|
212
|
+
await authInternal(ctx, user, err, info)
|
|
214
213
|
await context.identity.doInUserContext(user, async () => {
|
|
215
214
|
await events.auth.login("google-internal")
|
|
216
215
|
})
|
|
@@ -219,12 +218,6 @@ export const googleCallback = async (ctx: any, next: any) => {
|
|
|
219
218
|
)(ctx, next)
|
|
220
219
|
}
|
|
221
220
|
|
|
222
|
-
// OIDC SSO
|
|
223
|
-
|
|
224
|
-
export async function oidcCallbackUrl(config?: { callbackURL?: string }) {
|
|
225
|
-
return ssoCallbackUrl(tenancy.getGlobalDB(), config, ConfigType.OIDC)
|
|
226
|
-
}
|
|
227
|
-
|
|
228
221
|
export const oidcStrategyFactory = async (ctx: any, configId: any) => {
|
|
229
222
|
const db = tenancy.getGlobalDB()
|
|
230
223
|
const config = await dbCore.getScopedConfig(db, {
|
|
@@ -240,7 +233,7 @@ export const oidcStrategyFactory = async (ctx: any, configId: any) => {
|
|
|
240
233
|
chosenConfig,
|
|
241
234
|
callbackUrl
|
|
242
235
|
)
|
|
243
|
-
return oidc.strategyFactory(enrichedConfig,
|
|
236
|
+
return oidc.strategyFactory(enrichedConfig, sdk.users.save)
|
|
244
237
|
}
|
|
245
238
|
|
|
246
239
|
/**
|
|
@@ -272,15 +265,15 @@ export const oidcPreAuth = async (ctx: any, next: any) => {
|
|
|
272
265
|
})(ctx, next)
|
|
273
266
|
}
|
|
274
267
|
|
|
275
|
-
export const
|
|
268
|
+
export const oidcAuth = async (ctx: any, next: any) => {
|
|
276
269
|
const configId = getCookie(ctx, Cookie.OIDC_CONFIG)
|
|
277
270
|
const strategy = await oidcStrategyFactory(ctx, configId)
|
|
278
271
|
|
|
279
272
|
return passport.authenticate(
|
|
280
273
|
strategy,
|
|
281
274
|
{ successRedirect: "/", failureRedirect: "/error" },
|
|
282
|
-
async (err: any, user:
|
|
283
|
-
await
|
|
275
|
+
async (err: any, user: any, info: any) => {
|
|
276
|
+
await authInternal(ctx, user, err, info)
|
|
284
277
|
await context.identity.doInUserContext(user, async () => {
|
|
285
278
|
await events.auth.login("oidc")
|
|
286
279
|
})
|
|
@@ -1,22 +1,18 @@
|
|
|
1
|
-
import
|
|
1
|
+
import sdk from "../../../sdk"
|
|
2
2
|
import {
|
|
3
|
+
events,
|
|
3
4
|
featureFlags,
|
|
4
5
|
tenancy,
|
|
5
6
|
constants,
|
|
6
7
|
db as dbCore,
|
|
7
8
|
utils,
|
|
9
|
+
cache,
|
|
8
10
|
encryption,
|
|
9
|
-
auth as authCore,
|
|
10
11
|
} from "@budibase/backend-core"
|
|
11
12
|
import env from "../../../environment"
|
|
12
13
|
import { groups } from "@budibase/pro"
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
UpdateSelfResponse,
|
|
16
|
-
UpdateSelf,
|
|
17
|
-
UserCtx,
|
|
18
|
-
} from "@budibase/types"
|
|
19
|
-
const { getCookie, clearCookie, newid } = utils
|
|
14
|
+
const { hash, platformLogout, getCookie, clearCookie, newid } = utils
|
|
15
|
+
const { user: userCache } = cache
|
|
20
16
|
|
|
21
17
|
function newTestApiKey() {
|
|
22
18
|
return env.ENCRYPTED_TEST_PUBLIC_API_KEY
|
|
@@ -97,6 +93,17 @@ const addSessionAttributesToUser = (ctx: any) => {
|
|
|
97
93
|
ctx.body.csrfToken = ctx.user.csrfToken
|
|
98
94
|
}
|
|
99
95
|
|
|
96
|
+
const sanitiseUserUpdate = (ctx: any) => {
|
|
97
|
+
const allowed = ["firstName", "lastName", "password", "forceResetPassword"]
|
|
98
|
+
const resp: { [key: string]: any } = {}
|
|
99
|
+
for (let [key, value] of Object.entries(ctx.request.body)) {
|
|
100
|
+
if (allowed.includes(key)) {
|
|
101
|
+
resp[key] = value
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return resp
|
|
105
|
+
}
|
|
106
|
+
|
|
100
107
|
export async function getSelf(ctx: any) {
|
|
101
108
|
if (!ctx.user) {
|
|
102
109
|
ctx.throw(403, "User not logged in")
|
|
@@ -109,7 +116,7 @@ export async function getSelf(ctx: any) {
|
|
|
109
116
|
checkCurrentApp(ctx)
|
|
110
117
|
|
|
111
118
|
// get the main body of the user
|
|
112
|
-
const user = await
|
|
119
|
+
const user = await sdk.users.getUser(userId)
|
|
113
120
|
ctx.body = await groups.enrichUserRolesFromGroups(user)
|
|
114
121
|
|
|
115
122
|
// add the feature flags for this tenant
|
|
@@ -119,30 +126,39 @@ export async function getSelf(ctx: any) {
|
|
|
119
126
|
addSessionAttributesToUser(ctx)
|
|
120
127
|
}
|
|
121
128
|
|
|
122
|
-
export async function updateSelf(
|
|
123
|
-
|
|
124
|
-
)
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
const user = await userSdk.updateSelf(ctx.user._id!, update)
|
|
134
|
-
|
|
135
|
-
if (update.password) {
|
|
129
|
+
export async function updateSelf(ctx: any) {
|
|
130
|
+
const db = tenancy.getGlobalDB()
|
|
131
|
+
const user = await db.get(ctx.user._id)
|
|
132
|
+
let passwordChange = false
|
|
133
|
+
|
|
134
|
+
const userUpdateObj = sanitiseUserUpdate(ctx)
|
|
135
|
+
if (userUpdateObj.password) {
|
|
136
|
+
// changing password
|
|
137
|
+
passwordChange = true
|
|
138
|
+
userUpdateObj.password = await hash(userUpdateObj.password)
|
|
136
139
|
// Log all other sessions out apart from the current one
|
|
137
|
-
await
|
|
140
|
+
await platformLogout({
|
|
138
141
|
ctx,
|
|
139
|
-
userId: ctx.user._id
|
|
142
|
+
userId: ctx.user._id,
|
|
140
143
|
keepActiveSession: true,
|
|
141
144
|
})
|
|
142
145
|
}
|
|
143
146
|
|
|
147
|
+
const response = await db.put({
|
|
148
|
+
...user,
|
|
149
|
+
...userUpdateObj,
|
|
150
|
+
})
|
|
151
|
+
await userCache.invalidateUser(user._id)
|
|
144
152
|
ctx.body = {
|
|
145
|
-
_id:
|
|
146
|
-
_rev:
|
|
153
|
+
_id: response.id,
|
|
154
|
+
_rev: response.rev,
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// remove the old password from the user before sending events
|
|
158
|
+
user._rev = response.rev
|
|
159
|
+
delete user.password
|
|
160
|
+
await events.user.updated(user)
|
|
161
|
+
if (passwordChange) {
|
|
162
|
+
await events.user.passwordUpdated(user)
|
|
147
163
|
}
|
|
148
164
|
}
|