Merge pull request #6440 from Budibase/fix/couch-db-url-parsing
Improve Couch DB URL parsing to handle edge cases and special characters
This commit is contained in:
commit
0f6ad15b14
|
@ -1,21 +1,42 @@
|
||||||
const PouchDB = require("pouchdb")
|
const PouchDB = require("pouchdb")
|
||||||
const env = require("../environment")
|
const env = require("../environment")
|
||||||
|
|
||||||
function getUrlInfo() {
|
exports.getUrlInfo = (url = env.COUCH_DB_URL) => {
|
||||||
let url = env.COUCH_DB_URL
|
let cleanUrl, username, password, host
|
||||||
let username, password, host
|
if (url) {
|
||||||
const [protocol, rest] = url.split("://")
|
// Ensure the URL starts with a protocol
|
||||||
|
const protoRegex = /^https?:\/\//i
|
||||||
|
if (!protoRegex.test(url)) {
|
||||||
|
url = `http://${url}`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Split into protocol and remainder
|
||||||
|
const split = url.split("://")
|
||||||
|
const protocol = split[0]
|
||||||
|
const rest = split.slice(1).join("://")
|
||||||
|
|
||||||
|
// Extract auth if specified
|
||||||
if (url.includes("@")) {
|
if (url.includes("@")) {
|
||||||
const hostParts = rest.split("@")
|
// Split into host and remainder
|
||||||
host = hostParts[1]
|
let parts = rest.split("@")
|
||||||
const authParts = hostParts[0].split(":")
|
host = parts[parts.length - 1]
|
||||||
|
let auth = parts.slice(0, -1).join("@")
|
||||||
|
|
||||||
|
// Split auth into username and password
|
||||||
|
if (auth.includes(":")) {
|
||||||
|
const authParts = auth.split(":")
|
||||||
username = authParts[0]
|
username = authParts[0]
|
||||||
password = authParts[1]
|
password = authParts.slice(1).join(":")
|
||||||
|
} else {
|
||||||
|
username = auth
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
host = rest
|
host = rest
|
||||||
}
|
}
|
||||||
|
cleanUrl = `${protocol}://${host}`
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
url: `${protocol}://${host}`,
|
url: cleanUrl,
|
||||||
auth: {
|
auth: {
|
||||||
username,
|
username,
|
||||||
password,
|
password,
|
||||||
|
@ -24,7 +45,7 @@ function getUrlInfo() {
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.getCouchInfo = () => {
|
exports.getCouchInfo = () => {
|
||||||
const urlInfo = getUrlInfo()
|
const urlInfo = exports.getUrlInfo()
|
||||||
let username
|
let username
|
||||||
let password
|
let password
|
||||||
if (env.COUCH_DB_USERNAME) {
|
if (env.COUCH_DB_USERNAME) {
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
require("../../../tests/utilities/TestConfiguration")
|
||||||
|
const getUrlInfo = require("../pouch").getUrlInfo
|
||||||
|
|
||||||
|
describe("pouch", () => {
|
||||||
|
describe("Couch DB URL parsing", () => {
|
||||||
|
it("should handle a null Couch DB URL", () => {
|
||||||
|
const info = getUrlInfo(null)
|
||||||
|
expect(info.url).toBeUndefined()
|
||||||
|
expect(info.auth.username).toBeUndefined()
|
||||||
|
})
|
||||||
|
it("should be able to parse a basic Couch DB URL", () => {
|
||||||
|
const info = getUrlInfo("http://host.com")
|
||||||
|
expect(info.url).toBe("http://host.com")
|
||||||
|
expect(info.auth.username).toBeUndefined()
|
||||||
|
})
|
||||||
|
it("should be able to parse a Couch DB basic URL with HTTPS", () => {
|
||||||
|
const info = getUrlInfo("https://host.com")
|
||||||
|
expect(info.url).toBe("https://host.com")
|
||||||
|
expect(info.auth.username).toBeUndefined()
|
||||||
|
})
|
||||||
|
it("should be able to parse a basic Couch DB URL with a custom port", () => {
|
||||||
|
const info = getUrlInfo("https://host.com:1234")
|
||||||
|
expect(info.url).toBe("https://host.com:1234")
|
||||||
|
expect(info.auth.username).toBeUndefined()
|
||||||
|
})
|
||||||
|
it("should be able to parse a Couch DB URL with auth", () => {
|
||||||
|
const info = getUrlInfo("https://user:pass@host.com:1234")
|
||||||
|
expect(info.url).toBe("https://host.com:1234")
|
||||||
|
expect(info.auth.username).toBe("user")
|
||||||
|
expect(info.auth.password).toBe("pass")
|
||||||
|
})
|
||||||
|
it("should be able to parse a Couch DB URL with auth and special chars", () => {
|
||||||
|
const info = getUrlInfo("https://user:s:p@s://@://:d@;][~s@host.com:1234")
|
||||||
|
expect(info.url).toBe("https://host.com:1234")
|
||||||
|
expect(info.auth.username).toBe("user")
|
||||||
|
expect(info.auth.password).toBe("s:p@s://@://:d@;][~s")
|
||||||
|
})
|
||||||
|
it("should be able to parse a Couch DB URL without a protocol", () => {
|
||||||
|
const info = getUrlInfo("host.com:1234")
|
||||||
|
expect(info.url).toBe("http://host.com:1234")
|
||||||
|
expect(info.auth.username).toBeUndefined()
|
||||||
|
})
|
||||||
|
it("should be able to parse a Couch DB URL with auth and without a protocol", () => {
|
||||||
|
const info = getUrlInfo("user:s:p@s://@://:d@;][~s@host.com:1234")
|
||||||
|
expect(info.url).toBe("http://host.com:1234")
|
||||||
|
expect(info.auth.username).toBe("user")
|
||||||
|
expect(info.auth.password).toBe("s:p@s://@://:d@;][~s")
|
||||||
|
})
|
||||||
|
it("should be able to parse a Couch DB URL with only username auth", () => {
|
||||||
|
const info = getUrlInfo("https://user@host.com:1234")
|
||||||
|
expect(info.url).toBe("https://host.com:1234")
|
||||||
|
expect(info.auth.username).toBe("user")
|
||||||
|
expect(info.auth.password).toBeUndefined()
|
||||||
|
})
|
||||||
|
it("should be able to parse a Couch DB URL with only username auth and without a protocol", () => {
|
||||||
|
const info = getUrlInfo("user@host.com:1234")
|
||||||
|
expect(info.url).toBe("http://host.com:1234")
|
||||||
|
expect(info.auth.username).toBe("user")
|
||||||
|
expect(info.auth.password).toBeUndefined()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
Loading…
Reference in New Issue