From 14370c81b9b4b0914e600f24636f1d007d91b5a7 Mon Sep 17 00:00:00 2001 From: Martin McKeaveney Date: Tue, 12 Oct 2021 16:13:54 +0100 Subject: [PATCH] SSL support for digitalocean, started utility function for BB logout, bunch of minor bug fixes --- .github/workflows/budibase.code-workspace | 10 +++++++ packages/auth/src/middleware/authenticated.js | 5 ++-- packages/auth/src/security/sessions.js | 15 ++++++++--- packages/auth/src/utils.js | 26 ++++++++++++++++++- packages/builder/cypress/support/commands.js | 2 +- .../DataTable/modals/CreateEditColumn.svelte | 10 ++++++- .../IntegrationConfigForm.svelte | 19 +++++++++++++- .../modals/CreateDatasourceModal.svelte | 2 +- .../modals/DatasourceConfigModal.svelte | 2 +- .../server/src/automations/steps/discord.js | 2 +- packages/server/src/definitions/datasource.ts | 2 ++ .../src/integrations/ca-certificate.crt | 25 ++++++++++++++++++ packages/server/src/integrations/postgres.ts | 20 +++++++++++++- .../worker/src/api/controllers/global/auth.js | 3 +++ .../src/api/controllers/global/users.js | 2 ++ 15 files changed, 131 insertions(+), 14 deletions(-) create mode 100644 .github/workflows/budibase.code-workspace create mode 100644 packages/server/src/integrations/ca-certificate.crt diff --git a/.github/workflows/budibase.code-workspace b/.github/workflows/budibase.code-workspace new file mode 100644 index 0000000000..c8c469300a --- /dev/null +++ b/.github/workflows/budibase.code-workspace @@ -0,0 +1,10 @@ +{ + "folders": [ + { + "path": "../.." + }, + { + "path": "../../../budibase-infra" + } + ] +} \ No newline at end of file diff --git a/packages/auth/src/middleware/authenticated.js b/packages/auth/src/middleware/authenticated.js index 944f3ee9d9..4223e7e395 100644 --- a/packages/auth/src/middleware/authenticated.js +++ b/packages/auth/src/middleware/authenticated.js @@ -42,8 +42,9 @@ module.exports = ( internal = false if (authCookie) { let error = null - const sessionId = authCookie.sessionId, - userId = authCookie.userId + const sessionId = authCookie.sessionId + const userId = authCookie.userId + const session = await getSession(userId, sessionId) if (!session) { error = "No session found" diff --git a/packages/auth/src/security/sessions.js b/packages/auth/src/security/sessions.js index 83ca9d9bcd..93c2d0a9ca 100644 --- a/packages/auth/src/security/sessions.js +++ b/packages/auth/src/security/sessions.js @@ -24,17 +24,24 @@ exports.createASession = async (userId, session) => { await client.store(makeSessionID(userId, sessionId), session, EXPIRY_SECONDS) } -exports.invalidateSessions = async (userId, sessionId = null) => { +exports.invalidateSessions = async (userId, sessionIds = null) => { let sessions = [] - if (sessionId) { - sessions.push({ key: makeSessionID(userId, sessionId) }) - } else { + + // If no sessionIds, get all the sessions for the user + if (!sessionIds) { sessions = await getSessionsForUser(userId) sessions.forEach( session => (session.key = makeSessionID(session.userId, session.sessionId)) ) + } else { + // use the passed array of sessionIds + sessions = Array.isArray(sessionIds) ? sessionIds : [sessionIds] + sessions = sessions.map(sessionId => ({ + key: makeSessionID(userId, sessionId), + })) } + const client = await redis.getSessionClient() const promises = [] for (let session of sessions) { diff --git a/packages/auth/src/utils.js b/packages/auth/src/utils.js index f509a626c1..13728e1c13 100644 --- a/packages/auth/src/utils.js +++ b/packages/auth/src/utils.js @@ -7,7 +7,7 @@ const { const jwt = require("jsonwebtoken") const { options } = require("./middleware/passport/jwt") const { createUserEmailView } = require("./db/views") -const { Headers, UserStatus } = require("./constants") +const { Headers, UserStatus, Cookies } = require("./constants") const { getGlobalDB, updateTenantId, @@ -19,6 +19,10 @@ const accounts = require("./cloud/accounts") const { hash } = require("./hashing") const userCache = require("./cache/user") const env = require("./environment") +const { + getSessionsForUser, + invalidateSessions, +} = require("./security/sessions") const APP_PREFIX = DocumentTypes.APP + SEPARATOR @@ -235,3 +239,23 @@ exports.saveUser = async ( } } } + +/** + * Logs a user out from budibase. Re-used across account portal and builder. + */ +exports.logout = async ({ ctx, userId, sessionId, keepActiveSession }) => { + let sessions = await getSessionsForUser(userId) + + if (keepActiveSession) { + sessions = sessions.filter(session => session.sessionId !== sessionId) + } + + await invalidateSessions( + userId, + sessions.map(({ sessionId }) => sessionId) + ) + + // clear cookies + this.clearCookie(ctx, Cookies.Auth) + this.clearCookie(ctx, Cookies.CurrentApp) +} diff --git a/packages/builder/cypress/support/commands.js b/packages/builder/cypress/support/commands.js index c8e01435aa..f179a24729 100644 --- a/packages/builder/cypress/support/commands.js +++ b/packages/builder/cypress/support/commands.js @@ -5,7 +5,7 @@ // *********************************************** // -Cypress.on('uncaught:exception', (err, runnable) => { +Cypress.on("uncaught:exception", () => { return false }) diff --git a/packages/builder/src/components/backend/DataTable/modals/CreateEditColumn.svelte b/packages/builder/src/components/backend/DataTable/modals/CreateEditColumn.svelte index 011c9bee43..c2c872fe9c 100644 --- a/packages/builder/src/components/backend/DataTable/modals/CreateEditColumn.svelte +++ b/packages/builder/src/components/backend/DataTable/modals/CreateEditColumn.svelte @@ -32,6 +32,7 @@ const FORMULA_TYPE = FIELDS.FORMULA.type const LINK_TYPE = FIELDS.LINK.type const dispatch = createEventDispatcher() + const PROHIBITED_COLUMN_NAMES = ["type", "_id", "_rev"] const { hide } = getContext(Context.Modal) let fieldDefinitions = cloneDeep(FIELDS) @@ -66,7 +67,11 @@ (field.type === LINK_TYPE && !field.tableId) || Object.keys($tables.draft?.schema ?? {}).some( key => key !== originalName && key === field.name - ) + ) || + columnNameInvalid + $: columnNameInvalid = PROHIBITED_COLUMN_NAMES.some( + name => field.name === name + ) // used to select what different options can be displayed for column type $: canBeSearched = @@ -200,6 +205,9 @@ label="Name" bind:value={field.name} disabled={uneditable || (linkEditDisabled && field.type === LINK_TYPE)} + error={columnNameInvalid + ? "type, _id and _rev are disallowed as column names" + : ""} />