2020-02-03 10:24:25 +01:00
|
|
|
const Router = require("@koa/router")
|
|
|
|
const session = require("./session")
|
|
|
|
const StatusCodes = require("../utilities/statusCodes")
|
|
|
|
const { resolve } = require("path")
|
|
|
|
const send = require("koa-send")
|
2020-03-10 11:05:09 +01:00
|
|
|
const routeHandlers = require("./routeHandlers")
|
|
|
|
|
2020-02-03 10:24:25 +01:00
|
|
|
const {
|
|
|
|
getPackageForBuilder,
|
2020-02-18 16:41:44 +01:00
|
|
|
getComponentDefinitions,
|
2020-02-03 10:24:25 +01:00
|
|
|
getApps,
|
|
|
|
saveScreen,
|
|
|
|
renameScreen,
|
|
|
|
deleteScreen,
|
2020-02-10 22:35:51 +01:00
|
|
|
buildPage,
|
2020-02-03 10:24:25 +01:00
|
|
|
componentLibraryInfo,
|
2020-02-10 16:51:09 +01:00
|
|
|
listScreens,
|
2020-02-10 22:35:51 +01:00
|
|
|
saveBackend,
|
2020-02-03 10:24:25 +01:00
|
|
|
} = require("../utilities/builder")
|
2019-06-28 23:59:27 +02:00
|
|
|
|
2020-02-03 10:24:25 +01:00
|
|
|
const builderPath = resolve(__dirname, "../builder")
|
2019-07-15 07:59:46 +02:00
|
|
|
|
2019-06-14 11:05:46 +02:00
|
|
|
module.exports = (config, app) => {
|
2020-02-03 10:24:25 +01:00
|
|
|
const router = new Router()
|
2019-06-14 11:05:46 +02:00
|
|
|
|
2020-02-03 10:24:25 +01:00
|
|
|
router
|
2019-06-14 18:01:01 +02:00
|
|
|
.use(session(config, app))
|
|
|
|
.use(async (ctx, next) => {
|
2020-02-03 10:24:25 +01:00
|
|
|
ctx.sessionId = ctx.session._sessCtx.externalKey
|
|
|
|
ctx.session.accessed = true
|
2019-07-16 23:14:57 +02:00
|
|
|
|
2020-02-03 10:24:25 +01:00
|
|
|
const pathParts = ctx.path.split("/")
|
2019-07-16 23:14:57 +02:00
|
|
|
|
2020-02-03 10:24:25 +01:00
|
|
|
if (pathParts.length < 2) {
|
|
|
|
ctx.throw(StatusCodes.NOT_FOUND, "App Name not declared")
|
|
|
|
}
|
2019-07-16 23:14:57 +02:00
|
|
|
|
2020-02-03 10:24:25 +01:00
|
|
|
const appname = pathParts[1]
|
|
|
|
ctx.set("x-bbappname", appname)
|
2019-07-16 23:14:57 +02:00
|
|
|
|
2020-02-03 10:24:25 +01:00
|
|
|
if (appname === "_builder") {
|
2020-03-10 11:05:09 +01:00
|
|
|
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")) {
|
2020-03-11 17:42:19 +01:00
|
|
|
const {
|
|
|
|
instance,
|
|
|
|
publicPath,
|
|
|
|
sharedPath,
|
|
|
|
} = await ctx.master.getFullAccessApiForMaster()
|
|
|
|
ctx.instance = instance
|
|
|
|
ctx.publicPath = publicPath
|
|
|
|
ctx.sharedPath = sharedPath
|
2020-03-10 11:05:09 +01:00
|
|
|
ctx.isAuthenticated = !!ctx.instance
|
|
|
|
} else if (ctx.path.startsWith("/_builder/instance")) {
|
|
|
|
const builderAppName = pathParts[3]
|
|
|
|
const instanceId = pathParts[4]
|
2020-03-11 17:42:19 +01:00
|
|
|
const {
|
|
|
|
bbInstance,
|
|
|
|
publicPath,
|
|
|
|
sharedPath,
|
|
|
|
} = await ctx.master.getFullAccessApiForInstanceId(
|
2020-03-10 11:05:09 +01:00
|
|
|
builderAppName,
|
|
|
|
instanceId
|
2020-03-11 17:42:19 +01:00
|
|
|
)
|
|
|
|
ctx.instance = bbInstance
|
|
|
|
ctx.publicPath = publicPath
|
|
|
|
ctx.sharedPath = sharedPath
|
2020-03-10 11:05:09 +01:00
|
|
|
ctx.isAuthenticated = !!ctx.instance
|
|
|
|
}
|
|
|
|
|
2020-02-03 10:24:25 +01:00
|
|
|
await next()
|
|
|
|
} else {
|
|
|
|
const instance = await ctx.master.getInstanceApiForSession(
|
|
|
|
appname,
|
|
|
|
ctx.sessionId
|
|
|
|
)
|
2019-07-15 07:59:46 +02:00
|
|
|
|
2020-02-03 10:24:25 +01:00
|
|
|
ctx.instance = instance.instance
|
|
|
|
ctx.publicPath = instance.publicPath
|
|
|
|
ctx.sharedPath = instance.sharedPath
|
|
|
|
ctx.isAuthenticated = !!instance.instance
|
2019-07-15 07:59:46 +02:00
|
|
|
|
2020-02-03 10:24:25 +01:00
|
|
|
await next()
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.get("/_builder", async ctx => {
|
|
|
|
await send(ctx, "/index.html", { root: builderPath })
|
|
|
|
})
|
|
|
|
.get("/_builder/:appname/componentlibrary", async ctx => {
|
|
|
|
const info = await componentLibraryInfo(
|
|
|
|
config,
|
|
|
|
ctx.params.appname,
|
|
|
|
ctx.query.lib
|
|
|
|
)
|
|
|
|
await send(ctx, info.components._lib || "index.js", { root: info.libDir })
|
|
|
|
})
|
2019-07-15 07:59:46 +02:00
|
|
|
.get("/_builder/*", async (ctx, next) => {
|
2020-02-03 10:24:25 +01:00
|
|
|
const path = ctx.path.replace("/_builder", "")
|
2019-07-15 07:59:46 +02:00
|
|
|
|
2020-03-11 17:42:19 +01:00
|
|
|
if (path.startsWith("/api/") || path.startsWith("/instance/")) {
|
2020-02-03 10:24:25 +01:00
|
|
|
await next()
|
|
|
|
} else {
|
|
|
|
await send(ctx, path, { root: builderPath })
|
|
|
|
}
|
2019-07-13 11:35:57 +02:00
|
|
|
})
|
2020-03-10 11:05:09 +01:00
|
|
|
.post("/:appname/api/authenticate", routeHandlers.authenticate)
|
|
|
|
.post(
|
|
|
|
"/_builder/instance/:appname/:instanceid/api/authenticate",
|
|
|
|
routeHandlers.authenticate
|
|
|
|
)
|
|
|
|
.post(
|
|
|
|
"/:appname/api/setPasswordFromTemporaryCode",
|
|
|
|
routeHandlers.setPasswordFromTemporaryCode
|
|
|
|
)
|
|
|
|
.post(
|
|
|
|
"/_builder/instance/:appname/:instanceid/api/setPasswordFromTemporaryCode",
|
|
|
|
routeHandlers.setPasswordFromTemporaryCode
|
|
|
|
)
|
|
|
|
.post(
|
|
|
|
"/:appname/api/createTemporaryAccess",
|
|
|
|
routeHandlers.createTemporaryAccess
|
|
|
|
)
|
|
|
|
.post(
|
|
|
|
"/_builder/instance/:appname/:instanceid/api/createTemporaryAccess",
|
|
|
|
routeHandlers.createTemporaryAccess
|
|
|
|
)
|
2020-02-03 10:24:25 +01:00
|
|
|
.get("/_builder/api/apps", async ctx => {
|
|
|
|
ctx.body = await getApps(config, ctx.master)
|
|
|
|
ctx.response.status = StatusCodes.OK
|
|
|
|
})
|
|
|
|
.get("/_builder/api/:appname/appPackage", async ctx => {
|
2020-03-10 11:05:09 +01:00
|
|
|
const application = await ctx.master.getApplicationWithInstances(
|
|
|
|
ctx.params.appname
|
|
|
|
)
|
|
|
|
ctx.body = await getPackageForBuilder(config, application)
|
2020-02-03 10:24:25 +01:00
|
|
|
ctx.response.status = StatusCodes.OK
|
|
|
|
})
|
|
|
|
.get("/_builder/api/:appname/components", async ctx => {
|
|
|
|
try {
|
2020-02-25 16:21:23 +01:00
|
|
|
ctx.body = getComponentDefinitions(
|
|
|
|
config,
|
|
|
|
ctx.params.appname,
|
|
|
|
ctx.query.lib
|
|
|
|
)
|
2020-02-03 10:24:25 +01:00
|
|
|
ctx.response.status = StatusCodes.OK
|
|
|
|
} catch (e) {
|
|
|
|
if (e.status) {
|
|
|
|
ctx.response.status = e.status
|
|
|
|
} else {
|
|
|
|
throw e
|
2019-07-25 08:31:54 +02:00
|
|
|
}
|
2020-02-03 10:24:25 +01:00
|
|
|
}
|
2019-07-25 08:31:54 +02:00
|
|
|
})
|
2020-02-03 10:24:25 +01:00
|
|
|
.get("/_builder/api/:appname/componentlibrary", async ctx => {
|
|
|
|
const info = await componentLibraryInfo(
|
|
|
|
config,
|
|
|
|
ctx.params.appname,
|
|
|
|
ctx.query.lib ? decodeURI(ctx.query.lib) : ""
|
|
|
|
)
|
|
|
|
ctx.body = info.components
|
|
|
|
ctx.response.status = StatusCodes.OK
|
|
|
|
})
|
2020-02-10 22:35:51 +01:00
|
|
|
.post("/_builder/api/:appname/backend", async ctx => {
|
|
|
|
await saveBackend(
|
|
|
|
config,
|
|
|
|
ctx.params.appname,
|
|
|
|
ctx.request.body.appDefinition,
|
|
|
|
ctx.request.body.accessLevels
|
|
|
|
)
|
2020-03-25 13:38:04 +01:00
|
|
|
ctx.master.deleteLatestPackageFromCache(ctx.params.appname)
|
2020-02-10 22:35:51 +01:00
|
|
|
ctx.response.status = StatusCodes.OK
|
|
|
|
})
|
2020-02-10 16:51:09 +01:00
|
|
|
.post("/_builder/api/:appname/pages/:pageName", async ctx => {
|
2020-02-10 22:35:51 +01:00
|
|
|
await buildPage(
|
2020-02-10 16:51:09 +01:00
|
|
|
config,
|
|
|
|
ctx.params.appname,
|
|
|
|
ctx.params.pageName,
|
|
|
|
ctx.request.body
|
|
|
|
)
|
|
|
|
ctx.response.status = StatusCodes.OK
|
|
|
|
})
|
|
|
|
.get("/_builder/api/:appname/pages/:pagename/screens", async ctx => {
|
|
|
|
ctx.body = await listScreens(
|
|
|
|
config,
|
|
|
|
ctx.params.appname,
|
|
|
|
ctx.params.pagename
|
|
|
|
)
|
|
|
|
ctx.response.status = StatusCodes.OK
|
|
|
|
})
|
|
|
|
.post("/_builder/api/:appname/pages/:pagename/screen", async ctx => {
|
2020-02-11 17:36:16 +01:00
|
|
|
ctx.body = await saveScreen(
|
2020-02-10 16:51:09 +01:00
|
|
|
config,
|
|
|
|
ctx.params.appname,
|
|
|
|
ctx.params.pagename,
|
|
|
|
ctx.request.body
|
|
|
|
)
|
2020-02-03 10:24:25 +01:00
|
|
|
ctx.response.status = StatusCodes.OK
|
|
|
|
})
|
2020-02-10 16:51:09 +01:00
|
|
|
.patch("/_builder/api/:appname/pages/:pagename/screen", async ctx => {
|
2020-02-03 10:24:25 +01:00
|
|
|
await renameScreen(
|
|
|
|
config,
|
|
|
|
ctx.params.appname,
|
2020-02-10 16:51:09 +01:00
|
|
|
ctx.params.pagename,
|
2020-02-03 10:24:25 +01:00
|
|
|
ctx.request.body.oldname,
|
|
|
|
ctx.request.body.newname
|
|
|
|
)
|
|
|
|
ctx.response.status = StatusCodes.OK
|
|
|
|
})
|
2020-02-10 16:51:09 +01:00
|
|
|
.delete("/_builder/api/:appname/pages/:pagename/screen/*", async ctx => {
|
2020-02-03 10:24:25 +01:00
|
|
|
const name = ctx.request.path.replace(
|
2020-02-10 16:51:09 +01:00
|
|
|
`/_builder/api/${ctx.params.appname}/pages/${ctx.params.pagename}/screen/`,
|
2020-02-03 10:24:25 +01:00
|
|
|
""
|
|
|
|
)
|
|
|
|
|
2020-02-10 16:51:09 +01:00
|
|
|
await deleteScreen(
|
|
|
|
config,
|
|
|
|
ctx.params.appname,
|
|
|
|
ctx.params.pagename,
|
|
|
|
decodeURI(name)
|
|
|
|
)
|
|
|
|
|
2020-02-03 10:24:25 +01:00
|
|
|
ctx.response.status = StatusCodes.OK
|
2019-07-26 18:08:59 +02:00
|
|
|
})
|
2020-02-03 10:24:25 +01:00
|
|
|
.get("/:appname", async ctx => {
|
|
|
|
await send(ctx, "/index.html", { root: ctx.publicPath })
|
2019-07-16 23:14:57 +02:00
|
|
|
})
|
2020-03-10 11:05:09 +01:00
|
|
|
.get("/:appname/*", routeHandlers.appDefault)
|
|
|
|
.get("/_builder/instance/:appname/:instanceid/*", routeHandlers.appDefault)
|
|
|
|
// EVERYTHING BELOW HERE REQUIRES AUTHENTICATION
|
2019-07-16 23:14:57 +02:00
|
|
|
.use(async (ctx, next) => {
|
2020-02-03 10:24:25 +01:00
|
|
|
if (ctx.isAuthenticated) {
|
|
|
|
await next()
|
|
|
|
} else {
|
|
|
|
ctx.response.status = StatusCodes.UNAUTHORIZED
|
|
|
|
}
|
|
|
|
})
|
2020-03-24 11:56:48 +01:00
|
|
|
.post(
|
|
|
|
"/_builder/instance/:appname/:instanceid/api/upgradeData",
|
|
|
|
routeHandlers.upgradeData
|
|
|
|
)
|
2020-03-10 11:05:09 +01:00
|
|
|
.post("/:appname/api/changeMyPassword", routeHandlers.changeMyPassword)
|
|
|
|
.post(
|
|
|
|
"/_builder/instance/:appname/:instanceid/api/changeMyPassword",
|
|
|
|
routeHandlers.changeMyPassword
|
|
|
|
)
|
|
|
|
.post(
|
|
|
|
"/:appname/api/executeAction/:actionname",
|
|
|
|
routeHandlers.executeAction
|
|
|
|
)
|
|
|
|
.post(
|
|
|
|
"/_builder/instance/:appname/:instanceid/api/executeAction/:actionname",
|
|
|
|
routeHandlers.executeAction
|
|
|
|
)
|
|
|
|
.post("/:appname/api/createUser", routeHandlers.createUser)
|
|
|
|
.post(
|
|
|
|
"/_builder/instance/:appname/:instanceid/api/createUser",
|
|
|
|
routeHandlers.createUser
|
|
|
|
)
|
|
|
|
.post("/:appname/api/enableUser", routeHandlers.enableUser)
|
|
|
|
.post(
|
|
|
|
"/_builder/instance/:appname/:instanceid/api/enableUser",
|
|
|
|
routeHandlers.enableUser
|
|
|
|
)
|
|
|
|
.post("/:appname/api/disableUser", routeHandlers.disableUser)
|
|
|
|
.post(
|
|
|
|
"/_builder/instance/:appname/:instanceid/api/disableUser",
|
|
|
|
routeHandlers.disableUser
|
|
|
|
)
|
|
|
|
.get("/:appname/api/users", routeHandlers.getUsers)
|
|
|
|
.get(
|
|
|
|
"/_builder/instance/:appname/:instanceid/api/users",
|
|
|
|
routeHandlers.getUsers
|
|
|
|
)
|
|
|
|
.get("/:appname/api/accessLevels", routeHandlers.getAccessLevels)
|
|
|
|
.get(
|
|
|
|
"/_builder/instance/:appname/:instanceid/api/accessLevels",
|
|
|
|
routeHandlers.getAccessLevels
|
|
|
|
)
|
|
|
|
.get("/:appname/api/listRecords/*", routeHandlers.listRecordsGet)
|
|
|
|
.get(
|
|
|
|
"/_builder/instance/:appname/:instanceid/api/listRecords/*",
|
|
|
|
routeHandlers.listRecordsGet
|
|
|
|
)
|
|
|
|
.post("/:appname/api/listRecords/*", routeHandlers.listRecordsPost)
|
|
|
|
.post(
|
|
|
|
"/_builder/instance/:appname/:instanceid/api/listRecords/*",
|
|
|
|
routeHandlers.listRecordsPost
|
|
|
|
)
|
|
|
|
.post("/:appname/api/aggregates/*", routeHandlers.aggregatesPost)
|
|
|
|
.post(
|
|
|
|
"/_builder/instance/:appname/:instanceid/api/aggregates/*",
|
|
|
|
routeHandlers.aggregatesPost
|
|
|
|
)
|
|
|
|
.post("/:appname/api/files/*", routeHandlers.postFiles)
|
|
|
|
.post(
|
|
|
|
"/_builder/instance/:appname/:instanceid/api/files/*",
|
|
|
|
routeHandlers.postFiles
|
|
|
|
)
|
|
|
|
.post("/:appname/api/record/*", routeHandlers.saveRecord)
|
|
|
|
.post(
|
|
|
|
"/_builder/instance/:appname/:instanceid/api/record/*",
|
|
|
|
routeHandlers.saveRecord
|
|
|
|
)
|
|
|
|
.get("/:appname/api/lookup_field/*", routeHandlers.lookupField)
|
|
|
|
.get(
|
|
|
|
"/_builder/instance/:appname/:instanceid/api/lookup_field/*",
|
|
|
|
routeHandlers.lookupField
|
|
|
|
)
|
|
|
|
.get("/:appname/api/record/*", routeHandlers.getRecord)
|
|
|
|
.get(
|
|
|
|
"/_builder/instance/:appname/:instanceid/api/record/*",
|
|
|
|
routeHandlers.getRecord
|
|
|
|
)
|
|
|
|
.del("/:appname/api/record/*", routeHandlers.deleteRecord)
|
|
|
|
.del(
|
|
|
|
"/_builder/instance/:appname/:instanceid/api/record/*",
|
|
|
|
routeHandlers.deleteRecord
|
|
|
|
)
|
|
|
|
.post("/:appname/api/apphierarchy", routeHandlers.saveAppHierarchy)
|
2019-06-28 23:59:27 +02:00
|
|
|
|
2020-02-03 10:24:25 +01:00
|
|
|
return router
|
2020-03-24 11:58:15 +01:00
|
|
|
}
|