From fbaedd6a3472ab0396620ebdd5d0d0bfec344d3f Mon Sep 17 00:00:00 2001 From: Rory Powell Date: Wed, 3 Nov 2021 15:04:05 +0000 Subject: [PATCH 1/2] Fix: Prevent user updates in multi tenant mode from deleting user password. Also forward the authentication error from the backend to the login page to warn when an sso user is trying to log in with a password when one is not present --- packages/auth/src/middleware/passport/local.js | 14 ++++++++++++++ packages/auth/src/utils.js | 4 ++-- .../builder/src/pages/builder/auth/login.svelte | 2 +- packages/builder/src/stores/portal/auth.js | 2 +- 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/packages/auth/src/middleware/passport/local.js b/packages/auth/src/middleware/passport/local.js index 0db40d64eb..50c2b18d87 100644 --- a/packages/auth/src/middleware/passport/local.js +++ b/packages/auth/src/middleware/passport/local.js @@ -9,6 +9,7 @@ const { createASession } = require("../../security/sessions") const { getTenantId } = require("../../tenancy") const INVALID_ERR = "Invalid Credentials" +const SSO_NO_PASSWORD = "SSO user does not have a password set" exports.options = { passReqToCallback: true, @@ -36,6 +37,19 @@ exports.authenticate = async function (ctx, email, password, done) { return authError(done, INVALID_ERR) } + // check that the user has a stored password before proceeding + if (!dbUser.password) { + if ( + (dbUser.account && dbUser.account.authType === "sso") || // root account sso + dbUser.thirdPartyProfile // internal sso + ) { + return authError(done, SSO_NO_PASSWORD) + } + + console.error("User has no password", dbUser) + return authError(done, INVALID_ERR) + } + // authenticate if (await compare(password, dbUser.password)) { const sessionId = newid() diff --git a/packages/auth/src/utils.js b/packages/auth/src/utils.js index e1df289d6e..f7ab5d6990 100644 --- a/packages/auth/src/utils.js +++ b/packages/auth/src/utils.js @@ -181,8 +181,8 @@ exports.saveUser = async ( // check budibase users in other tenants if (env.MULTI_TENANCY) { - dbUser = await getTenantUser(email) - if (dbUser != null && dbUser.tenantId !== tenantId) { + const tenantUser = await getTenantUser(email) + if (tenantUser != null && tenantUser.tenantId !== tenantId) { throw `Email address ${email} already in use.` } } diff --git a/packages/builder/src/pages/builder/auth/login.svelte b/packages/builder/src/pages/builder/auth/login.svelte index 7374678236..5a5a27eb6e 100644 --- a/packages/builder/src/pages/builder/auth/login.svelte +++ b/packages/builder/src/pages/builder/auth/login.svelte @@ -44,7 +44,7 @@ } } catch (err) { console.error(err) - notifications.error("Invalid credentials") + notifications.error(err.message ? err.message : "Invalid Credentials") } } diff --git a/packages/builder/src/stores/portal/auth.js b/packages/builder/src/stores/portal/auth.js index 333226e3ba..134232dd74 100644 --- a/packages/builder/src/stores/portal/auth.js +++ b/packages/builder/src/stores/portal/auth.js @@ -112,7 +112,7 @@ export function createAuthStore() { if (response.status === 200) { setUser(json.user) } else { - throw "Invalid credentials" + throw new Error(json.message ? json.message : "Invalid credentials") } return json }, From 044579b829d2f5ad2cfbe59abc18c0663da91965 Mon Sep 17 00:00:00 2001 From: Rory Powell Date: Wed, 3 Nov 2021 15:46:45 +0000 Subject: [PATCH 2/2] Add expired user notification --- packages/auth/src/middleware/passport/local.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/auth/src/middleware/passport/local.js b/packages/auth/src/middleware/passport/local.js index 50c2b18d87..f95c3a173e 100644 --- a/packages/auth/src/middleware/passport/local.js +++ b/packages/auth/src/middleware/passport/local.js @@ -10,6 +10,7 @@ const { getTenantId } = require("../../tenancy") const INVALID_ERR = "Invalid Credentials" const SSO_NO_PASSWORD = "SSO user does not have a password set" +const EXPIRED = "This account has expired. Please reset your password" exports.options = { passReqToCallback: true, @@ -46,8 +47,8 @@ exports.authenticate = async function (ctx, email, password, done) { return authError(done, SSO_NO_PASSWORD) } - console.error("User has no password", dbUser) - return authError(done, INVALID_ERR) + console.error("Non SSO usser has no password set", dbUser) + return authError(done, EXPIRED) } // authenticate