commit
1d1f271349
|
@ -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"
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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,7 @@ const accounts = require("./cloud/accounts")
|
|||
const { hash } = require("./hashing")
|
||||
const userCache = require("./cache/user")
|
||||
const env = require("./environment")
|
||||
const { getUserSessions, invalidateSessions } = require("./security/sessions")
|
||||
|
||||
const APP_PREFIX = DocumentTypes.APP + SEPARATOR
|
||||
|
||||
|
@ -235,3 +236,28 @@ exports.saveUser = async (
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs a user out from budibase. Re-used across account portal and builder.
|
||||
*/
|
||||
exports.platformLogout = async ({ ctx, userId, keepActiveSession }) => {
|
||||
if (!ctx) throw new Error("Koa context must be supplied to logout.")
|
||||
|
||||
const currentSession = this.getCookie(ctx, Cookies.Auth)
|
||||
let sessions = await getUserSessions(userId)
|
||||
|
||||
if (keepActiveSession) {
|
||||
sessions = sessions.filter(
|
||||
session => session.sessionId !== currentSession.sessionId
|
||||
)
|
||||
} else {
|
||||
// clear cookies
|
||||
this.clearCookie(ctx, Cookies.Auth)
|
||||
this.clearCookie(ctx, Cookies.CurrentApp)
|
||||
}
|
||||
|
||||
await invalidateSessions(
|
||||
userId,
|
||||
sessions.map(({ sessionId }) => sessionId)
|
||||
)
|
||||
}
|
||||
|
|
|
@ -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", "tableId"]
|
||||
const { hide } = getContext(Context.Modal)
|
||||
let fieldDefinitions = cloneDeep(FIELDS)
|
||||
|
||||
|
@ -66,6 +67,10 @@
|
|||
(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
|
||||
|
@ -200,6 +205,9 @@
|
|||
label="Name"
|
||||
bind:value={field.name}
|
||||
disabled={uneditable || (linkEditDisabled && field.type === LINK_TYPE)}
|
||||
error={columnNameInvalid
|
||||
? `${PROHIBITED_COLUMN_NAMES.join(", ")} are not allowed as column names`
|
||||
: ""}
|
||||
/>
|
||||
|
||||
<Select
|
||||
|
|
|
@ -1,10 +1,18 @@
|
|||
<script>
|
||||
import { Label, Input, Layout, Toggle, Button } from "@budibase/bbui"
|
||||
import {
|
||||
Label,
|
||||
Input,
|
||||
Layout,
|
||||
Toggle,
|
||||
Button,
|
||||
TextArea,
|
||||
} from "@budibase/bbui"
|
||||
import KeyValueBuilder from "components/integration/KeyValueBuilder.svelte"
|
||||
import { capitalise } from "helpers"
|
||||
|
||||
export let integration
|
||||
export let schema
|
||||
|
||||
let addButton
|
||||
</script>
|
||||
|
||||
|
@ -29,6 +37,15 @@
|
|||
<Label>{capitalise(configKey)}</Label>
|
||||
<Toggle text="" bind:value={integration[configKey]} />
|
||||
</div>
|
||||
{:else if schema[configKey].type === "longForm"}
|
||||
<div class="form-row">
|
||||
<Label>{capitalise(configKey)}</Label>
|
||||
<TextArea
|
||||
type={schema[configKey].type}
|
||||
on:change
|
||||
bind:value={integration[configKey]}
|
||||
/>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="form-row">
|
||||
<Label>{capitalise(configKey)}</Label>
|
||||
|
|
|
@ -60,7 +60,7 @@
|
|||
</Modal>
|
||||
|
||||
<Modal bind:this={externalDatasourceModal}>
|
||||
<DatasourceConfigModal {integration} />
|
||||
<DatasourceConfigModal {integration} {modal} />
|
||||
</Modal>
|
||||
|
||||
<Modal bind:this={modal}>
|
||||
|
|
|
@ -64,7 +64,7 @@
|
|||
? "Fetch tables from database"
|
||||
: "Save and continue to query"}
|
||||
cancelText="Back"
|
||||
size="M"
|
||||
size="L"
|
||||
>
|
||||
<Layout noPadding>
|
||||
<Body size="XS"
|
||||
|
|
|
@ -77,7 +77,7 @@ exports.run = async function ({ inputs }) {
|
|||
const { status, message } = await getFetchResponse(response)
|
||||
return {
|
||||
httpStatus: status,
|
||||
success: status === 200,
|
||||
success: status === 200 || status === 204,
|
||||
response: message,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,12 +20,14 @@ export enum QueryTypes {
|
|||
|
||||
export enum DatasourceFieldTypes {
|
||||
STRING = "string",
|
||||
LONGFORM = "longForm",
|
||||
BOOLEAN = "boolean",
|
||||
NUMBER = "number",
|
||||
PASSWORD = "password",
|
||||
LIST = "list",
|
||||
OBJECT = "object",
|
||||
JSON = "json",
|
||||
FILE = "file",
|
||||
}
|
||||
|
||||
export enum SourceNames {
|
||||
|
|
|
@ -28,6 +28,8 @@ module PostgresModule {
|
|||
user: string
|
||||
password: string
|
||||
ssl?: boolean
|
||||
ca?: string
|
||||
rejectUnauthorized?: boolean
|
||||
}
|
||||
|
||||
const SCHEMA: Integration = {
|
||||
|
@ -67,6 +69,16 @@ module PostgresModule {
|
|||
default: false,
|
||||
required: false,
|
||||
},
|
||||
rejectUnauthorized: {
|
||||
type: DatasourceFieldTypes.BOOLEAN,
|
||||
default: false,
|
||||
required: false,
|
||||
},
|
||||
ca: {
|
||||
type: DatasourceFieldTypes.LONGFORM,
|
||||
default: false,
|
||||
required: false,
|
||||
},
|
||||
},
|
||||
query: {
|
||||
create: {
|
||||
|
@ -144,7 +156,12 @@ module PostgresModule {
|
|||
|
||||
let newConfig = {
|
||||
...this.config,
|
||||
ssl: this.config.ssl ? { rejectUnauthorized: true } : undefined,
|
||||
ssl: this.config.ssl
|
||||
? {
|
||||
rejectUnauthorized: this.config.rejectUnauthorized,
|
||||
ca: this.config.ca,
|
||||
}
|
||||
: undefined,
|
||||
}
|
||||
if (!this.pool) {
|
||||
this.pool = new Pool(newConfig)
|
||||
|
|
|
@ -14,6 +14,7 @@ const {
|
|||
isMultiTenant,
|
||||
} = require("@budibase/auth/tenancy")
|
||||
const env = require("../../../environment")
|
||||
const { platformLogout } = require("../../../../../auth/src/utils")
|
||||
|
||||
function googleCallbackUrl(config) {
|
||||
// incase there is a callback URL from before
|
||||
|
@ -121,8 +122,7 @@ exports.resetUpdate = async ctx => {
|
|||
}
|
||||
|
||||
exports.logout = async ctx => {
|
||||
clearCookie(ctx, Cookies.Auth)
|
||||
clearCookie(ctx, Cookies.CurrentApp)
|
||||
await platformLogout({ ctx, userId: ctx.user._id })
|
||||
ctx.body = { message: "User logged out." }
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,8 @@ const {
|
|||
StaticDatabases,
|
||||
generateNewUsageQuotaDoc,
|
||||
} = require("@budibase/auth/db")
|
||||
const { hash, getGlobalUserByEmail, saveUser } = require("@budibase/auth").utils
|
||||
const { hash, getGlobalUserByEmail, saveUser, platformLogout } =
|
||||
require("@budibase/auth").utils
|
||||
const { EmailTemplatePurpose } = require("../../../constants")
|
||||
const { checkInviteCode } = require("../../../utilities/redis")
|
||||
const { sendEmail } = require("../../../utilities/email")
|
||||
|
@ -173,7 +174,14 @@ exports.updateSelf = async ctx => {
|
|||
const db = getGlobalDB()
|
||||
const user = await db.get(ctx.user._id)
|
||||
if (ctx.request.body.password) {
|
||||
// changing password
|
||||
ctx.request.body.password = await hash(ctx.request.body.password)
|
||||
// Log all other sessions out apart from the current one
|
||||
await platformLogout({
|
||||
ctx,
|
||||
userId: ctx.user._id,
|
||||
keepActiveSession: true,
|
||||
})
|
||||
}
|
||||
// don't allow sending up an ID/Rev, always use the existing one
|
||||
delete ctx.request.body._id
|
||||
|
|
Loading…
Reference in New Issue