exposing _master database operations to builder
This commit is contained in:
parent
14ad487d92
commit
f8e71d0e96
|
@ -0,0 +1,12 @@
|
||||||
|
const StatusCodes = require("../../utilities/statusCodes")
|
||||||
|
const { getRecordKey } = require("./helpers")
|
||||||
|
|
||||||
|
module.exports = async ctx => {
|
||||||
|
const indexkey = getRecordKey(ctx.params.appname, ctx.request.path)
|
||||||
|
ctx.body = await ctx.instance.indexApi.aggregates(indexkey, {
|
||||||
|
rangeStartParams: ctx.request.body.rangeStartParams,
|
||||||
|
rangeEndParams: ctx.request.body.rangeEndParams,
|
||||||
|
searchPhrase: ctx.request.body.searchPhrase,
|
||||||
|
})
|
||||||
|
ctx.response.status = StatusCodes.OK
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
const send = require("koa-send")
|
||||||
|
|
||||||
|
module.exports = async (ctx, next) => {
|
||||||
|
const path = ctx.path.replace(`/${ctx.params.appname}`, "")
|
||||||
|
|
||||||
|
if (path.startsWith("/api/")) {
|
||||||
|
await next()
|
||||||
|
} else if (path.startsWith("/_shared/")) {
|
||||||
|
await send(ctx, path.replace(`/_shared/`, ""), { root: ctx.sharedPath })
|
||||||
|
} else if (
|
||||||
|
path.endsWith(".js") ||
|
||||||
|
path.endsWith(".map") ||
|
||||||
|
path.endsWith(".css")
|
||||||
|
) {
|
||||||
|
await send(ctx, path, { root: ctx.publicPath })
|
||||||
|
} else {
|
||||||
|
await send(ctx, "/index.html", { root: ctx.publicPath })
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
const StatusCodes = require("../../utilities/statusCodes")
|
||||||
|
|
||||||
|
module.exports = async ctx => {
|
||||||
|
const user = await ctx.master.authenticate(
|
||||||
|
ctx.sessionId,
|
||||||
|
ctx.params.appname,
|
||||||
|
ctx.request.body.username,
|
||||||
|
ctx.request.body.password
|
||||||
|
)
|
||||||
|
if (!user) {
|
||||||
|
ctx.throw(StatusCodes.UNAUTHORIZED, "invalid username or password")
|
||||||
|
}
|
||||||
|
ctx.body = user.user_json
|
||||||
|
ctx.response.status = StatusCodes.OK
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
const StatusCodes = require("../../utilities/statusCodes")
|
||||||
|
|
||||||
|
module.exports = async ctx => {
|
||||||
|
await ctx.instance.authApi.changeMyPassword(
|
||||||
|
ctx.request.body.currentPassword,
|
||||||
|
ctx.request.body.newPassword
|
||||||
|
)
|
||||||
|
ctx.response.status = StatusCodes.OK
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
const StatusCodes = require("../../utilities/statusCodes")
|
||||||
|
|
||||||
|
module.exports = async ctx => {
|
||||||
|
const instanceApi = await ctx.master.getFullAccessInstanceApiForUsername(
|
||||||
|
ctx.params.appname,
|
||||||
|
ctx.request.body.username
|
||||||
|
)
|
||||||
|
|
||||||
|
if (!instanceApi) {
|
||||||
|
ctx.request.status = StatusCodes.OK
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
await instanceApi.authApi.createTemporaryAccess(ctx.request.body.username)
|
||||||
|
|
||||||
|
ctx.response.status = StatusCodes.OK
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
const StatusCodes = require("../../utilities/statusCodes")
|
||||||
|
|
||||||
|
module.exports = async ctx => {
|
||||||
|
await ctx.instance.authApi.createUser(
|
||||||
|
ctx.request.body.user,
|
||||||
|
ctx.request.body.password
|
||||||
|
)
|
||||||
|
|
||||||
|
ctx.response.status = StatusCodes.OK
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
const StatusCodes = require("../../utilities/statusCodes")
|
||||||
|
const { getRecordKey } = require("./helpers")
|
||||||
|
|
||||||
|
module.exports = async ctx => {
|
||||||
|
await ctx.instance.recordApi.delete(
|
||||||
|
getRecordKey(ctx.params.appname, ctx.request.path)
|
||||||
|
)
|
||||||
|
ctx.response.status = StatusCodes.OK
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
const StatusCodes = require("../../utilities/statusCodes")
|
||||||
|
|
||||||
|
module.exports = async ctx => {
|
||||||
|
await ctx.instance.authApi.disableUser(ctx.request.body.username)
|
||||||
|
|
||||||
|
await ctx.master.removeSessionsForUser(
|
||||||
|
ctx.params.appname,
|
||||||
|
ctx.request.body.username
|
||||||
|
)
|
||||||
|
ctx.response.status = StatusCodes.OK
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
const StatusCodes = require("../../utilities/statusCodes")
|
||||||
|
|
||||||
|
module.exports = async ctx => {
|
||||||
|
await ctx.instance.authApi.enableUser(ctx.request.body.username)
|
||||||
|
ctx.response.status = StatusCodes.OK
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
const StatusCodes = require("../../utilities/statusCodes")
|
||||||
|
|
||||||
|
module.exports = async ctx => {
|
||||||
|
ctx.body = await ctx.instance.actionApi.execute(
|
||||||
|
ctx.request.body.actionname,
|
||||||
|
ctx.request.body.parameters
|
||||||
|
)
|
||||||
|
ctx.response.status = StatusCodes.OK
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
const StatusCodes = require("../../utilities/statusCodes")
|
||||||
|
|
||||||
|
module.exports = async ctx => {
|
||||||
|
ctx.body = await ctx.instance.authApi.getAccessLevels()
|
||||||
|
ctx.response.status = StatusCodes.OK
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
const StatusCodes = require("../../utilities/statusCodes")
|
||||||
|
const { getRecordKey } = require("./helpers")
|
||||||
|
|
||||||
|
module.exports = async ctx => {
|
||||||
|
try {
|
||||||
|
ctx.body = await ctx.instance.recordApi.load(
|
||||||
|
getRecordKey(ctx.params.appname, ctx.request.path)
|
||||||
|
)
|
||||||
|
ctx.response.status = StatusCodes.OK
|
||||||
|
} catch (e) {
|
||||||
|
// need to be catching for 404s here
|
||||||
|
ctx.response.status = StatusCodes.INTERAL_ERROR
|
||||||
|
ctx.response.body = e.message
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
const StatusCodes = require("../../utilities/statusCodes")
|
||||||
|
|
||||||
|
module.exports = async ctx => {
|
||||||
|
ctx.body = await ctx.instance.authApi.getUsers()
|
||||||
|
ctx.response.status = StatusCodes.OK
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
exports.getRecordKey = (appname, wholePath) =>
|
||||||
|
wholePath
|
||||||
|
.replace(`/${appname}/api/files/`, "")
|
||||||
|
.replace(`/${appname}/api/lookup_field/`, "")
|
||||||
|
.replace(`/${appname}/api/record/`, "")
|
||||||
|
.replace(`/${appname}/api/listRecords/`, "")
|
||||||
|
.replace(`/${appname}/api/aggregates/`, "")
|
|
@ -0,0 +1,43 @@
|
||||||
|
const authenticate = require("./authenticate")
|
||||||
|
const setPasswordFromTemporaryCode = require("./setPasswordFromTemporaryCode")
|
||||||
|
const createTemporaryAccess = require("./createTemporaryAccess")
|
||||||
|
const appDefault = require("./appDefault")
|
||||||
|
const changeMyPassword = require("./changeMyPassword")
|
||||||
|
const executeAction = require("./executeAction")
|
||||||
|
const createUser = require("./createUser")
|
||||||
|
const enableUser = require("./enableUser")
|
||||||
|
const disableUser = require("./disableUser")
|
||||||
|
const getUsers = require("./getUsers")
|
||||||
|
const getAccessLevels = require("./getAccessLevels")
|
||||||
|
const listRecordsGet = require("./listRecordsGet")
|
||||||
|
const listRecordsPost = require("./listRecordsPost")
|
||||||
|
const aggregatesPost = require("./aggregatesPost")
|
||||||
|
const postFiles = require("./postFiles")
|
||||||
|
const saveRecord = require("./saveRecord")
|
||||||
|
const lookupField = require("./lookupField")
|
||||||
|
const getRecord = require("./getRecord")
|
||||||
|
const deleteRecord = require("./deleteRecord")
|
||||||
|
const saveAppHierarchy = require("./saveAppHierarchy")
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
authenticate,
|
||||||
|
setPasswordFromTemporaryCode,
|
||||||
|
createTemporaryAccess,
|
||||||
|
appDefault,
|
||||||
|
changeMyPassword,
|
||||||
|
executeAction,
|
||||||
|
createUser,
|
||||||
|
enableUser,
|
||||||
|
disableUser,
|
||||||
|
getUsers,
|
||||||
|
getAccessLevels,
|
||||||
|
listRecordsGet,
|
||||||
|
listRecordsPost,
|
||||||
|
aggregatesPost,
|
||||||
|
postFiles,
|
||||||
|
saveRecord,
|
||||||
|
lookupField,
|
||||||
|
getRecord,
|
||||||
|
deleteRecord,
|
||||||
|
saveAppHierarchy,
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
const StatusCodes = require("../../utilities/statusCodes")
|
||||||
|
const { getRecordKey } = require("./helpers")
|
||||||
|
|
||||||
|
module.exports = async ctx => {
|
||||||
|
const indexkey = getRecordKey(ctx.params.appname, ctx.request.path)
|
||||||
|
ctx.body = await ctx.instance.indexApi.listItems(indexkey)
|
||||||
|
ctx.response.status = StatusCodes.OK
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
const StatusCodes = require("../../utilities/statusCodes")
|
||||||
|
const { getRecordKey } = require("./helpers")
|
||||||
|
|
||||||
|
module.exports = async ctx => {
|
||||||
|
const indexkey = getRecordKey(ctx.params.appname, ctx.request.path)
|
||||||
|
ctx.body = await ctx.instance.indexApi.listItems(indexkey, {
|
||||||
|
rangeStartParams: ctx.request.body.rangeStartParams,
|
||||||
|
rangeEndParams: ctx.request.body.rangeEndParams,
|
||||||
|
searchPhrase: ctx.request.body.searchPhrase,
|
||||||
|
})
|
||||||
|
ctx.response.status = StatusCodes.OK
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
const StatusCodes = require("../../utilities/statusCodes")
|
||||||
|
const { getRecordKey } = require("./helpers")
|
||||||
|
|
||||||
|
module.exports = async ctx => {
|
||||||
|
const recordKey = getRecordKey(ctx.params.appname, ctx.request.path)
|
||||||
|
const fields = ctx.query.fields.split(",")
|
||||||
|
const recordContext = await ctx.instance.recordApi.getContext(recordKey)
|
||||||
|
const allContext = []
|
||||||
|
for (let field of fields) {
|
||||||
|
allContext.push(await recordContext.referenceOptions(field))
|
||||||
|
}
|
||||||
|
ctx.body = allContext
|
||||||
|
ctx.response.status = StatusCodes.OK
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
const StatusCodes = require("../../utilities/statusCodes")
|
||||||
|
const { getRecordKey } = require("./helpers")
|
||||||
|
const fs = require("fs")
|
||||||
|
|
||||||
|
module.exports = async ctx => {
|
||||||
|
const file = ctx.request.files.file
|
||||||
|
ctx.body = await ctx.instance.recordApi.uploadFile(
|
||||||
|
getRecordKey(ctx.params.appname, ctx.request.path),
|
||||||
|
fs.createReadStream(file.path),
|
||||||
|
file.name
|
||||||
|
)
|
||||||
|
ctx.response.status = StatusCodes.OK
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
const StatusCodes = require("../../utilities/statusCodes")
|
||||||
|
|
||||||
|
module.exports = async ctx => {
|
||||||
|
ctx.body = await ctx.instance.templateApi.saveApplicationHierarchy(ctx.body)
|
||||||
|
ctx.response.status = StatusCodes.OK
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
const StatusCodes = require("../../utilities/statusCodes")
|
||||||
|
|
||||||
|
module.exports = async ctx => {
|
||||||
|
ctx.body = await ctx.instance.recordApi.save(ctx.request.body)
|
||||||
|
ctx.response.status = StatusCodes.OK
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
const StatusCodes = require("../../utilities/statusCodes")
|
||||||
|
|
||||||
|
module.exports = async ctx => {
|
||||||
|
const instanceApi = await ctx.master.getFullAccessInstanceApiForUsername(
|
||||||
|
ctx.params.appname,
|
||||||
|
ctx.request.body.username
|
||||||
|
)
|
||||||
|
|
||||||
|
if (!instanceApi) {
|
||||||
|
ctx.request.status = StatusCodes.OK
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
await instanceApi.authApi.setPasswordFromTemporaryCode(
|
||||||
|
ctx.request.body.tempCode,
|
||||||
|
ctx.request.body.newPassword
|
||||||
|
)
|
||||||
|
|
||||||
|
ctx.response.status = StatusCodes.OK
|
||||||
|
}
|
|
@ -1,9 +1,10 @@
|
||||||
const Router = require("@koa/router")
|
const Router = require("@koa/router")
|
||||||
const session = require("./session")
|
const session = require("./session")
|
||||||
const StatusCodes = require("../utilities/statusCodes")
|
const StatusCodes = require("../utilities/statusCodes")
|
||||||
const fs = require("fs")
|
|
||||||
const { resolve } = require("path")
|
const { resolve } = require("path")
|
||||||
const send = require("koa-send")
|
const send = require("koa-send")
|
||||||
|
const routeHandlers = require("./routeHandlers")
|
||||||
|
|
||||||
const {
|
const {
|
||||||
getPackageForBuilder,
|
getPackageForBuilder,
|
||||||
getComponentDefinitions,
|
getComponentDefinitions,
|
||||||
|
@ -38,6 +39,25 @@ module.exports = (config, app) => {
|
||||||
ctx.set("x-bbappname", appname)
|
ctx.set("x-bbappname", appname)
|
||||||
|
|
||||||
if (appname === "_builder") {
|
if (appname === "_builder") {
|
||||||
|
if (!config.dev) {
|
||||||
|
ctx.response.status = StatusCodes.FORBIDDEN
|
||||||
|
ctx.body = "run in dev mode to access builder"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctx.path.startsWith("/_builder/instance/_master")) {
|
||||||
|
ctx.instance = ctx.master.getFullAccessApiForMaster()
|
||||||
|
ctx.isAuthenticated = !!ctx.instance
|
||||||
|
} else if (ctx.path.startsWith("/_builder/instance")) {
|
||||||
|
const builderAppName = pathParts[3]
|
||||||
|
const instanceId = pathParts[4]
|
||||||
|
ctx.instance = ctx.master.getFullAccessApiForInstanceId(
|
||||||
|
builderAppName,
|
||||||
|
instanceId
|
||||||
|
).bbInstance
|
||||||
|
ctx.isAuthenticated = !!ctx.instance
|
||||||
|
}
|
||||||
|
|
||||||
await next()
|
await next()
|
||||||
} else {
|
} else {
|
||||||
const instance = await ctx.master.getInstanceApiForSession(
|
const instance = await ctx.master.getInstanceApiForSession(
|
||||||
|
@ -54,12 +74,6 @@ module.exports = (config, app) => {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.get("/_builder", async ctx => {
|
.get("/_builder", async ctx => {
|
||||||
if (!config.dev) {
|
|
||||||
ctx.response.status = StatusCodes.FORBIDDEN
|
|
||||||
ctx.body = "run in dev mode to access builder"
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
await send(ctx, "/index.html", { root: builderPath })
|
await send(ctx, "/index.html", { root: builderPath })
|
||||||
})
|
})
|
||||||
.get("/_builder/:appname/componentlibrary", async ctx => {
|
.get("/_builder/:appname/componentlibrary", async ctx => {
|
||||||
|
@ -71,12 +85,6 @@ module.exports = (config, app) => {
|
||||||
await send(ctx, info.components._lib || "index.js", { root: info.libDir })
|
await send(ctx, info.components._lib || "index.js", { root: info.libDir })
|
||||||
})
|
})
|
||||||
.get("/_builder/*", async (ctx, next) => {
|
.get("/_builder/*", async (ctx, next) => {
|
||||||
if (!config.dev) {
|
|
||||||
ctx.response.status = StatusCodes.FORBIDDEN
|
|
||||||
ctx.body = "run in dev mode to access builder"
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const path = ctx.path.replace("/_builder", "")
|
const path = ctx.path.replace("/_builder", "")
|
||||||
|
|
||||||
if (path.startsWith("/api/")) {
|
if (path.startsWith("/api/")) {
|
||||||
|
@ -85,58 +93,36 @@ module.exports = (config, app) => {
|
||||||
await send(ctx, path, { root: builderPath })
|
await send(ctx, path, { root: builderPath })
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.post("/:appname/api/authenticate", async ctx => {
|
.post("/:appname/api/authenticate", routeHandlers.authenticate)
|
||||||
const user = await ctx.master.authenticate(
|
.post(
|
||||||
ctx.sessionId,
|
"/_builder/instance/:appname/:instanceid/api/authenticate",
|
||||||
ctx.params.appname,
|
routeHandlers.authenticate
|
||||||
ctx.request.body.username,
|
)
|
||||||
ctx.request.body.password
|
.post(
|
||||||
)
|
"/:appname/api/setPasswordFromTemporaryCode",
|
||||||
if (!user) {
|
routeHandlers.setPasswordFromTemporaryCode
|
||||||
ctx.throw(StatusCodes.UNAUTHORIZED, "invalid username or password")
|
)
|
||||||
}
|
.post(
|
||||||
ctx.body = user.user_json
|
"/_builder/instance/:appname/:instanceid/api/setPasswordFromTemporaryCode",
|
||||||
ctx.response.status = StatusCodes.OK
|
routeHandlers.setPasswordFromTemporaryCode
|
||||||
})
|
)
|
||||||
.post("/:appname/api/setPasswordFromTemporaryCode", async ctx => {
|
.post(
|
||||||
const instanceApi = await ctx.master.getFullAccessInstanceApiForUsername(
|
"/:appname/api/createTemporaryAccess",
|
||||||
ctx.params.appname,
|
routeHandlers.createTemporaryAccess
|
||||||
ctx.request.body.username
|
)
|
||||||
)
|
.post(
|
||||||
|
"/_builder/instance/:appname/:instanceid/api/createTemporaryAccess",
|
||||||
if (!instanceApi) {
|
routeHandlers.createTemporaryAccess
|
||||||
ctx.request.status = StatusCodes.OK
|
)
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
await instanceApi.authApi.setPasswordFromTemporaryCode(
|
|
||||||
ctx.request.body.tempCode,
|
|
||||||
ctx.request.body.newPassword
|
|
||||||
)
|
|
||||||
|
|
||||||
ctx.response.status = StatusCodes.OK
|
|
||||||
})
|
|
||||||
.post("/:appname/api/createTemporaryAccess", async ctx => {
|
|
||||||
const instanceApi = await ctx.master.getFullAccessInstanceApiForUsername(
|
|
||||||
ctx.params.appname,
|
|
||||||
ctx.request.body.username
|
|
||||||
)
|
|
||||||
|
|
||||||
if (!instanceApi) {
|
|
||||||
ctx.request.status = StatusCodes.OK
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
await instanceApi.authApi.createTemporaryAccess(ctx.request.body.username)
|
|
||||||
|
|
||||||
ctx.response.status = StatusCodes.OK
|
|
||||||
})
|
|
||||||
.get("/_builder/api/apps", async ctx => {
|
.get("/_builder/api/apps", async ctx => {
|
||||||
ctx.body = await getApps(config, ctx.master)
|
ctx.body = await getApps(config, ctx.master)
|
||||||
ctx.response.status = StatusCodes.OK
|
ctx.response.status = StatusCodes.OK
|
||||||
})
|
})
|
||||||
.get("/_builder/api/:appname/appPackage", async ctx => {
|
.get("/_builder/api/:appname/appPackage", async ctx => {
|
||||||
ctx.body = await getPackageForBuilder(config, ctx.params.appname)
|
const application = await ctx.master.getApplicationWithInstances(
|
||||||
|
ctx.params.appname
|
||||||
|
)
|
||||||
|
ctx.body = await getPackageForBuilder(config, application)
|
||||||
ctx.response.status = StatusCodes.OK
|
ctx.response.status = StatusCodes.OK
|
||||||
})
|
})
|
||||||
.get("/_builder/api/:appname/components", async ctx => {
|
.get("/_builder/api/:appname/components", async ctx => {
|
||||||
|
@ -228,23 +214,9 @@ module.exports = (config, app) => {
|
||||||
.get("/:appname", async ctx => {
|
.get("/:appname", async ctx => {
|
||||||
await send(ctx, "/index.html", { root: ctx.publicPath })
|
await send(ctx, "/index.html", { root: ctx.publicPath })
|
||||||
})
|
})
|
||||||
.get("/:appname/*", async (ctx, next) => {
|
.get("/:appname/*", routeHandlers.appDefault)
|
||||||
const path = ctx.path.replace(`/${ctx.params.appname}`, "")
|
.get("/_builder/instance/:appname/:instanceid/*", routeHandlers.appDefault)
|
||||||
|
// EVERYTHING BELOW HERE REQUIRES AUTHENTICATION
|
||||||
if (path.startsWith("/api/")) {
|
|
||||||
await next()
|
|
||||||
} else if (path.startsWith("/_shared/")) {
|
|
||||||
await send(ctx, path.replace(`/_shared/`, ""), { root: ctx.sharedPath })
|
|
||||||
} else if (
|
|
||||||
path.endsWith(".js") ||
|
|
||||||
path.endsWith(".map") ||
|
|
||||||
path.endsWith(".css")
|
|
||||||
) {
|
|
||||||
await send(ctx, path, { root: ctx.publicPath })
|
|
||||||
} else {
|
|
||||||
await send(ctx, "/index.html", { root: ctx.publicPath })
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.use(async (ctx, next) => {
|
.use(async (ctx, next) => {
|
||||||
if (ctx.isAuthenticated) {
|
if (ctx.isAuthenticated) {
|
||||||
await next()
|
await next()
|
||||||
|
@ -252,147 +224,85 @@ module.exports = (config, app) => {
|
||||||
ctx.response.status = StatusCodes.UNAUTHORIZED
|
ctx.response.status = StatusCodes.UNAUTHORIZED
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.post("/:appname/api/changeMyPassword", async ctx => {
|
.post("/:appname/api/changeMyPassword", routeHandlers.changeMyPassword)
|
||||||
await ctx.instance.authApi.changeMyPassword(
|
.post(
|
||||||
ctx.request.body.currentPassword,
|
"/_builder/instance/:appname/:instanceid/api/changeMyPassword",
|
||||||
ctx.request.body.newPassword
|
routeHandlers.changeMyPassword
|
||||||
)
|
)
|
||||||
ctx.response.status = StatusCodes.OK
|
.post(
|
||||||
})
|
"/:appname/api/executeAction/:actionname",
|
||||||
.post("/:appname/api/changeMyPassword", async ctx => {
|
routeHandlers.executeAction
|
||||||
await ctx.instance.authApi.changeMyPassword(
|
)
|
||||||
ctx.request.body.currentPassword,
|
.post(
|
||||||
ctx.request.body.newPassword
|
"/_builder/instance/:appname/:instanceid/api/executeAction/:actionname",
|
||||||
)
|
routeHandlers.executeAction
|
||||||
ctx.response.status = StatusCodes.OK
|
)
|
||||||
})
|
.post("/:appname/api/createUser", routeHandlers.createUser)
|
||||||
.post("/:appname/api/executeAction/:actionname", async ctx => {
|
.post(
|
||||||
ctx.body = await ctx.instance.actionApi.execute(
|
"/_builder/instance/:appname/:instanceid/api/createUser",
|
||||||
ctx.request.body.actionname,
|
routeHandlers.createUser
|
||||||
ctx.request.body.parameters
|
)
|
||||||
)
|
.post("/:appname/api/enableUser", routeHandlers.enableUser)
|
||||||
ctx.response.status = StatusCodes.OK
|
.post(
|
||||||
})
|
"/_builder/instance/:appname/:instanceid/api/enableUser",
|
||||||
.post("/:appname/api/createUser", async ctx => {
|
routeHandlers.enableUser
|
||||||
await ctx.instance.authApi.createUser(
|
)
|
||||||
ctx.request.body.user,
|
.post("/:appname/api/disableUser", routeHandlers.disableUser)
|
||||||
ctx.request.body.password
|
.post(
|
||||||
)
|
"/_builder/instance/:appname/:instanceid/api/disableUser",
|
||||||
|
routeHandlers.disableUser
|
||||||
ctx.response.status = StatusCodes.OK
|
)
|
||||||
})
|
.get("/:appname/api/users", routeHandlers.getUsers)
|
||||||
.post("/:appname/api/enableUser", async ctx => {
|
.get(
|
||||||
await ctx.instance.authApi.enableUser(ctx.request.body.username)
|
"/_builder/instance/:appname/:instanceid/api/users",
|
||||||
ctx.response.status = StatusCodes.OK
|
routeHandlers.getUsers
|
||||||
})
|
)
|
||||||
.post("/:appname/api/disableUser", async ctx => {
|
.get("/:appname/api/accessLevels", routeHandlers.getAccessLevels)
|
||||||
await ctx.instance.authApi.disableUser(ctx.request.body.username)
|
.get(
|
||||||
|
"/_builder/instance/:appname/:instanceid/api/accessLevels",
|
||||||
await ctx.master.removeSessionsForUser(
|
routeHandlers.getAccessLevels
|
||||||
ctx.params.appname,
|
)
|
||||||
ctx.request.body.username
|
.get("/:appname/api/listRecords/*", routeHandlers.listRecordsGet)
|
||||||
)
|
.get(
|
||||||
ctx.response.status = StatusCodes.OK
|
"/_builder/instance/:appname/:instanceid/api/listRecords/*",
|
||||||
})
|
routeHandlers.listRecordsGet
|
||||||
.get("/:appname/api/users", async ctx => {
|
)
|
||||||
ctx.body = await ctx.instance.authApi.getUsers()
|
.post("/:appname/api/listRecords/*", routeHandlers.listRecordsPost)
|
||||||
ctx.response.status = StatusCodes.OK
|
.post(
|
||||||
})
|
"/_builder/instance/:appname/:instanceid/api/listRecords/*",
|
||||||
.get("/:appname/api/accessLevels", async ctx => {
|
routeHandlers.listRecordsPost
|
||||||
ctx.body = await ctx.instance.authApi.getAccessLevels()
|
)
|
||||||
ctx.response.status = StatusCodes.OK
|
.post("/:appname/api/aggregates/*", routeHandlers.aggregatesPost)
|
||||||
})
|
.post(
|
||||||
.get("/:appname/api/listRecords/*", async ctx => {
|
"/_builder/instance/:appname/:instanceid/api/aggregates/*",
|
||||||
const indexkey = getRecordKey(ctx.params.appname, ctx.request.path)
|
routeHandlers.aggregatesPost
|
||||||
ctx.body = await ctx.instance.indexApi.listItems(indexkey)
|
)
|
||||||
ctx.response.status = StatusCodes.OK
|
.post("/:appname/api/files/*", routeHandlers.postFiles)
|
||||||
})
|
.post(
|
||||||
.post("/:appname/api/listRecords/*", async ctx => {
|
"/_builder/instance/:appname/:instanceid/api/files/*",
|
||||||
const indexkey = getRecordKey(ctx.params.appname, ctx.request.path)
|
routeHandlers.postFiles
|
||||||
ctx.body = await ctx.instance.indexApi.listItems(indexkey, {
|
)
|
||||||
rangeStartParams: ctx.request.body.rangeStartParams,
|
.post("/:appname/api/record/*", routeHandlers.saveRecord)
|
||||||
rangeEndParams: ctx.request.body.rangeEndParams,
|
.post(
|
||||||
searchPhrase: ctx.request.body.searchPhrase,
|
"/_builder/instance/:appname/:instanceid/api/record/*",
|
||||||
})
|
routeHandlers.saveRecord
|
||||||
ctx.response.status = StatusCodes.OK
|
)
|
||||||
})
|
.get("/:appname/api/lookup_field/*", routeHandlers.lookupField)
|
||||||
.post("/:appname/api/aggregates/*", async ctx => {
|
.get(
|
||||||
const indexkey = getRecordKey(ctx.params.appname, ctx.request.path)
|
"/_builder/instance/:appname/:instanceid/api/lookup_field/*",
|
||||||
ctx.body = await ctx.instance.indexApi.aggregates(indexkey, {
|
routeHandlers.lookupField
|
||||||
rangeStartParams: ctx.request.body.rangeStartParams,
|
)
|
||||||
rangeEndParams: ctx.request.body.rangeEndParams,
|
.get("/:appname/api/record/*", routeHandlers.getRecord)
|
||||||
searchPhrase: ctx.request.body.searchPhrase,
|
.get(
|
||||||
})
|
"/_builder/instance/:appname/:instanceid/api/record/*",
|
||||||
ctx.response.status = StatusCodes.OK
|
routeHandlers.getRecord
|
||||||
})
|
)
|
||||||
.post("/:appname/api/files/*", async ctx => {
|
.del("/:appname/api/record/*", routeHandlers.deleteRecord)
|
||||||
const file = ctx.request.files.file
|
.del(
|
||||||
ctx.body = await ctx.instance.recordApi.uploadFile(
|
"/_builder/instance/:appname/:instanceid/api/record/*",
|
||||||
getRecordKey(ctx.params.appname, ctx.request.path),
|
routeHandlers.deleteRecord
|
||||||
fs.createReadStream(file.path),
|
)
|
||||||
file.name
|
.post("/:appname/api/apphierarchy", routeHandlers.saveAppHierarchy)
|
||||||
)
|
|
||||||
ctx.response.status = StatusCodes.OK
|
|
||||||
})
|
|
||||||
.post("/:appname/api/record/*", async ctx => {
|
|
||||||
ctx.body = await ctx.instance.recordApi.save(ctx.request.body)
|
|
||||||
ctx.response.status = StatusCodes.OK
|
|
||||||
})
|
|
||||||
.get("/:appname/api/lookup_field/*", async ctx => {
|
|
||||||
const recordKey = getRecordKey(ctx.params.appname, ctx.request.path)
|
|
||||||
const fields = ctx.query.fields.split(",")
|
|
||||||
const recordContext = await ctx.instance.recordApi.getContext(recordKey)
|
|
||||||
const allContext = []
|
|
||||||
for (let field of fields) {
|
|
||||||
allContext.push(await recordContext.referenceOptions(field))
|
|
||||||
}
|
|
||||||
ctx.body = allContext
|
|
||||||
ctx.response.status = StatusCodes.OK
|
|
||||||
})
|
|
||||||
.get("/:appname/api/record/*", async ctx => {
|
|
||||||
try {
|
|
||||||
ctx.body = await ctx.instance.recordApi.load(
|
|
||||||
getRecordKey(ctx.params.appname, ctx.request.path)
|
|
||||||
)
|
|
||||||
ctx.response.status = StatusCodes.OK
|
|
||||||
} catch (e) {
|
|
||||||
// need to be catching for 404s here
|
|
||||||
ctx.response.status = StatusCodes.INTERAL_ERROR
|
|
||||||
ctx.response.body = e.message
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.del("/:appname/api/record/*", async ctx => {
|
|
||||||
await ctx.instance.recordApi.delete(
|
|
||||||
getRecordKey(ctx.params.appname, ctx.request.path)
|
|
||||||
)
|
|
||||||
ctx.response.status = StatusCodes.OK
|
|
||||||
})
|
|
||||||
.post("/:appname/api/apphierarchy", async ctx => {
|
|
||||||
ctx.body = await ctx.instance.templateApi.saveApplicationHierarchy(
|
|
||||||
ctx.body
|
|
||||||
)
|
|
||||||
ctx.response.status = StatusCodes.OK
|
|
||||||
})
|
|
||||||
/*.post("/:appname/api/actionsAndTriggers", async (ctx) => {
|
|
||||||
ctx.body = await ctx.instance.templateApi.saveApplicationHierarchy(
|
|
||||||
ctx.body
|
|
||||||
);
|
|
||||||
ctx.response.status = StatusCodes.OK;
|
|
||||||
})
|
|
||||||
.get("/:appname/api/appDefinition", async (ctx) => {
|
|
||||||
ctx.body = await ctx.instance.templateApi.saveActionsAndTriggers(
|
|
||||||
ctx.body
|
|
||||||
);
|
|
||||||
ctx.response.status = StatusCodes.OK;
|
|
||||||
})*/
|
|
||||||
|
|
||||||
const getRecordKey = (appname, wholePath) =>
|
|
||||||
wholePath
|
|
||||||
.replace(`/${appname}/api/files/`, "")
|
|
||||||
.replace(`/${appname}/api/lookup_field/`, "")
|
|
||||||
.replace(`/${appname}/api/record/`, "")
|
|
||||||
.replace(`/${appname}/api/listRecords/`, "")
|
|
||||||
.replace(`/${appname}/api/aggregates/`, "")
|
|
||||||
|
|
||||||
return router
|
return router
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,8 +27,8 @@ module.exports.saveBackend = saveBackend
|
||||||
const getAppDefinition = async appPath =>
|
const getAppDefinition = async appPath =>
|
||||||
await readJSON(`${appPath}/appDefinition.json`)
|
await readJSON(`${appPath}/appDefinition.json`)
|
||||||
|
|
||||||
module.exports.getPackageForBuilder = async (config, appname) => {
|
module.exports.getPackageForBuilder = async (config, application) => {
|
||||||
const appPath = appPackageFolder(config, appname)
|
const appPath = appPackageFolder(config, application.name)
|
||||||
|
|
||||||
const pages = await getPages(appPath)
|
const pages = await getPages(appPath)
|
||||||
|
|
||||||
|
@ -40,6 +40,8 @@ module.exports.getPackageForBuilder = async (config, appname) => {
|
||||||
pages,
|
pages,
|
||||||
|
|
||||||
components: await getComponentDefinitions(appPath, pages),
|
components: await getComponentDefinitions(appPath, pages),
|
||||||
|
|
||||||
|
application,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ const {
|
||||||
const getDatastore = require("./datastore")
|
const getDatastore = require("./datastore")
|
||||||
const getDatabaseManager = require("./databaseManager")
|
const getDatabaseManager = require("./databaseManager")
|
||||||
const { $ } = require("@budibase/core").common
|
const { $ } = require("@budibase/core").common
|
||||||
const { keyBy, values } = require("lodash/fp")
|
const { keyBy, values, cloneDeep } = require("lodash/fp")
|
||||||
const {
|
const {
|
||||||
masterAppPackage,
|
masterAppPackage,
|
||||||
applictionVersionPackage,
|
applictionVersionPackage,
|
||||||
|
@ -128,20 +128,10 @@ module.exports = async context => {
|
||||||
const userInMaster = await getUser(app.id, username)
|
const userInMaster = await getUser(app.id, username)
|
||||||
if (!userInMaster) return null
|
if (!userInMaster) return null
|
||||||
|
|
||||||
const instance = await bb.recordApi.load(userInMaster.instance.key)
|
const { instance, bbInstance } = await getFullAccessApiForInstanceId(
|
||||||
|
|
||||||
const versionId = determineVersionId(instance.version)
|
|
||||||
|
|
||||||
const dsConfig = JSON.parse(instance.datastoreconfig)
|
|
||||||
const appPackage = await applictionVersionPackage(
|
|
||||||
context,
|
|
||||||
appname,
|
appname,
|
||||||
versionId,
|
userInMaster.instance.id,
|
||||||
instance.key
|
app.id
|
||||||
)
|
|
||||||
const bbInstance = await getApisWithFullAccess(
|
|
||||||
datastoreModule.getDatastore(dsConfig),
|
|
||||||
appPackage
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const authUser = await bbInstance.authApi.authenticate(username, password)
|
const authUser = await bbInstance.authApi.authenticate(username, password)
|
||||||
|
@ -164,6 +154,34 @@ module.exports = async context => {
|
||||||
return session
|
return session
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getFullAccessApiForInstanceId = async (appname, instanceId, appId) => {
|
||||||
|
if (!appId) {
|
||||||
|
appId = (await getApplication(appname)).id
|
||||||
|
}
|
||||||
|
const instanceKey = `/applications/${appId}/instances/${instanceId}`
|
||||||
|
const instance = await bb.recordApi.load(instanceKey)
|
||||||
|
|
||||||
|
const versionId = determineVersionId(instance.version)
|
||||||
|
|
||||||
|
const dsConfig = JSON.parse(instance.datastoreconfig)
|
||||||
|
const appPackage = await applictionVersionPackage(
|
||||||
|
context,
|
||||||
|
appname,
|
||||||
|
versionId,
|
||||||
|
instance.key
|
||||||
|
)
|
||||||
|
return {
|
||||||
|
bbInstance: await getApisWithFullAccess(
|
||||||
|
datastoreModule.getDatastore(dsConfig),
|
||||||
|
appPackage
|
||||||
|
),
|
||||||
|
instance,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const getFullAccessApiForMaster = async () =>
|
||||||
|
await getApisWithFullAccess(masterDatastore, masterAppPackage(context))
|
||||||
|
|
||||||
const getInstanceApiForSession = async (appname, sessionId) => {
|
const getInstanceApiForSession = async (appname, sessionId) => {
|
||||||
if (isMaster(appname)) {
|
if (isMaster(appname)) {
|
||||||
const customId = bb.recordApi.customId("mastersession", sessionId)
|
const customId = bb.recordApi.customId("mastersession", sessionId)
|
||||||
|
@ -295,6 +313,14 @@ module.exports = async context => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getApplicationWithInstances = async appname => {
|
||||||
|
const app = cloneDeep(await getApplication(appname))
|
||||||
|
app.instances = await bb.indexApi.listItems(
|
||||||
|
`/applications/${app.id}/allinstances`
|
||||||
|
)
|
||||||
|
return app
|
||||||
|
}
|
||||||
|
|
||||||
const disableUser = async (app, username) => {
|
const disableUser = async (app, username) => {
|
||||||
await removeSessionsForUser(app.name, username)
|
await removeSessionsForUser(app.name, username)
|
||||||
const userInMaster = await getUser(app.id, username)
|
const userInMaster = await getUser(app.id, username)
|
||||||
|
@ -324,5 +350,8 @@ module.exports = async context => {
|
||||||
createAppUser,
|
createAppUser,
|
||||||
bbMaster: bb,
|
bbMaster: bb,
|
||||||
listApplications,
|
listApplications,
|
||||||
|
getFullAccessApiForInstanceId,
|
||||||
|
getFullAccessApiForMaster,
|
||||||
|
getApplicationWithInstances,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue