@budibase/backend-core 3.2.4 → 3.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js.map +1 -1
- package/dist/index.js.meta.json +1 -1
- package/dist/package.json +11 -4
- package/dist/plugins.js.meta.json +1 -1
- package/package.json +11 -4
- 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 -210
- 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 -150
- package/src/cache/docWritethrough.ts +0 -105
- package/src/cache/generic.ts +0 -33
- package/src/cache/index.ts +0 -8
- package/src/cache/invite.ts +0 -86
- package/src/cache/passwordReset.ts +0 -49
- package/src/cache/tests/docWritethrough.spec.ts +0 -296
- package/src/cache/tests/user.spec.ts +0 -145
- package/src/cache/tests/writethrough.spec.ts +0 -139
- package/src/cache/user.ts +0 -154
- package/src/cache/writethrough.ts +0 -133
- package/src/configs/configs.ts +0 -263
- package/src/configs/index.ts +0 -1
- package/src/configs/tests/configs.spec.ts +0 -184
- package/src/constants/db.ts +0 -75
- package/src/constants/index.ts +0 -2
- package/src/constants/misc.ts +0 -36
- 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 -422
- package/src/context/tests/index.spec.ts +0 -255
- package/src/context/types.ts +0 -26
- package/src/db/Replication.ts +0 -94
- package/src/db/couch/DatabaseImpl.ts +0 -511
- package/src/db/couch/connections.ts +0 -89
- package/src/db/couch/index.ts +0 -4
- package/src/db/couch/pouchDB.ts +0 -97
- package/src/db/couch/pouchDump.ts +0 -0
- package/src/db/couch/tests/DatabaseImpl.spec.ts +0 -118
- package/src/db/couch/utils.ts +0 -55
- package/src/db/db.ts +0 -34
- package/src/db/errors.ts +0 -14
- package/src/db/index.ts +0 -12
- package/src/db/instrumentation.ts +0 -199
- package/src/db/lucene.ts +0 -721
- package/src/db/searchIndexes/index.ts +0 -1
- package/src/db/searchIndexes/searchIndexes.ts +0 -62
- package/src/db/tests/DatabaseImpl.spec.ts +0 -55
- package/src/db/tests/connections.spec.ts +0 -22
- package/src/db/tests/index.spec.ts +0 -32
- package/src/db/tests/lucene.spec.ts +0 -400
- package/src/db/tests/pouch.spec.js +0 -62
- package/src/db/tests/utils.spec.ts +0 -63
- package/src/db/utils.ts +0 -208
- package/src/db/views.ts +0 -245
- package/src/docIds/conversions.ts +0 -60
- package/src/docIds/ids.ts +0 -126
- package/src/docIds/index.ts +0 -2
- package/src/docIds/newid.ts +0 -5
- package/src/docIds/params.ts +0 -189
- package/src/docUpdates/index.ts +0 -24
- package/src/environment.ts +0 -293
- 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 -47
- package/src/events/identification.ts +0 -311
- package/src/events/index.ts +0 -15
- package/src/events/processors/AnalyticsProcessor.ts +0 -64
- package/src/events/processors/AuditLogsProcessor.ts +0 -92
- package/src/events/processors/LoggingProcessor.ts +0 -36
- package/src/events/processors/Processors.ts +0 -52
- package/src/events/processors/async/DocumentUpdateProcessor.ts +0 -38
- 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 -3
- package/src/events/processors/posthog/rateLimiting.ts +0 -106
- package/src/events/processors/posthog/tests/PosthogProcessor.spec.ts +0 -164
- package/src/events/processors/types.ts +0 -1
- package/src/events/publishers/account.ts +0 -41
- package/src/events/publishers/ai.ts +0 -21
- package/src/events/publishers/app.ts +0 -168
- 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 -25
- 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 -89
- 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/features/features.ts +0 -277
- package/src/features/index.ts +0 -2
- package/src/features/tests/features.spec.ts +0 -267
- package/src/features/tests/utils.ts +0 -64
- package/src/helpers.ts +0 -9
- package/src/index.ts +0 -59
- package/src/installation.ts +0 -115
- package/src/logging/alerts.ts +0 -26
- package/src/logging/correlation/correlation.ts +0 -15
- package/src/logging/correlation/index.ts +0 -1
- package/src/logging/correlation/middleware.ts +0 -18
- package/src/logging/index.ts +0 -4
- package/src/logging/pino/logger.ts +0 -239
- package/src/logging/pino/middleware.ts +0 -48
- 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 -247
- package/src/middleware/builderOnly.ts +0 -21
- package/src/middleware/builderOrAdmin.ts +0 -21
- package/src/middleware/contentSecurityPolicy.ts +0 -113
- package/src/middleware/csrf.ts +0 -81
- package/src/middleware/errorHandling.ts +0 -43
- package/src/middleware/index.ts +0 -24
- package/src/middleware/internalApi.ts +0 -23
- package/src/middleware/ip.ts +0 -12
- package/src/middleware/joi-validator.ts +0 -58
- package/src/middleware/matchers.ts +0 -39
- package/src/middleware/passport/datasource/google.ts +0 -102
- 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 -152
- package/src/middleware/passport/sso/sso.ts +0 -138
- package/src/middleware/passport/sso/tests/google.spec.ts +0 -68
- package/src/middleware/passport/sso/tests/oidc.spec.ts +0 -144
- 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 -181
- package/src/middleware/tests/contentSecurityPolicy.spec.ts +0 -75
- package/src/middleware/tests/matchers.spec.ts +0 -100
- package/src/migrations/definitions.ts +0 -40
- package/src/migrations/index.ts +0 -2
- package/src/migrations/migrations.ts +0 -186
- 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 -53
- 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 -161
- 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 -585
- package/src/objectStore/utils.ts +0 -113
- 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 -129
- package/src/plugin/index.ts +0 -1
- package/src/plugin/tests/validation.spec.ts +0 -209
- package/src/plugin/utils.ts +0 -175
- package/src/queue/constants.ts +0 -8
- package/src/queue/inMemoryQueue.ts +0 -189
- package/src/queue/index.ts +0 -2
- package/src/queue/listeners.ts +0 -199
- package/src/queue/queue.ts +0 -84
- package/src/redis/index.ts +0 -6
- package/src/redis/init.ts +0 -118
- package/src/redis/redis.ts +0 -358
- package/src/redis/redlockImpl.ts +0 -155
- package/src/redis/tests/redis.spec.ts +0 -207
- package/src/redis/tests/redlockImpl.spec.ts +0 -105
- package/src/redis/utils.ts +0 -128
- package/src/security/auth.ts +0 -24
- package/src/security/encryption.ts +0 -185
- package/src/security/index.ts +0 -1
- package/src/security/permissions.ts +0 -166
- package/src/security/roles.ts +0 -655
- package/src/security/secrets.ts +0 -20
- package/src/security/sessions.ts +0 -123
- package/src/security/tests/auth.spec.ts +0 -45
- package/src/security/tests/encryption.spec.ts +0 -31
- package/src/security/tests/permissions.spec.ts +0 -146
- package/src/security/tests/secrets.spec.ts +0 -35
- package/src/security/tests/sessions.spec.ts +0 -12
- package/src/sql/designDoc.ts +0 -17
- package/src/sql/index.ts +0 -5
- package/src/sql/sql.ts +0 -1854
- package/src/sql/sqlTable.ts +0 -319
- package/src/sql/utils.ts +0 -193
- package/src/tenancy/db.ts +0 -6
- package/src/tenancy/index.ts +0 -2
- package/src/tenancy/tenancy.ts +0 -148
- 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 -582
- package/src/users/events.ts +0 -176
- package/src/users/index.ts +0 -4
- package/src/users/lookup.ts +0 -99
- package/src/users/test/db.spec.ts +0 -188
- package/src/users/test/utils.spec.ts +0 -67
- package/src/users/users.ts +0 -353
- package/src/users/utils.ts +0 -81
- package/src/utils/Duration.ts +0 -56
- package/src/utils/hashing.ts +0 -15
- package/src/utils/index.ts +0 -4
- package/src/utils/stringUtils.ts +0 -8
- package/src/utils/tests/Duration.spec.ts +0 -19
- package/src/utils/tests/utils.spec.ts +0 -204
- package/src/utils/utils.ts +0 -249
- package/tests/core/logging.ts +0 -34
- package/tests/core/users/users.spec.js +0 -53
- package/tests/core/utilities/index.ts +0 -7
- package/tests/core/utilities/jestUtils.ts +0 -33
- package/tests/core/utilities/mocks/alerts.ts +0 -4
- package/tests/core/utilities/mocks/date.ts +0 -3
- package/tests/core/utilities/mocks/events.ts +0 -132
- package/tests/core/utilities/mocks/index.ts +0 -9
- package/tests/core/utilities/mocks/licenses.ts +0 -119
- package/tests/core/utilities/queue.ts +0 -9
- package/tests/core/utilities/structures/Chance.ts +0 -20
- package/tests/core/utilities/structures/accounts.ts +0 -80
- 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 -3
- 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 -190
- package/tests/core/utilities/structures/plugins.ts +0 -19
- package/tests/core/utilities/structures/quotas.ts +0 -72
- package/tests/core/utilities/structures/scim.ts +0 -80
- package/tests/core/utilities/structures/sso.ts +0 -118
- 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 -89
- package/tests/core/utilities/testContainerUtils.ts +0 -165
- package/tests/core/utilities/utils/index.ts +0 -2
- package/tests/core/utilities/utils/queue.ts +0 -27
- 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 -2
- package/tests/jestEnv.ts +0 -10
- package/tests/jestSetup.ts +0 -36
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { UserCtx } from "@budibase/types"
|
|
2
|
-
import { isBuilder, hasBuilderPermissions } from "../users"
|
|
3
|
-
import { getAppId } from "../context"
|
|
4
|
-
import env from "../environment"
|
|
5
|
-
|
|
6
|
-
export default async (ctx: UserCtx, next: any) => {
|
|
7
|
-
const appId = getAppId()
|
|
8
|
-
const builderFn =
|
|
9
|
-
env.isWorker() || !appId
|
|
10
|
-
? hasBuilderPermissions
|
|
11
|
-
: env.isApps()
|
|
12
|
-
? isBuilder
|
|
13
|
-
: undefined
|
|
14
|
-
if (!builderFn) {
|
|
15
|
-
throw new Error("Service name unknown - middleware inactive.")
|
|
16
|
-
}
|
|
17
|
-
if (!ctx.internal && !builderFn(ctx.user, appId)) {
|
|
18
|
-
ctx.throw(403, "Builder user only endpoint.")
|
|
19
|
-
}
|
|
20
|
-
return next()
|
|
21
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { UserCtx } from "@budibase/types"
|
|
2
|
-
import { isBuilder, isAdmin, hasBuilderPermissions } from "../users"
|
|
3
|
-
import { getAppId } from "../context"
|
|
4
|
-
import env from "../environment"
|
|
5
|
-
|
|
6
|
-
export default async (ctx: UserCtx, next: any) => {
|
|
7
|
-
const appId = getAppId()
|
|
8
|
-
const builderFn =
|
|
9
|
-
env.isWorker() || !appId
|
|
10
|
-
? hasBuilderPermissions
|
|
11
|
-
: env.isApps()
|
|
12
|
-
? isBuilder
|
|
13
|
-
: undefined
|
|
14
|
-
if (!builderFn) {
|
|
15
|
-
throw new Error("Service name unknown - middleware inactive.")
|
|
16
|
-
}
|
|
17
|
-
if (!ctx.internal && !builderFn(ctx.user, appId) && !isAdmin(ctx.user)) {
|
|
18
|
-
ctx.throw(403, "Admin/Builder user only endpoint.")
|
|
19
|
-
}
|
|
20
|
-
return next()
|
|
21
|
-
}
|
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
import crypto from "crypto"
|
|
2
|
-
|
|
3
|
-
const CSP_DIRECTIVES = {
|
|
4
|
-
"default-src": ["'self'"],
|
|
5
|
-
"script-src": [
|
|
6
|
-
"'self'",
|
|
7
|
-
"'unsafe-eval'",
|
|
8
|
-
"https://*.budibase.net",
|
|
9
|
-
"https://cdn.budi.live",
|
|
10
|
-
"https://js.intercomcdn.com",
|
|
11
|
-
"https://widget.intercom.io",
|
|
12
|
-
"https://d2l5prqdbvm3op.cloudfront.net",
|
|
13
|
-
"https://us-assets.i.posthog.com",
|
|
14
|
-
],
|
|
15
|
-
"style-src": [
|
|
16
|
-
"'self'",
|
|
17
|
-
"'unsafe-inline'",
|
|
18
|
-
"https://cdn.jsdelivr.net",
|
|
19
|
-
"https://fonts.googleapis.com",
|
|
20
|
-
"https://rsms.me",
|
|
21
|
-
"https://maxcdn.bootstrapcdn.com",
|
|
22
|
-
],
|
|
23
|
-
"object-src": ["'none'"],
|
|
24
|
-
"base-uri": ["'self'"],
|
|
25
|
-
"connect-src": [
|
|
26
|
-
"'self'",
|
|
27
|
-
"https://*.budibase.app",
|
|
28
|
-
"https://*.budibaseqa.app",
|
|
29
|
-
"https://*.budibase.net",
|
|
30
|
-
"https://api-iam.intercom.io",
|
|
31
|
-
"https://api-ping.intercom.io",
|
|
32
|
-
"https://app.posthog.com",
|
|
33
|
-
"https://us.i.posthog.com",
|
|
34
|
-
"wss://nexus-websocket-a.intercom.io",
|
|
35
|
-
"wss://nexus-websocket-b.intercom.io",
|
|
36
|
-
"https://nexus-websocket-a.intercom.io",
|
|
37
|
-
"https://nexus-websocket-b.intercom.io",
|
|
38
|
-
"https://uploads.intercomcdn.com",
|
|
39
|
-
"https://uploads.intercomusercontent.com",
|
|
40
|
-
"https://*.amazonaws.com",
|
|
41
|
-
"https://*.s3.amazonaws.com",
|
|
42
|
-
"https://*.s3.us-east-2.amazonaws.com",
|
|
43
|
-
"https://*.s3.us-east-1.amazonaws.com",
|
|
44
|
-
"https://*.s3.us-west-1.amazonaws.com",
|
|
45
|
-
"https://*.s3.us-west-2.amazonaws.com",
|
|
46
|
-
"https://*.s3.af-south-1.amazonaws.com",
|
|
47
|
-
"https://*.s3.ap-east-1.amazonaws.com",
|
|
48
|
-
"https://*.s3.ap-south-1.amazonaws.com",
|
|
49
|
-
"https://*.s3.ap-northeast-2.amazonaws.com",
|
|
50
|
-
"https://*.s3.ap-southeast-1.amazonaws.com",
|
|
51
|
-
"https://*.s3.ap-southeast-2.amazonaws.com",
|
|
52
|
-
"https://*.s3.ap-northeast-1.amazonaws.com",
|
|
53
|
-
"https://*.s3.ca-central-1.amazonaws.com",
|
|
54
|
-
"https://*.s3.cn-north-1.amazonaws.com",
|
|
55
|
-
"https://*.s3.cn-northwest-1.amazonaws.com",
|
|
56
|
-
"https://*.s3.eu-central-1.amazonaws.com",
|
|
57
|
-
"https://*.s3.eu-west-1.amazonaws.com",
|
|
58
|
-
"https://*.s3.eu-west-2.amazonaws.com",
|
|
59
|
-
"https://*.s3.eu-south-1.amazonaws.com",
|
|
60
|
-
"https://*.s3.eu-west-3.amazonaws.com",
|
|
61
|
-
"https://*.s3.eu-north-1.amazonaws.com",
|
|
62
|
-
"https://*.s3.sa-east-1.amazonaws.com",
|
|
63
|
-
"https://*.s3.me-south-1.amazonaws.com",
|
|
64
|
-
"https://*.s3.us-gov-east-1.amazonaws.com",
|
|
65
|
-
"https://*.s3.us-gov-west-1.amazonaws.com",
|
|
66
|
-
"https://api.github.com",
|
|
67
|
-
],
|
|
68
|
-
"font-src": [
|
|
69
|
-
"'self'",
|
|
70
|
-
"data:",
|
|
71
|
-
"https://cdn.jsdelivr.net",
|
|
72
|
-
"https://fonts.gstatic.com",
|
|
73
|
-
"https://rsms.me",
|
|
74
|
-
"https://maxcdn.bootstrapcdn.com",
|
|
75
|
-
"https://js.intercomcdn.com",
|
|
76
|
-
"https://fonts.intercomcdn.com",
|
|
77
|
-
],
|
|
78
|
-
"frame-src": ["'self'", "https:"],
|
|
79
|
-
"img-src": ["http:", "https:", "data:", "blob:"],
|
|
80
|
-
"manifest-src": ["'self'"],
|
|
81
|
-
"media-src": [
|
|
82
|
-
"'self'",
|
|
83
|
-
"https://js.intercomcdn.com",
|
|
84
|
-
"https://cdn.budi.live",
|
|
85
|
-
],
|
|
86
|
-
"worker-src": ["blob:"],
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
export async function contentSecurityPolicy(ctx: any, next: any) {
|
|
90
|
-
try {
|
|
91
|
-
const nonce = crypto.randomBytes(16).toString("base64")
|
|
92
|
-
|
|
93
|
-
const directives = { ...CSP_DIRECTIVES }
|
|
94
|
-
directives["script-src"] = [
|
|
95
|
-
...CSP_DIRECTIVES["script-src"],
|
|
96
|
-
`'nonce-${nonce}'`,
|
|
97
|
-
]
|
|
98
|
-
|
|
99
|
-
ctx.state.nonce = nonce
|
|
100
|
-
|
|
101
|
-
const cspHeader = Object.entries(directives)
|
|
102
|
-
.map(([key, sources]) => `${key} ${sources.join(" ")}`)
|
|
103
|
-
.join("; ")
|
|
104
|
-
ctx.set("Content-Security-Policy", cspHeader)
|
|
105
|
-
await next()
|
|
106
|
-
} catch (err: any) {
|
|
107
|
-
console.error(
|
|
108
|
-
`Error occurred in Content-Security-Policy middleware: ${err}`
|
|
109
|
-
)
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
export default contentSecurityPolicy
|
package/src/middleware/csrf.ts
DELETED
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import { Header } from "../constants"
|
|
2
|
-
import { buildMatcherRegex, matches } from "./matchers"
|
|
3
|
-
import { BBContext, EndpointMatcher } from "@budibase/types"
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* GET, HEAD and OPTIONS methods are considered safe operations
|
|
7
|
-
*
|
|
8
|
-
* POST, PUT, PATCH, and DELETE methods, being state changing verbs,
|
|
9
|
-
* should have a CSRF token attached to the request
|
|
10
|
-
*/
|
|
11
|
-
const EXCLUDED_METHODS = ["GET", "HEAD", "OPTIONS"]
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* There are only three content type values that can be used in cross domain requests.
|
|
15
|
-
* If any other value is used, e.g. application/json, the browser will first make a OPTIONS
|
|
16
|
-
* request which will be protected by CORS.
|
|
17
|
-
*/
|
|
18
|
-
const INCLUDED_CONTENT_TYPES = [
|
|
19
|
-
"application/x-www-form-urlencoded",
|
|
20
|
-
"multipart/form-data",
|
|
21
|
-
"text/plain",
|
|
22
|
-
]
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Validate the CSRF token generated aganst the user session.
|
|
26
|
-
* Compare the token with the x-csrf-token header.
|
|
27
|
-
*
|
|
28
|
-
* If the token is not found within the request or the value provided
|
|
29
|
-
* does not match the value within the user session, the request is rejected.
|
|
30
|
-
*
|
|
31
|
-
* CSRF protection provided using the 'Synchronizer Token Pattern'
|
|
32
|
-
* https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html#synchronizer-token-pattern
|
|
33
|
-
*
|
|
34
|
-
*/
|
|
35
|
-
export default function (
|
|
36
|
-
opts: { noCsrfPatterns: EndpointMatcher[] } = { noCsrfPatterns: [] }
|
|
37
|
-
) {
|
|
38
|
-
const noCsrfOptions = buildMatcherRegex(opts.noCsrfPatterns)
|
|
39
|
-
return async (ctx: BBContext | any, next: any) => {
|
|
40
|
-
// don't apply for excluded paths
|
|
41
|
-
const found = matches(ctx, noCsrfOptions)
|
|
42
|
-
if (found) {
|
|
43
|
-
return next()
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// don't apply for the excluded http methods
|
|
47
|
-
if (EXCLUDED_METHODS.indexOf(ctx.method) !== -1) {
|
|
48
|
-
return next()
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
// don't apply when the content type isn't supported
|
|
52
|
-
let contentType = ctx.get("content-type")
|
|
53
|
-
? ctx.get("content-type").toLowerCase()
|
|
54
|
-
: ""
|
|
55
|
-
if (
|
|
56
|
-
!INCLUDED_CONTENT_TYPES.filter(type => contentType.includes(type)).length
|
|
57
|
-
) {
|
|
58
|
-
return next()
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
// don't apply csrf when the internal api key has been used
|
|
62
|
-
if (ctx.internal) {
|
|
63
|
-
return next()
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// apply csrf when there is a token in the session (new logins)
|
|
67
|
-
// in future there should be a hard requirement that the token is present
|
|
68
|
-
const userToken = ctx.user?.csrfToken
|
|
69
|
-
if (!userToken) {
|
|
70
|
-
return next()
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
// reject if no token in request or mismatch
|
|
74
|
-
const requestToken = ctx.get(Header.CSRF_TOKEN)
|
|
75
|
-
if (!requestToken || requestToken !== userToken) {
|
|
76
|
-
ctx.throw(403, "Invalid CSRF token")
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
return next()
|
|
80
|
-
}
|
|
81
|
-
}
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { APIError } from "@budibase/types"
|
|
2
|
-
import * as errors from "../errors"
|
|
3
|
-
import environment from "../environment"
|
|
4
|
-
import { stringContainsSecret } from "../security/secrets"
|
|
5
|
-
|
|
6
|
-
export async function errorHandling(ctx: any, next: any) {
|
|
7
|
-
try {
|
|
8
|
-
await next()
|
|
9
|
-
} catch (err: any) {
|
|
10
|
-
const status = err.status || err.statusCode || 500
|
|
11
|
-
ctx.status = status
|
|
12
|
-
|
|
13
|
-
if (status >= 400 && status < 500) {
|
|
14
|
-
console.warn(err)
|
|
15
|
-
} else {
|
|
16
|
-
console.error("Got 400 response code", err)
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
let error: APIError = {
|
|
20
|
-
message: err.message,
|
|
21
|
-
status,
|
|
22
|
-
validationErrors: err.validation,
|
|
23
|
-
error: errors.getPublicError(err),
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
if (stringContainsSecret(JSON.stringify(error))) {
|
|
27
|
-
error = {
|
|
28
|
-
message: "Unexpected error",
|
|
29
|
-
status,
|
|
30
|
-
error: "Unexpected error",
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
if (environment.isTest() && ctx.headers["x-budibase-include-stacktrace"]) {
|
|
35
|
-
// @ts-ignore
|
|
36
|
-
error.stack = err.stack
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
ctx.body = error
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export default errorHandling
|
package/src/middleware/index.ts
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
export * as local from "./passport/local"
|
|
2
|
-
export * as google from "./passport/sso/google"
|
|
3
|
-
export * as oidc from "./passport/sso/oidc"
|
|
4
|
-
import * as datasourceGoogle from "./passport/datasource/google"
|
|
5
|
-
|
|
6
|
-
export const datasource = {
|
|
7
|
-
google: datasourceGoogle,
|
|
8
|
-
}
|
|
9
|
-
export { authError, ssoCallbackUrl } from "./passport/utils"
|
|
10
|
-
export { default as authenticated } from "./authenticated"
|
|
11
|
-
export { default as auditLog } from "./auditLog"
|
|
12
|
-
export { default as tenancy } from "./tenancy"
|
|
13
|
-
export { default as internalApi } from "./internalApi"
|
|
14
|
-
export { default as csrf } from "./csrf"
|
|
15
|
-
export { default as adminOnly } from "./adminOnly"
|
|
16
|
-
export { default as builderOrAdmin } from "./builderOrAdmin"
|
|
17
|
-
export { default as builderOnly } from "./builderOnly"
|
|
18
|
-
export { default as pino } from "../logging/pino/middleware"
|
|
19
|
-
export { default as correlation } from "../logging/correlation/middleware"
|
|
20
|
-
export { default as errorHandling } from "./errorHandling"
|
|
21
|
-
export { default as querystringToBody } from "./querystringToBody"
|
|
22
|
-
export { default as csp } from "./contentSecurityPolicy"
|
|
23
|
-
export * as joiValidator from "./joi-validator"
|
|
24
|
-
export { default as ip } from "./ip"
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { Header } from "../constants"
|
|
2
|
-
import { BBContext } from "@budibase/types"
|
|
3
|
-
import { isValidInternalAPIKey } from "../utils"
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* API Key only endpoint.
|
|
7
|
-
*/
|
|
8
|
-
export default async (ctx: BBContext, next: any) => {
|
|
9
|
-
const apiKey = ctx.request.headers[Header.API_KEY]
|
|
10
|
-
if (!apiKey) {
|
|
11
|
-
ctx.throw(403, "Unauthorized")
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
if (Array.isArray(apiKey)) {
|
|
15
|
-
ctx.throw(403, "Unauthorized")
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
if (!isValidInternalAPIKey(apiKey)) {
|
|
19
|
-
ctx.throw(403, "Unauthorized")
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
return next()
|
|
23
|
-
}
|
package/src/middleware/ip.ts
DELETED
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import Joi from "joi"
|
|
2
|
-
import { Ctx } from "@budibase/types"
|
|
3
|
-
|
|
4
|
-
function validate(
|
|
5
|
-
schema: Joi.ObjectSchema | Joi.ArraySchema,
|
|
6
|
-
property: string,
|
|
7
|
-
opts?: { errorPrefix?: string; allowUnknown?: boolean }
|
|
8
|
-
) {
|
|
9
|
-
const errorPrefix = opts?.errorPrefix ?? `Invalid ${property}`
|
|
10
|
-
// Return a Koa middleware function
|
|
11
|
-
return (ctx: Ctx, next: any) => {
|
|
12
|
-
if (!schema) {
|
|
13
|
-
return next()
|
|
14
|
-
}
|
|
15
|
-
let params = null
|
|
16
|
-
// @ts-ignore
|
|
17
|
-
let reqProp = ctx.request?.[property]
|
|
18
|
-
if (ctx[property] != null) {
|
|
19
|
-
params = ctx[property]
|
|
20
|
-
} else if (reqProp != null) {
|
|
21
|
-
params = reqProp
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
// not all schemas have the append property e.g. array schemas
|
|
25
|
-
if ((schema as Joi.ObjectSchema).append) {
|
|
26
|
-
schema = (schema as Joi.ObjectSchema).append({
|
|
27
|
-
createdAt: Joi.any().optional(),
|
|
28
|
-
updatedAt: Joi.any().optional(),
|
|
29
|
-
})
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
const { error } = schema.validate(params, {
|
|
33
|
-
allowUnknown: opts?.allowUnknown,
|
|
34
|
-
})
|
|
35
|
-
if (error) {
|
|
36
|
-
let message = error.message
|
|
37
|
-
if (errorPrefix) {
|
|
38
|
-
message = `Invalid ${property} - ${message}`
|
|
39
|
-
}
|
|
40
|
-
ctx.throw(400, message)
|
|
41
|
-
}
|
|
42
|
-
return next()
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export function body(
|
|
47
|
-
schema: Joi.ObjectSchema | Joi.ArraySchema,
|
|
48
|
-
opts?: { errorPrefix?: string; allowUnknown?: boolean }
|
|
49
|
-
) {
|
|
50
|
-
return validate(schema, "body", opts)
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
export function params(
|
|
54
|
-
schema: Joi.ObjectSchema | Joi.ArraySchema,
|
|
55
|
-
opts?: { errorPrefix: string }
|
|
56
|
-
) {
|
|
57
|
-
return validate(schema, "params", opts)
|
|
58
|
-
}
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { BBContext, EndpointMatcher, RegexMatcher } from "@budibase/types"
|
|
2
|
-
|
|
3
|
-
const PARAM_REGEX = /\/:(.*?)(\/.*)?$/g
|
|
4
|
-
|
|
5
|
-
export const buildMatcherRegex = (
|
|
6
|
-
patterns: EndpointMatcher[]
|
|
7
|
-
): RegexMatcher[] => {
|
|
8
|
-
if (!patterns) {
|
|
9
|
-
return []
|
|
10
|
-
}
|
|
11
|
-
return patterns.map(pattern => {
|
|
12
|
-
let route = pattern.route
|
|
13
|
-
const method = pattern.method
|
|
14
|
-
|
|
15
|
-
// if there is a param in the route
|
|
16
|
-
// use a wildcard pattern
|
|
17
|
-
const matches = route.match(PARAM_REGEX)
|
|
18
|
-
if (matches) {
|
|
19
|
-
for (let match of matches) {
|
|
20
|
-
const suffix = match.endsWith("/") ? "/" : ""
|
|
21
|
-
const pattern = "/.*" + suffix
|
|
22
|
-
route = route.replace(match, pattern)
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
return { regex: new RegExp(route), method, route }
|
|
27
|
-
})
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export const matches = (ctx: BBContext, options: RegexMatcher[]) => {
|
|
31
|
-
return options.find(({ regex, method }) => {
|
|
32
|
-
const urlMatch = regex.test(ctx.request.url)
|
|
33
|
-
const methodMatch =
|
|
34
|
-
method === "ALL"
|
|
35
|
-
? true
|
|
36
|
-
: ctx.request.method.toLowerCase() === method.toLowerCase()
|
|
37
|
-
return urlMatch && methodMatch
|
|
38
|
-
})
|
|
39
|
-
}
|
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
import * as google from "../sso/google"
|
|
2
|
-
import { Cookie } from "../../../constants"
|
|
3
|
-
import * as configs from "../../../configs"
|
|
4
|
-
import * as cache from "../../../cache"
|
|
5
|
-
import * as utils from "../../../utils"
|
|
6
|
-
import { UserCtx, SSOProfile } from "@budibase/types"
|
|
7
|
-
import { ssoSaveUserNoOp } from "../sso/sso"
|
|
8
|
-
|
|
9
|
-
const GoogleStrategy = require("passport-google-oauth").OAuth2Strategy
|
|
10
|
-
|
|
11
|
-
type Passport = {
|
|
12
|
-
authenticate: any
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
async function fetchGoogleCreds() {
|
|
16
|
-
let config = await configs.getGoogleDatasourceConfig()
|
|
17
|
-
|
|
18
|
-
if (!config) {
|
|
19
|
-
throw new Error("No google configuration found")
|
|
20
|
-
}
|
|
21
|
-
return config
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export async function preAuth(
|
|
25
|
-
passport: Passport,
|
|
26
|
-
ctx: UserCtx,
|
|
27
|
-
next: Function
|
|
28
|
-
) {
|
|
29
|
-
// get the relevant config
|
|
30
|
-
const googleConfig = await fetchGoogleCreds()
|
|
31
|
-
const platformUrl = await configs.getPlatformUrl({ tenantAware: false })
|
|
32
|
-
|
|
33
|
-
let callbackUrl = `${platformUrl}/api/global/auth/datasource/google/callback`
|
|
34
|
-
const strategy = await google.strategyFactory(
|
|
35
|
-
googleConfig,
|
|
36
|
-
callbackUrl,
|
|
37
|
-
ssoSaveUserNoOp
|
|
38
|
-
)
|
|
39
|
-
|
|
40
|
-
if (!ctx.query.appId) {
|
|
41
|
-
ctx.throw(400, "appId query param not present.")
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
return passport.authenticate(strategy, {
|
|
45
|
-
scope: ["profile", "email", "https://www.googleapis.com/auth/spreadsheets"],
|
|
46
|
-
accessType: "offline",
|
|
47
|
-
prompt: "consent",
|
|
48
|
-
})(ctx, next)
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
export async function postAuth(
|
|
52
|
-
passport: Passport,
|
|
53
|
-
ctx: UserCtx,
|
|
54
|
-
next: Function
|
|
55
|
-
) {
|
|
56
|
-
// get the relevant config
|
|
57
|
-
const config = await fetchGoogleCreds()
|
|
58
|
-
const platformUrl = await configs.getPlatformUrl({ tenantAware: false })
|
|
59
|
-
|
|
60
|
-
let callbackUrl = `${platformUrl}/api/global/auth/datasource/google/callback`
|
|
61
|
-
const authStateCookie = utils.getCookie<{ appId: string }>(
|
|
62
|
-
ctx,
|
|
63
|
-
Cookie.DatasourceAuth
|
|
64
|
-
)
|
|
65
|
-
|
|
66
|
-
if (!authStateCookie) {
|
|
67
|
-
throw new Error("Unable to fetch datasource auth cookie")
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
return passport.authenticate(
|
|
71
|
-
new GoogleStrategy(
|
|
72
|
-
{
|
|
73
|
-
clientID: config.clientID,
|
|
74
|
-
clientSecret: config.clientSecret,
|
|
75
|
-
callbackURL: callbackUrl,
|
|
76
|
-
},
|
|
77
|
-
(
|
|
78
|
-
accessToken: string,
|
|
79
|
-
refreshToken: string,
|
|
80
|
-
_profile: SSOProfile,
|
|
81
|
-
done: Function
|
|
82
|
-
) => {
|
|
83
|
-
utils.clearCookie(ctx, Cookie.DatasourceAuth)
|
|
84
|
-
done(null, { accessToken, refreshToken })
|
|
85
|
-
}
|
|
86
|
-
),
|
|
87
|
-
{ successRedirect: "/", failureRedirect: "/error" },
|
|
88
|
-
async (err: any, tokens: string[]) => {
|
|
89
|
-
const baseUrl = `/builder/app/${authStateCookie.appId}/data`
|
|
90
|
-
|
|
91
|
-
const id = utils.newid()
|
|
92
|
-
await cache.store(
|
|
93
|
-
`datasource:creation:${authStateCookie.appId}:google:${id}`,
|
|
94
|
-
{
|
|
95
|
-
tokens,
|
|
96
|
-
}
|
|
97
|
-
)
|
|
98
|
-
|
|
99
|
-
ctx.redirect(`${baseUrl}/new?continue_google_setup=${id}`)
|
|
100
|
-
}
|
|
101
|
-
)(ctx, next)
|
|
102
|
-
}
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import { UserStatus } from "../../constants"
|
|
2
|
-
import { compare } from "../../utils"
|
|
3
|
-
import * as users from "../../users"
|
|
4
|
-
import { authError } from "./utils"
|
|
5
|
-
import { BBContext } from "@budibase/types"
|
|
6
|
-
|
|
7
|
-
const INVALID_ERR = "Invalid credentials"
|
|
8
|
-
const EXPIRED = "This account has expired. Please reset your password"
|
|
9
|
-
|
|
10
|
-
export const options = {
|
|
11
|
-
passReqToCallback: true,
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Passport Local Authentication Middleware.
|
|
16
|
-
* @param ctx the request structure
|
|
17
|
-
* @param email username to login with
|
|
18
|
-
* @param password plain text password to log in with
|
|
19
|
-
* @param done callback from passport to return user information and errors
|
|
20
|
-
* @returns The authenticated user, or errors if they occur
|
|
21
|
-
*/
|
|
22
|
-
export async function authenticate(
|
|
23
|
-
ctx: BBContext,
|
|
24
|
-
email: string,
|
|
25
|
-
password: string,
|
|
26
|
-
done: Function
|
|
27
|
-
) {
|
|
28
|
-
if (!email) return authError(done, "Email Required")
|
|
29
|
-
if (!password) return authError(done, "Password Required")
|
|
30
|
-
|
|
31
|
-
const dbUser = await users.getGlobalUserByEmail(email)
|
|
32
|
-
if (dbUser == null) {
|
|
33
|
-
console.info(`user=${email} could not be found`)
|
|
34
|
-
return authError(done, INVALID_ERR)
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
if (dbUser.status === UserStatus.INACTIVE) {
|
|
38
|
-
console.info(`user=${email} is inactive`, dbUser)
|
|
39
|
-
return authError(done, INVALID_ERR)
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
if (!dbUser.password) {
|
|
43
|
-
console.info(`user=${email} has no password set`, dbUser)
|
|
44
|
-
return authError(done, EXPIRED)
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
if (!(await compare(password, dbUser.password))) {
|
|
48
|
-
return authError(done, INVALID_ERR)
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
// intentionally remove the users password in payload
|
|
52
|
-
delete dbUser.password
|
|
53
|
-
return done(null, dbUser)
|
|
54
|
-
}
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
import { ssoCallbackUrl } from "../utils"
|
|
2
|
-
import * as sso from "./sso"
|
|
3
|
-
import {
|
|
4
|
-
ConfigType,
|
|
5
|
-
SSOProfile,
|
|
6
|
-
SSOAuthDetails,
|
|
7
|
-
SSOProviderType,
|
|
8
|
-
SaveSSOUserFunction,
|
|
9
|
-
GoogleInnerConfig,
|
|
10
|
-
} from "@budibase/types"
|
|
11
|
-
|
|
12
|
-
const GoogleStrategy = require("passport-google-oauth").OAuth2Strategy
|
|
13
|
-
|
|
14
|
-
export function buildVerifyFn(saveUserFn: SaveSSOUserFunction) {
|
|
15
|
-
return (
|
|
16
|
-
accessToken: string,
|
|
17
|
-
refreshToken: string,
|
|
18
|
-
profile: SSOProfile,
|
|
19
|
-
done: Function
|
|
20
|
-
) => {
|
|
21
|
-
const details: SSOAuthDetails = {
|
|
22
|
-
provider: "google",
|
|
23
|
-
providerType: SSOProviderType.GOOGLE,
|
|
24
|
-
userId: profile.id,
|
|
25
|
-
profile: profile,
|
|
26
|
-
email: profile._json.email,
|
|
27
|
-
oauth2: {
|
|
28
|
-
accessToken,
|
|
29
|
-
refreshToken,
|
|
30
|
-
},
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
return sso.authenticate(
|
|
34
|
-
details,
|
|
35
|
-
true, // require local accounts to exist
|
|
36
|
-
done,
|
|
37
|
-
saveUserFn
|
|
38
|
-
)
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Create an instance of the google passport strategy. This wrapper fetches the configuration
|
|
44
|
-
* from couchDB rather than environment variables, using this factory is necessary for dynamically configuring passport.
|
|
45
|
-
* @returns Dynamically configured Passport Google Strategy
|
|
46
|
-
*/
|
|
47
|
-
export async function strategyFactory(
|
|
48
|
-
config: GoogleInnerConfig,
|
|
49
|
-
callbackUrl: string,
|
|
50
|
-
saveUserFn: SaveSSOUserFunction
|
|
51
|
-
) {
|
|
52
|
-
try {
|
|
53
|
-
const { clientID, clientSecret } = config
|
|
54
|
-
|
|
55
|
-
if (!clientID || !clientSecret) {
|
|
56
|
-
throw new Error(
|
|
57
|
-
"Configuration invalid. Must contain google clientID and clientSecret"
|
|
58
|
-
)
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
const verify = buildVerifyFn(saveUserFn)
|
|
62
|
-
return new GoogleStrategy(
|
|
63
|
-
{
|
|
64
|
-
clientID: config.clientID,
|
|
65
|
-
clientSecret: config.clientSecret,
|
|
66
|
-
callbackURL: callbackUrl,
|
|
67
|
-
},
|
|
68
|
-
verify
|
|
69
|
-
)
|
|
70
|
-
} catch (err: any) {
|
|
71
|
-
throw new Error(`Error constructing google authentication strategy: ${err}`)
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
export async function getCallbackUrl(config: GoogleInnerConfig) {
|
|
76
|
-
return ssoCallbackUrl(ConfigType.GOOGLE, config)
|
|
77
|
-
}
|