Merge pull request #2881 from Budibase/api-keys
Add API keys between account portal and budibase
This commit is contained in:
commit
421f72c4dc
|
@ -89,6 +89,8 @@ spec:
|
||||||
value: {{ .Values.globals.selfHosted | quote }}
|
value: {{ .Values.globals.selfHosted | quote }}
|
||||||
- name: ACCOUNT_PORTAL_URL
|
- name: ACCOUNT_PORTAL_URL
|
||||||
value: {{ .Values.globals.accountPortalUrl | quote }}
|
value: {{ .Values.globals.accountPortalUrl | quote }}
|
||||||
|
- name: ACCOUNT_PORTAL_API_KEY
|
||||||
|
value: {{ .Values.globals.accountPortalApiKey | quote }}
|
||||||
- name: COOKIE_DOMAIN
|
- name: COOKIE_DOMAIN
|
||||||
value: {{ .Values.globals.cookieDomain | quote }}
|
value: {{ .Values.globals.cookieDomain | quote }}
|
||||||
image: budibase/worker
|
image: budibase/worker
|
||||||
|
|
|
@ -90,6 +90,7 @@ globals:
|
||||||
logLevel: info
|
logLevel: info
|
||||||
selfHosted: 1
|
selfHosted: 1
|
||||||
accountPortalUrL: ""
|
accountPortalUrL: ""
|
||||||
|
accountPortalApiKey: ""
|
||||||
cookieDomain: ""
|
cookieDomain: ""
|
||||||
createSecrets: true # creates an internal API key, JWT secrets and redis password for you
|
createSecrets: true # creates an internal API key, JWT secrets and redis password for you
|
||||||
|
|
||||||
|
|
|
@ -1,16 +1,18 @@
|
||||||
const API = require("./api")
|
const API = require("./api")
|
||||||
const env = require("../environment")
|
const env = require("../environment")
|
||||||
|
const { Headers } = require("../constants")
|
||||||
|
|
||||||
const api = new API(env.ACCOUNT_PORTAL_URL)
|
const api = new API(env.ACCOUNT_PORTAL_URL)
|
||||||
|
|
||||||
// TODO: Authorization
|
|
||||||
|
|
||||||
exports.getAccount = async email => {
|
exports.getAccount = async email => {
|
||||||
const payload = {
|
const payload = {
|
||||||
email,
|
email,
|
||||||
}
|
}
|
||||||
const response = await api.post(`/api/accounts/search`, {
|
const response = await api.post(`/api/accounts/search`, {
|
||||||
body: payload,
|
body: payload,
|
||||||
|
headers: {
|
||||||
|
[Headers.API_KEY]: env.ACCOUNT_PORTAL_API_KEY,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
const json = await response.json()
|
const json = await response.json()
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ module.exports = {
|
||||||
INTERNAL_API_KEY: process.env.INTERNAL_API_KEY,
|
INTERNAL_API_KEY: process.env.INTERNAL_API_KEY,
|
||||||
MULTI_TENANCY: process.env.MULTI_TENANCY,
|
MULTI_TENANCY: process.env.MULTI_TENANCY,
|
||||||
ACCOUNT_PORTAL_URL: process.env.ACCOUNT_PORTAL_URL,
|
ACCOUNT_PORTAL_URL: process.env.ACCOUNT_PORTAL_URL,
|
||||||
|
ACCOUNT_PORTAL_API_KEY: process.env.ACCOUNT_PORTAL_API_KEY,
|
||||||
DISABLE_ACCOUNT_PORTAL: process.env.DISABLE_ACCOUNT_PORTAL,
|
DISABLE_ACCOUNT_PORTAL: process.env.DISABLE_ACCOUNT_PORTAL,
|
||||||
SELF_HOSTED: !!parseInt(process.env.SELF_HOSTED),
|
SELF_HOSTED: !!parseInt(process.env.SELF_HOSTED),
|
||||||
COOKIE_DOMAIN: process.env.COOKIE_DOMAIN,
|
COOKIE_DOMAIN: process.env.COOKIE_DOMAIN,
|
||||||
|
|
|
@ -7,6 +7,7 @@ exports.buildMatcherRegex = patterns => {
|
||||||
return patterns.map(pattern => {
|
return patterns.map(pattern => {
|
||||||
const isObj = typeof pattern === "object" && pattern.route
|
const isObj = typeof pattern === "object" && pattern.route
|
||||||
const method = isObj ? pattern.method : "GET"
|
const method = isObj ? pattern.method : "GET"
|
||||||
|
const strict = pattern.strict ? pattern.strict : false
|
||||||
let route = isObj ? pattern.route : pattern
|
let route = isObj ? pattern.route : pattern
|
||||||
|
|
||||||
const matches = route.match(PARAM_REGEX)
|
const matches = route.match(PARAM_REGEX)
|
||||||
|
@ -16,13 +17,19 @@ exports.buildMatcherRegex = patterns => {
|
||||||
route = route.replace(match, pattern)
|
route = route.replace(match, pattern)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return { regex: new RegExp(route), method }
|
return { regex: new RegExp(route), method, strict, route }
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.matches = (ctx, options) => {
|
exports.matches = (ctx, options) => {
|
||||||
return options.find(({ regex, method }) => {
|
return options.find(({ regex, method, strict, route }) => {
|
||||||
const urlMatch = regex.test(ctx.request.url)
|
let urlMatch
|
||||||
|
if (strict) {
|
||||||
|
urlMatch = ctx.request.url === route
|
||||||
|
} else {
|
||||||
|
urlMatch = regex.test(ctx.request.url)
|
||||||
|
}
|
||||||
|
|
||||||
const methodMatch =
|
const methodMatch =
|
||||||
method === "ALL"
|
method === "ALL"
|
||||||
? true
|
? true
|
||||||
|
|
|
@ -205,9 +205,13 @@ module External {
|
||||||
} else {
|
} else {
|
||||||
// we're not inserting a doc, will be a bunch of update calls
|
// we're not inserting a doc, will be a bunch of update calls
|
||||||
const isUpdate = !field.through
|
const isUpdate = !field.through
|
||||||
const thisKey: string = isUpdate ? "id" : (field.throughTo || linkTablePrimary)
|
const thisKey: string = isUpdate
|
||||||
|
? "id"
|
||||||
|
: field.throughTo || linkTablePrimary
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const otherKey: string = isUpdate ? field.fieldName : (field.throughFrom || tablePrimary)
|
const otherKey: string = isUpdate
|
||||||
|
? field.fieldName
|
||||||
|
: field.throughFrom || tablePrimary
|
||||||
row[key].map((relationship: any) => {
|
row[key].map((relationship: any) => {
|
||||||
// we don't really support composite keys for relationships, this is why [0] is used
|
// we don't really support composite keys for relationships, this is why [0] is used
|
||||||
manyRelationships.push({
|
manyRelationships.push({
|
||||||
|
|
|
@ -23,6 +23,7 @@ async function init() {
|
||||||
MULTI_TENANCY: "",
|
MULTI_TENANCY: "",
|
||||||
DISABLE_ACCOUNT_PORTAL: "",
|
DISABLE_ACCOUNT_PORTAL: "",
|
||||||
ACCOUNT_PORTAL_URL: "http://localhost:10001",
|
ACCOUNT_PORTAL_URL: "http://localhost:10001",
|
||||||
|
ACCOUNT_PORTAL_API_KEY: "budibase",
|
||||||
PLATFORM_URL: "http://localhost:10000",
|
PLATFORM_URL: "http://localhost:10000",
|
||||||
}
|
}
|
||||||
let envFile = ""
|
let envFile = ""
|
||||||
|
|
|
@ -3,6 +3,7 @@ const controller = require("../../controllers/global/users")
|
||||||
const joiValidator = require("../../../middleware/joi-validator")
|
const joiValidator = require("../../../middleware/joi-validator")
|
||||||
const adminOnly = require("../../../middleware/adminOnly")
|
const adminOnly = require("../../../middleware/adminOnly")
|
||||||
const Joi = require("joi")
|
const Joi = require("joi")
|
||||||
|
const cloudRestricted = require("../../../middleware/cloudRestricted")
|
||||||
|
|
||||||
const router = Router()
|
const router = Router()
|
||||||
|
|
||||||
|
@ -90,6 +91,7 @@ router
|
||||||
)
|
)
|
||||||
.post(
|
.post(
|
||||||
"/api/global/users/init",
|
"/api/global/users/init",
|
||||||
|
cloudRestricted,
|
||||||
buildAdminInitValidation(),
|
buildAdminInitValidation(),
|
||||||
controller.adminUser
|
controller.adminUser
|
||||||
)
|
)
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
const env = require("../environment")
|
||||||
|
const { Headers } = require("@budibase/auth").constants
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a restricted endpoint in the cloud.
|
||||||
|
* Ensure that the correct API key has been supplied.
|
||||||
|
*/
|
||||||
|
module.exports = async (ctx, next) => {
|
||||||
|
if (!env.SELF_HOSTED) {
|
||||||
|
const apiKey = ctx.request.headers[Headers.API_KEY]
|
||||||
|
if (apiKey !== env.INTERNAL_API_KEY) {
|
||||||
|
ctx.throw(403, "Unauthorized")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return next()
|
||||||
|
}
|
Loading…
Reference in New Issue