Fixing an issue with cookie auth.
This commit is contained in:
parent
6556a41a5a
commit
061868c826
|
@ -1,35 +1,36 @@
|
||||||
const PouchDB = require("pouchdb")
|
const PouchDB = require("pouchdb")
|
||||||
const env = require("../environment")
|
const env = require("../environment")
|
||||||
|
|
||||||
exports.getCouchUrl = () => {
|
exports.getCouchInfo = () => {
|
||||||
if (!env.COUCH_DB_URL) return
|
let url = "http://localhost:4005"
|
||||||
|
if (env.COUCH_DB_URL && env.COUCH_DB_URL.includes("@")) {
|
||||||
// username and password already exist in URL
|
url = env.COUCH_DB_URL
|
||||||
if (env.COUCH_DB_URL.includes("@")) {
|
} else if (env.COUCH_DB_URL) {
|
||||||
return env.COUCH_DB_URL
|
const [protocol, ...rest] = env.COUCH_DB_URL.split("://")
|
||||||
|
url = `${protocol}://${env.COUCH_DB_USERNAME}:${env.COUCH_DB_PASSWORD}@${rest}`
|
||||||
|
if (!env.COUCH_DB_USERNAME || !env.COUCH_DB_PASSWORD) {
|
||||||
|
throw new Error(
|
||||||
|
"CouchDB configuration invalid. You must provide a fully qualified CouchDB url, or the COUCH_DB_USER and COUCH_DB_PASSWORD environment variables."
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const [protocol, ...rest] = env.COUCH_DB_URL.split("://")
|
|
||||||
|
|
||||||
if (!env.COUCH_DB_USERNAME || !env.COUCH_DB_PASSWORD) {
|
|
||||||
throw new Error(
|
|
||||||
"CouchDB configuration invalid. You must provide a fully qualified CouchDB url, or the COUCH_DB_USER and COUCH_DB_PASSWORD environment variables."
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return `${protocol}://${env.COUCH_DB_USERNAME}:${env.COUCH_DB_PASSWORD}@${rest}`
|
|
||||||
}
|
|
||||||
|
|
||||||
exports.splitCouchUrl = url => {
|
|
||||||
const [protocol, rest] = url.split("://")
|
const [protocol, rest] = url.split("://")
|
||||||
const [auth, host] = rest.split("@")
|
const [auth, host] = rest.split("@")
|
||||||
const [username, password] = auth.split(":")
|
let [username, password] = auth.split(":")
|
||||||
|
if (!username && env.COUCH_DB_USERNAME) {
|
||||||
|
username = env.COUCH_DB_USERNAME
|
||||||
|
}
|
||||||
|
if (!password && env.COUCH_DB_PASSWORD) {
|
||||||
|
password = env.COUCH_DB_PASSWORD
|
||||||
|
}
|
||||||
|
const authCookie = Buffer.from(`${username}:${password}`).toString("base64")
|
||||||
return {
|
return {
|
||||||
url: `${protocol}://${host}`,
|
url: `${protocol}://${host}`,
|
||||||
auth: {
|
auth: {
|
||||||
username,
|
username: username,
|
||||||
password,
|
password: password,
|
||||||
},
|
},
|
||||||
|
cookie: `Basic ${authCookie}`,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,26 +40,12 @@ exports.splitCouchUrl = url => {
|
||||||
* Exposed for exceptional cases such as in-memory views.
|
* Exposed for exceptional cases such as in-memory views.
|
||||||
*/
|
*/
|
||||||
exports.getPouch = (opts = {}) => {
|
exports.getPouch = (opts = {}) => {
|
||||||
let auth = {
|
let { url, cookie } = exports.getCouchInfo()
|
||||||
username: env.COUCH_DB_USERNAME,
|
|
||||||
password: env.COUCH_DB_PASSWORD,
|
|
||||||
}
|
|
||||||
let url = exports.getCouchUrl() || "http://localhost:4005"
|
|
||||||
// need to update security settings
|
|
||||||
if (!auth.username || !auth.password || url.includes("@")) {
|
|
||||||
const split = exports.splitCouchUrl(url)
|
|
||||||
url = split.url
|
|
||||||
auth = split.auth
|
|
||||||
}
|
|
||||||
|
|
||||||
const authCookie = Buffer.from(`${auth.username}:${auth.password}`).toString(
|
|
||||||
"base64"
|
|
||||||
)
|
|
||||||
let POUCH_DB_DEFAULTS = {
|
let POUCH_DB_DEFAULTS = {
|
||||||
prefix: url,
|
prefix: url,
|
||||||
fetch: (url, opts) => {
|
fetch: (url, opts) => {
|
||||||
// use a specific authorization cookie - be very explicit about how we authenticate
|
// use a specific authorization cookie - be very explicit about how we authenticate
|
||||||
opts.headers.set("Authorization", `Basic ${authCookie}`)
|
opts.headers.set("Authorization", cookie)
|
||||||
return PouchDB.fetch(url, opts)
|
return PouchDB.fetch(url, opts)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ const {
|
||||||
const { getTenantId, getGlobalDBName } = require("../tenancy")
|
const { getTenantId, getGlobalDBName } = require("../tenancy")
|
||||||
const fetch = require("node-fetch")
|
const fetch = require("node-fetch")
|
||||||
const { doWithDB, allDbs } = require("./index")
|
const { doWithDB, allDbs } = require("./index")
|
||||||
const { getCouchUrl } = require("./pouch")
|
const { getCouchInfo } = require("./pouch")
|
||||||
const { getAppMetadata } = require("../cache/appMetadata")
|
const { getAppMetadata } = require("../cache/appMetadata")
|
||||||
const { checkSlashesInUrl } = require("../helpers")
|
const { checkSlashesInUrl } = require("../helpers")
|
||||||
const {
|
const {
|
||||||
|
@ -169,8 +169,14 @@ exports.getAllDbs = async (opts = { efficient: false }) => {
|
||||||
return allDbs()
|
return allDbs()
|
||||||
}
|
}
|
||||||
let dbs = []
|
let dbs = []
|
||||||
async function addDbs(url) {
|
let { url, cookie } = getCouchInfo()
|
||||||
const response = await fetch(checkSlashesInUrl(encodeURI(url)))
|
async function addDbs(couchUrl) {
|
||||||
|
const response = await fetch(checkSlashesInUrl(encodeURI(couchUrl)), {
|
||||||
|
method: "GET",
|
||||||
|
headers: {
|
||||||
|
Authorization: cookie,
|
||||||
|
},
|
||||||
|
})
|
||||||
if (response.status === 200) {
|
if (response.status === 200) {
|
||||||
let json = await response.json()
|
let json = await response.json()
|
||||||
dbs = dbs.concat(json)
|
dbs = dbs.concat(json)
|
||||||
|
@ -178,7 +184,7 @@ exports.getAllDbs = async (opts = { efficient: false }) => {
|
||||||
throw "Cannot connect to CouchDB instance"
|
throw "Cannot connect to CouchDB instance"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let couchUrl = `${getCouchUrl()}/_all_dbs`
|
let couchUrl = `${url}/_all_dbs`
|
||||||
let tenantId = getTenantId()
|
let tenantId = getTenantId()
|
||||||
if (!env.MULTI_TENANCY || (!efficient && tenantId === DEFAULT_TENANT_ID)) {
|
if (!env.MULTI_TENANCY || (!efficient && tenantId === DEFAULT_TENANT_ID)) {
|
||||||
// just get all DBs when:
|
// just get all DBs when:
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
const { SearchIndexes } = require("../../../db/utils")
|
const { SearchIndexes } = require("../../../db/utils")
|
||||||
const fetch = require("node-fetch")
|
const fetch = require("node-fetch")
|
||||||
const { getCouchUrl } = require("@budibase/backend-core/db")
|
const { getCouchInfo } = require("@budibase/backend-core/db")
|
||||||
const { getAppId } = require("@budibase/backend-core/context")
|
const { getAppId } = require("@budibase/backend-core/context")
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -242,11 +242,10 @@ class QueryBuilder {
|
||||||
|
|
||||||
async run() {
|
async run() {
|
||||||
const appId = getAppId()
|
const appId = getAppId()
|
||||||
const url = `${getCouchUrl()}/${appId}/_design/database/_search/${
|
const { url, cookie } = getCouchInfo()
|
||||||
SearchIndexes.ROWS
|
const fullPath = `${url}/${appId}/_design/database/_search/${SearchIndexes.ROWS}`
|
||||||
}`
|
|
||||||
const body = this.buildSearchBody()
|
const body = this.buildSearchBody()
|
||||||
return await runQuery(url, body)
|
return await runQuery(fullPath, body, cookie)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -254,12 +253,16 @@ class QueryBuilder {
|
||||||
* Executes a lucene search query.
|
* Executes a lucene search query.
|
||||||
* @param url The query URL
|
* @param url The query URL
|
||||||
* @param body The request body defining search criteria
|
* @param body The request body defining search criteria
|
||||||
|
* @param cookie The auth cookie for CouchDB
|
||||||
* @returns {Promise<{rows: []}>}
|
* @returns {Promise<{rows: []}>}
|
||||||
*/
|
*/
|
||||||
const runQuery = async (url, body) => {
|
const runQuery = async (url, body, cookie) => {
|
||||||
const response = await fetch(url, {
|
const response = await fetch(url, {
|
||||||
body: JSON.stringify(body),
|
body: JSON.stringify(body),
|
||||||
method: "POST",
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
Authorization: cookie,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
const json = await response.json()
|
const json = await response.json()
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue