From 69bfd01bf039d422dd86124566a4453da61dadd8 Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Fri, 5 Jan 2024 11:37:10 +0000 Subject: [PATCH 1/6] Attach authenticated user to DataDog spans. --- .../backend-core/src/middleware/authenticated.ts | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/packages/backend-core/src/middleware/authenticated.ts b/packages/backend-core/src/middleware/authenticated.ts index 16f658b90a..cfdb7bafed 100644 --- a/packages/backend-core/src/middleware/authenticated.ts +++ b/packages/backend-core/src/middleware/authenticated.ts @@ -15,6 +15,7 @@ import * as identity from "../context/identity" import env from "../environment" import { Ctx, EndpointMatcher, SessionCookie } from "@budibase/types" import { InvalidAPIKeyError, ErrorCode } from "../errors" +import tracer from "dd-trace" const ONE_MINUTE = env.SESSION_UPDATE_PERIOD ? parseInt(env.SESSION_UPDATE_PERIOD) @@ -166,6 +167,20 @@ export default function ( if (!authenticated) { authenticated = false } + + if (user) { + tracer.setUser({ + id: user?.id, + email: user?.email, + tenantId: user?.tenantId, + admin: user?.admin, + builder: user?.builder, + budibaseAccess: user?.budibaseAccess, + status: user?.status, + roles: user?.roles, + }) + } + // isAuthenticated is a function, so use a variable to be able to check authed state finalise(ctx, { authenticated, user, internal, version, publicEndpoint }) From f416f7a54f61ccd1c2ea086e9f85a83e3fa9b072 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Fri, 5 Jan 2024 12:24:56 +0000 Subject: [PATCH 2/6] Get rid of a warning when starting up self host stack with docker compose V2 - OFFLINE_MODE is fine to be left as a blank string and warning might be causing some confusion. --- hosting/docker-compose.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hosting/docker-compose.yaml b/hosting/docker-compose.yaml index 34cae92dc7..36b88466fe 100644 --- a/hosting/docker-compose.yaml +++ b/hosting/docker-compose.yaml @@ -26,7 +26,7 @@ services: BB_ADMIN_USER_EMAIL: ${BB_ADMIN_USER_EMAIL} BB_ADMIN_USER_PASSWORD: ${BB_ADMIN_USER_PASSWORD} PLUGINS_DIR: ${PLUGINS_DIR} - OFFLINE_MODE: ${OFFLINE_MODE} + OFFLINE_MODE: ${OFFLINE_MODE:-} depends_on: - worker-service - redis-service @@ -53,7 +53,7 @@ services: INTERNAL_API_KEY: ${INTERNAL_API_KEY} REDIS_URL: redis-service:6379 REDIS_PASSWORD: ${REDIS_PASSWORD} - OFFLINE_MODE: ${OFFLINE_MODE} + OFFLINE_MODE: ${OFFLINE_MODE:-} depends_on: - redis-service - minio-service From f2f16cfceec7e8cff0197523995507ea6f91701d Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Fri, 5 Jan 2024 13:17:10 +0000 Subject: [PATCH 3/6] Adding an option to disable password validation when creating an admin user - this means that the environment variables used for BB_ADMIN creation can have any length of password (not breaking change). --- packages/backend-core/src/environment.ts | 2 ++ packages/backend-core/src/security/auth.ts | 6 +++--- packages/backend-core/src/users/db.ts | 17 +++++++++++++---- packages/server/src/startup.ts | 6 +++++- packages/types/src/sdk/user.ts | 1 + 5 files changed, 24 insertions(+), 8 deletions(-) diff --git a/packages/backend-core/src/environment.ts b/packages/backend-core/src/environment.ts index 138dbbd9e0..0fec786c31 100644 --- a/packages/backend-core/src/environment.ts +++ b/packages/backend-core/src/environment.ts @@ -166,6 +166,8 @@ const environment = { DISABLE_JWT_WARNING: process.env.DISABLE_JWT_WARNING, BLACKLIST_IPS: process.env.BLACKLIST_IPS, SERVICE_TYPE: "unknown", + PASSWORD_MIN_LENGTH: process.env.PASSWORD_MIN_LENGTH, + PASSWORD_MAX_LENGTH: process.env.PASSWORD_MAX_LENGTH, /** * Enable to allow an admin user to login using a password. * This can be useful to prevent lockout when configuring SSO. diff --git a/packages/backend-core/src/security/auth.ts b/packages/backend-core/src/security/auth.ts index c90d9df09b..1cce35a0af 100644 --- a/packages/backend-core/src/security/auth.ts +++ b/packages/backend-core/src/security/auth.ts @@ -1,7 +1,7 @@ -import { env } from ".." +import env from "../environment" -export const PASSWORD_MIN_LENGTH = +(process.env.PASSWORD_MIN_LENGTH || 8) -export const PASSWORD_MAX_LENGTH = +(process.env.PASSWORD_MAX_LENGTH || 512) +export const PASSWORD_MIN_LENGTH = +(env.PASSWORD_MIN_LENGTH || 8) +export const PASSWORD_MAX_LENGTH = +(env.PASSWORD_MAX_LENGTH || 512) export function validatePassword( password: string diff --git a/packages/backend-core/src/users/db.ts b/packages/backend-core/src/users/db.ts index 3214b3ab63..6d2e476707 100644 --- a/packages/backend-core/src/users/db.ts +++ b/packages/backend-core/src/users/db.ts @@ -44,6 +44,12 @@ type GroupFns = { getBulk: GroupGetFn getGroupBuilderAppIds: GroupBuildersFn } +type CreateAdminUserOpts = { + ssoId?: string + hashPassword?: boolean + requirePassword?: boolean + noPasswordValidation?: boolean +} type FeatureFns = { isSSOEnforced: FeatureFn; isAppBuildersEnabled: FeatureFn } const bulkDeleteProcessing = async (dbUser: User) => { @@ -112,9 +118,11 @@ export class UserDB { throw new HTTPError("Password change is disabled for this user", 400) } - const passwordValidation = validatePassword(password) - if (!passwordValidation.valid) { - throw new HTTPError(passwordValidation.error, 400) + if (!opts.noPasswordValidation) { + const passwordValidation = validatePassword(password) + if (!passwordValidation.valid) { + throw new HTTPError(passwordValidation.error, 400) + } } hashedPassword = opts.hashPassword ? await hash(password) : password @@ -489,7 +497,7 @@ export class UserDB { email: string, password: string, tenantId: string, - opts?: { ssoId?: string; hashPassword?: boolean; requirePassword?: boolean } + opts?: CreateAdminUserOpts ) { const user: User = { email: email, @@ -513,6 +521,7 @@ export class UserDB { return await UserDB.save(user, { hashPassword: opts?.hashPassword, requirePassword: opts?.requirePassword, + noPasswordValidation: opts?.noPasswordValidation, }) } diff --git a/packages/server/src/startup.ts b/packages/server/src/startup.ts index 6860fe5f9b..880bf7a894 100644 --- a/packages/server/src/startup.ts +++ b/packages/server/src/startup.ts @@ -138,7 +138,11 @@ export async function startup(app?: Koa, server?: Server) { bbAdminEmail, bbAdminPassword, tenantId, - { hashPassword: true, requirePassword: true } + { + hashPassword: true, + requirePassword: true, + noPasswordValidation: true, + } ) // Need to set up an API key for automated integration tests if (env.isTest()) { diff --git a/packages/types/src/sdk/user.ts b/packages/types/src/sdk/user.ts index 2b970da1a9..fb2e32c811 100644 --- a/packages/types/src/sdk/user.ts +++ b/packages/types/src/sdk/user.ts @@ -2,4 +2,5 @@ export interface SaveUserOpts { hashPassword?: boolean requirePassword?: boolean currentUserId?: string + noPasswordValidation?: boolean } From b3cd74e8774fa1c5deb2ed0b97684fdd85b40f44 Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Fri, 5 Jan 2024 13:49:01 +0000 Subject: [PATCH 4/6] Remove user email from DataDog user info. --- packages/backend-core/src/middleware/authenticated.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/backend-core/src/middleware/authenticated.ts b/packages/backend-core/src/middleware/authenticated.ts index cfdb7bafed..8885e5c996 100644 --- a/packages/backend-core/src/middleware/authenticated.ts +++ b/packages/backend-core/src/middleware/authenticated.ts @@ -171,7 +171,6 @@ export default function ( if (user) { tracer.setUser({ id: user?.id, - email: user?.email, tenantId: user?.tenantId, admin: user?.admin, builder: user?.builder, From b4b8e16f22fb968cc17fc4cdabaac766a8225d2c Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Fri, 5 Jan 2024 13:58:31 +0000 Subject: [PATCH 5/6] PR comments. --- packages/backend-core/src/users/db.ts | 6 +++--- packages/server/src/startup.ts | 2 +- packages/types/src/sdk/user.ts | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/backend-core/src/users/db.ts b/packages/backend-core/src/users/db.ts index 6d2e476707..4d0d216603 100644 --- a/packages/backend-core/src/users/db.ts +++ b/packages/backend-core/src/users/db.ts @@ -48,7 +48,7 @@ type CreateAdminUserOpts = { ssoId?: string hashPassword?: boolean requirePassword?: boolean - noPasswordValidation?: boolean + skipPasswordValidation?: boolean } type FeatureFns = { isSSOEnforced: FeatureFn; isAppBuildersEnabled: FeatureFn } @@ -118,7 +118,7 @@ export class UserDB { throw new HTTPError("Password change is disabled for this user", 400) } - if (!opts.noPasswordValidation) { + if (!opts.skipPasswordValidation) { const passwordValidation = validatePassword(password) if (!passwordValidation.valid) { throw new HTTPError(passwordValidation.error, 400) @@ -521,7 +521,7 @@ export class UserDB { return await UserDB.save(user, { hashPassword: opts?.hashPassword, requirePassword: opts?.requirePassword, - noPasswordValidation: opts?.noPasswordValidation, + skipPasswordValidation: opts?.skipPasswordValidation, }) } diff --git a/packages/server/src/startup.ts b/packages/server/src/startup.ts index 880bf7a894..f9b5974eb2 100644 --- a/packages/server/src/startup.ts +++ b/packages/server/src/startup.ts @@ -141,7 +141,7 @@ export async function startup(app?: Koa, server?: Server) { { hashPassword: true, requirePassword: true, - noPasswordValidation: true, + skipPasswordValidation: true, } ) // Need to set up an API key for automated integration tests diff --git a/packages/types/src/sdk/user.ts b/packages/types/src/sdk/user.ts index fb2e32c811..3f6f69d2d1 100644 --- a/packages/types/src/sdk/user.ts +++ b/packages/types/src/sdk/user.ts @@ -2,5 +2,5 @@ export interface SaveUserOpts { hashPassword?: boolean requirePassword?: boolean currentUserId?: string - noPasswordValidation?: boolean + skipPasswordValidation?: boolean } From 946a73f1b6b6f1603a92e5198afc183d93c1967f Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Fri, 5 Jan 2024 14:40:16 +0000 Subject: [PATCH 6/6] Set user ID correctly. --- packages/backend-core/src/middleware/authenticated.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/backend-core/src/middleware/authenticated.ts b/packages/backend-core/src/middleware/authenticated.ts index 8885e5c996..e8e16589de 100644 --- a/packages/backend-core/src/middleware/authenticated.ts +++ b/packages/backend-core/src/middleware/authenticated.ts @@ -170,7 +170,7 @@ export default function ( if (user) { tracer.setUser({ - id: user?.id, + id: user?._id, tenantId: user?.tenantId, admin: user?.admin, builder: user?.builder,