2021-04-09 16:11:49 +02:00
|
|
|
const fetch = require("node-fetch")
|
|
|
|
const env = require("../environment")
|
|
|
|
const { checkSlashesInUrl } = require("./index")
|
2022-01-31 18:42:51 +01:00
|
|
|
const { getProdAppID } = require("@budibase/backend-core/db")
|
2021-10-07 16:49:26 +02:00
|
|
|
const { updateAppRole } = require("./global")
|
2022-11-16 18:24:13 +01:00
|
|
|
const { Header } = require("@budibase/backend-core/constants")
|
2022-01-10 20:33:00 +01:00
|
|
|
const { getTenantId, isTenantIdSet } = require("@budibase/backend-core/tenancy")
|
2021-04-09 16:11:49 +02:00
|
|
|
|
2021-08-05 10:59:08 +02:00
|
|
|
function request(ctx, request) {
|
2021-04-09 16:11:49 +02:00
|
|
|
if (!request.headers) {
|
|
|
|
request.headers = {}
|
|
|
|
}
|
2021-08-05 10:59:08 +02:00
|
|
|
if (!ctx) {
|
2022-11-16 18:23:12 +01:00
|
|
|
request.headers[Header.API_KEY] = env.INTERNAL_API_KEY
|
2021-08-05 10:59:08 +02:00
|
|
|
if (isTenantIdSet()) {
|
2022-11-16 18:23:12 +01:00
|
|
|
request.headers[Header.TENANT_ID] = getTenantId()
|
2021-08-05 10:59:08 +02:00
|
|
|
}
|
2021-06-04 13:13:29 +02:00
|
|
|
}
|
2021-05-10 14:18:05 +02:00
|
|
|
if (request.body && Object.keys(request.body).length > 0) {
|
2021-04-09 16:11:49 +02:00
|
|
|
request.headers["Content-Type"] = "application/json"
|
|
|
|
request.body =
|
|
|
|
typeof request.body === "object"
|
|
|
|
? JSON.stringify(request.body)
|
|
|
|
: request.body
|
2021-05-10 14:18:05 +02:00
|
|
|
} else {
|
|
|
|
delete request.body
|
2021-04-09 16:11:49 +02:00
|
|
|
}
|
2021-05-11 13:02:29 +02:00
|
|
|
if (ctx && ctx.headers) {
|
2022-02-23 19:31:32 +01:00
|
|
|
request.headers = ctx.headers
|
2021-04-09 18:33:21 +02:00
|
|
|
}
|
2021-04-09 16:11:49 +02:00
|
|
|
return request
|
|
|
|
}
|
|
|
|
|
2022-02-25 20:00:12 +01:00
|
|
|
async function checkResponse(response, errorMsg, { ctx } = {}) {
|
|
|
|
if (response.status !== 200) {
|
|
|
|
let error
|
|
|
|
try {
|
|
|
|
error = await response.json()
|
|
|
|
} catch (err) {
|
|
|
|
error = await response.text()
|
|
|
|
}
|
2022-02-25 20:01:17 +01:00
|
|
|
const msg = `Unable to ${errorMsg} - ${
|
|
|
|
error.message ? error.message : error
|
|
|
|
}`
|
2022-02-25 20:00:12 +01:00
|
|
|
if (ctx) {
|
|
|
|
ctx.throw(400, msg)
|
|
|
|
} else {
|
|
|
|
throw msg
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return response.json()
|
|
|
|
}
|
|
|
|
|
2021-04-15 16:57:55 +02:00
|
|
|
exports.request = request
|
|
|
|
|
2021-08-05 10:59:08 +02:00
|
|
|
// have to pass in the tenant ID as this could be coming from an automation
|
2022-09-21 16:58:04 +02:00
|
|
|
exports.sendSmtpEmail = async (
|
|
|
|
to,
|
|
|
|
from,
|
|
|
|
subject,
|
|
|
|
contents,
|
|
|
|
cc,
|
|
|
|
bcc,
|
|
|
|
automation
|
|
|
|
) => {
|
2021-08-05 10:59:08 +02:00
|
|
|
// tenant ID will be set in header
|
2021-05-11 13:02:29 +02:00
|
|
|
const response = await fetch(
|
2021-08-05 10:59:08 +02:00
|
|
|
checkSlashesInUrl(env.WORKER_URL + `/api/global/email/send`),
|
2021-05-11 13:02:29 +02:00
|
|
|
request(null, {
|
|
|
|
method: "POST",
|
2021-05-11 16:08:59 +02:00
|
|
|
body: {
|
|
|
|
email: to,
|
|
|
|
from,
|
|
|
|
contents,
|
|
|
|
subject,
|
2022-09-21 16:58:04 +02:00
|
|
|
cc,
|
|
|
|
bcc,
|
2021-05-11 16:08:59 +02:00
|
|
|
purpose: "custom",
|
2021-09-27 17:28:39 +02:00
|
|
|
automation,
|
2021-05-11 16:08:59 +02:00
|
|
|
},
|
2021-05-11 13:02:29 +02:00
|
|
|
})
|
|
|
|
)
|
2022-02-25 20:00:12 +01:00
|
|
|
return checkResponse(response, "send email")
|
2021-05-11 13:02:29 +02:00
|
|
|
}
|
|
|
|
|
2021-05-27 15:53:41 +02:00
|
|
|
exports.getGlobalSelf = async (ctx, appId = null) => {
|
2022-02-14 19:11:35 +01:00
|
|
|
const endpoint = `/api/global/self`
|
2021-05-19 16:09:57 +02:00
|
|
|
const response = await fetch(
|
|
|
|
checkSlashesInUrl(env.WORKER_URL + endpoint),
|
2021-06-04 13:13:29 +02:00
|
|
|
// we don't want to use API key when getting self
|
2021-08-05 10:59:08 +02:00
|
|
|
request(ctx, { method: "GET" })
|
2021-05-19 16:09:57 +02:00
|
|
|
)
|
2022-02-25 20:00:12 +01:00
|
|
|
let json = await checkResponse(response, "get self globally", { ctx })
|
2021-05-27 15:53:41 +02:00
|
|
|
if (appId) {
|
2022-01-27 19:18:31 +01:00
|
|
|
json = updateAppRole(json)
|
2021-05-27 15:53:41 +02:00
|
|
|
}
|
2021-05-19 16:09:57 +02:00
|
|
|
return json
|
|
|
|
}
|
|
|
|
|
2021-08-05 10:59:08 +02:00
|
|
|
exports.removeAppFromUserRoles = async (ctx, appId) => {
|
2022-01-31 18:42:51 +01:00
|
|
|
const prodAppId = getProdAppID(appId)
|
2021-06-01 16:58:40 +02:00
|
|
|
const response = await fetch(
|
2022-01-31 18:42:51 +01:00
|
|
|
checkSlashesInUrl(env.WORKER_URL + `/api/global/roles/${prodAppId}`),
|
2021-08-05 10:59:08 +02:00
|
|
|
request(ctx, {
|
2021-06-01 16:58:40 +02:00
|
|
|
method: "DELETE",
|
|
|
|
})
|
|
|
|
)
|
2022-02-25 20:00:12 +01:00
|
|
|
return checkResponse(response, "remove app role")
|
|
|
|
}
|
|
|
|
|
|
|
|
exports.allGlobalUsers = async ctx => {
|
|
|
|
const response = await fetch(
|
|
|
|
checkSlashesInUrl(env.WORKER_URL + "/api/global/users"),
|
|
|
|
// we don't want to use API key when getting self
|
|
|
|
request(ctx, { method: "GET" })
|
|
|
|
)
|
|
|
|
return checkResponse(response, "get users", { ctx })
|
|
|
|
}
|
|
|
|
|
|
|
|
exports.saveGlobalUser = async ctx => {
|
|
|
|
const response = await fetch(
|
|
|
|
checkSlashesInUrl(env.WORKER_URL + "/api/global/users"),
|
|
|
|
// we don't want to use API key when getting self
|
|
|
|
request(ctx, { method: "POST", body: ctx.request.body })
|
|
|
|
)
|
|
|
|
return checkResponse(response, "save user", { ctx })
|
|
|
|
}
|
|
|
|
|
|
|
|
exports.deleteGlobalUser = async ctx => {
|
|
|
|
const response = await fetch(
|
2022-02-25 20:01:17 +01:00
|
|
|
checkSlashesInUrl(
|
|
|
|
env.WORKER_URL + `/api/global/users/${ctx.params.userId}`
|
|
|
|
),
|
2022-02-25 20:00:12 +01:00
|
|
|
// we don't want to use API key when getting self
|
|
|
|
request(ctx, { method: "DELETE" })
|
|
|
|
)
|
|
|
|
return checkResponse(response, "delete user", { ctx, body: ctx.request.body })
|
|
|
|
}
|
|
|
|
|
|
|
|
exports.readGlobalUser = async ctx => {
|
|
|
|
const response = await fetch(
|
2022-02-25 20:01:17 +01:00
|
|
|
checkSlashesInUrl(
|
|
|
|
env.WORKER_URL + `/api/global/users/${ctx.params.userId}`
|
|
|
|
),
|
2022-02-25 20:00:12 +01:00
|
|
|
// we don't want to use API key when getting self
|
|
|
|
request(ctx, { method: "GET" })
|
|
|
|
)
|
|
|
|
return checkResponse(response, "get user", { ctx })
|
2021-04-09 16:11:49 +02:00
|
|
|
}
|
2022-06-30 12:28:52 +02:00
|
|
|
|
|
|
|
exports.createAdminUser = async (email, password, tenantId) => {
|
|
|
|
const response = await fetch(
|
|
|
|
checkSlashesInUrl(env.WORKER_URL + "/api/global/users/init"),
|
|
|
|
request(null, { method: "POST", body: { email, password, tenantId } })
|
|
|
|
)
|
|
|
|
return checkResponse(response, "create admin user")
|
|
|
|
}
|
|
|
|
|
|
|
|
exports.getChecklist = async () => {
|
|
|
|
const response = await fetch(
|
|
|
|
checkSlashesInUrl(env.WORKER_URL + "/api/global/configs/checklist"),
|
|
|
|
request(null, { method: "GET" })
|
|
|
|
)
|
|
|
|
return checkResponse(response, "get checklist")
|
|
|
|
}
|
2022-09-05 19:28:53 +02:00
|
|
|
|
|
|
|
exports.generateApiKey = async userId => {
|
|
|
|
const response = await fetch(
|
|
|
|
checkSlashesInUrl(env.WORKER_URL + "/api/global/self/api_key"),
|
|
|
|
request(null, { method: "POST", body: { userId } })
|
|
|
|
)
|
|
|
|
return checkResponse(response, "generate API key")
|
|
|
|
}
|