diff --git a/packages/server/middleware/routes/apps.js b/packages/server/middleware/routes/apps.js new file mode 100644 index 0000000000..dd20d79ab5 --- /dev/null +++ b/packages/server/middleware/routes/apps.js @@ -0,0 +1,35 @@ +const Router = require("@koa/router"); +const { + getPackageForBuilder, + getApps, +} = require("../utilities/builder") + +const router = Router(); + +router.get("/_builder/api/apps", async ctx => { + ctx.body = await getApps(config, ctx.master) + ctx.response.status = StatusCodes.OK +}) + +router.get("/_builder/api/:appname/appPackage", async ctx => { + const application = await ctx.master.getApplicationWithInstances( + ctx.params.appname + ) + ctx.body = await getPackageForBuilder(config, application) + ctx.response.status = StatusCodes.OK +}) + +router + .post("/_builder/api/:appname/backend", async ctx => { + await saveBackend( + config, + ctx.params.appname, + ctx.request.body.appDefinition, + ctx.request.body.accessLevels + ) + ctx.master.deleteLatestPackageFromCache(ctx.params.appname) + ctx.response.status = StatusCodes.OK + }) + + +module.exports = router \ No newline at end of file diff --git a/packages/server/middleware/routes/authenticated.js b/packages/server/middleware/routes/authenticated.js new file mode 100644 index 0000000000..5931469d89 --- /dev/null +++ b/packages/server/middleware/routes/authenticated.js @@ -0,0 +1,129 @@ +const Router = require("koa-router"); +const routeHandlers = require("../routeHandlers") + +const router = Router(); + +router.use(async (ctx, next) => { + if (ctx.isAuthenticated) { + await next() + } else { + ctx.response.status = StatusCodes.UNAUTHORIZED + } +}) + +router.post( + "/_builder/instance/:appname/:instanceid/api/upgradeData", + routeHandlers.upgradeData +) + +router.post("/:appname/api/changeMyPassword", routeHandlers.changeMyPassword) + +router.post( + "/_builder/instance/:appname/:instanceid/api/changeMyPassword", + routeHandlers.changeMyPassword +) + +router.post( + "/:appname/api/executeAction/:actionname", + routeHandlers.executeAction +) + +router.post( + "/_builder/instance/:appname/:instanceid/api/executeAction/:actionname", + routeHandlers.executeAction +) + +router.post("/:appname/api/createUser", routeHandlers.createUser) + +router.post( + "/_builder/instance/:appname/:instanceid/api/createUser", + routeHandlers.createUser +) + +router.post("/:appname/api/enableUser", routeHandlers.enableUser) + +router.post( + "/_builder/instance/:appname/:instanceid/api/enableUser", + routeHandlers.enableUser +) + +router.post("/:appname/api/disableUser", routeHandlers.disableUser) + +router.post( + "/_builder/instance/:appname/:instanceid/api/disableUser", + routeHandlers.disableUser +) + +router.get("/:appname/api/users", routeHandlers.getUsers) + +router.get( + "/_builder/instance/:appname/:instanceid/api/users", + routeHandlers.getUsers +) + +router.get("/:appname/api/accessLevels", routeHandlers.getAccessLevels) + +router.get( + "/_builder/instance/:appname/:instanceid/api/accessLevels", + routeHandlers.getAccessLevels +) + +router.get("/:appname/api/listRecords/*", routeHandlers.listRecordsGet) + +router.get( + "/_builder/instance/:appname/:instanceid/api/listRecords/*", + routeHandlers.listRecordsGet +) + +router.post("/:appname/api/listRecords/*", routeHandlers.listRecordsPost) + +router.post( + "/_builder/instance/:appname/:instanceid/api/listRecords/*", + routeHandlers.listRecordsPost +) + +router.post("/:appname/api/aggregates/*", routeHandlers.aggregatesPost) + +router.post( + "/_builder/instance/:appname/:instanceid/api/aggregates/*", + routeHandlers.aggregatesPost +) + +router.post("/:appname/api/files/*", routeHandlers.postFiles) + +router.post( + "/_builder/instance/:appname/:instanceid/api/files/*", + routeHandlers.postFiles +) + +router.post("/:appname/api/record/*", routeHandlers.saveRecord) + +router.post( + "/_builder/instance/:appname/:instanceid/api/record/*", + routeHandlers.saveRecord +) + +router.get("/:appname/api/lookup_field/*", routeHandlers.lookupField) + +router.get( + "/_builder/instance/:appname/:instanceid/api/lookup_field/*", + routeHandlers.lookupField +) + +router.get("/:appname/api/record/*", routeHandlers.getRecord) + +router.get( + "/_builder/instance/:appname/:instanceid/api/record/*", + routeHandlers.getRecord +) + +router.del("/:appname/api/record/*", routeHandlers.deleteRecord) + +router.del( + "/_builder/instance/:appname/:instanceid/api/record/*", + routeHandlers.deleteRecord +) + +router.post("/:appname/api/apphierarchy", routeHandlers.saveAppHierarchy) + +module.exports = router \ No newline at end of file diff --git a/packages/server/middleware/routes/builderRouter.js b/packages/server/middleware/routes/builderRouter.js new file mode 100644 index 0000000000..a9960a0b26 --- /dev/null +++ b/packages/server/middleware/routes/builderRouter.js @@ -0,0 +1,116 @@ +const Router = require("@koa/router") +const session = require("./session") +const StatusCodes = require("../utilities/statusCodes") +const { resolve } = require("path") +const send = require("koa-send") +const routeHandlers = require("./routeHandlers") +const { + componentRoutes, + appsRoutes, + pageRoutes, + userRoutes, + authenticatedRoutes +} = require("./"); + +const builderPath = resolve(__dirname, "../builder") + +module.exports = (config, app) => { + const router = new Router() + + router + .use(session(config, app)) + .use(async (ctx, next) => { + ctx.sessionId = ctx.session._sessCtx.externalKey + ctx.session.accessed = true + + const pathParts = ctx.path.split("/") + + if (pathParts.length < 2) { + ctx.throw(StatusCodes.NOT_FOUND, "App Name not declared") + } + + const appname = pathParts[1] + ctx.set("x-bbappname", appname) + + 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")) { + const { + instance, + publicPath, + sharedPath, + } = await ctx.master.getFullAccessApiForMaster() + ctx.instance = instance + ctx.publicPath = publicPath + ctx.sharedPath = sharedPath + ctx.isAuthenticated = !!ctx.instance + } else if (ctx.path.startsWith("/_builder/instance")) { + const builderAppName = pathParts[3] + const instanceId = pathParts[4] + const { + bbInstance, + publicPath, + sharedPath, + } = await ctx.master.getFullAccessApiForInstanceId( + builderAppName, + instanceId + ) + ctx.instance = bbInstance + ctx.publicPath = publicPath + ctx.sharedPath = sharedPath + ctx.isAuthenticated = !!ctx.instance + } + + await next() + } else { + const instance = await ctx.master.getInstanceApiForSession( + appname, + ctx.sessionId + ) + + ctx.instance = instance.instance + ctx.publicPath = instance.publicPath + ctx.sharedPath = instance.sharedPath + ctx.isAuthenticated = !!instance.instance + + await next() + } + }) + + router.get("/_builder", async ctx => { + await send(ctx, "/index.html", { root: builderPath }) + }) + router.get("/_builder/*", async (ctx, next) => { + const path = ctx.path.replace("/_builder", "") + + const isFile = new RegExp(/(.+\..{1,5})/g).test(path) + + if (path.startsWith("/api/") || path.startsWith("/instance/")) { + await next() + } else if (isFile) { + await send(ctx, path, { root: builderPath }) + } else { + await send(ctx, "/index.html", { root: builderPath }) + } + }) + + router.use(userRoutes.routes()); + router.use(appsRoutes.routes()) + router.use(componentRoutes.routes()); + router.use(pageRoutes.routes()); + + router.get("/:appname", async ctx => { + await send(ctx, "/index.html", { root: ctx.publicPath }) + }) + router.get("/:appname/*", routeHandlers.appDefault) + router.get("/_builder/instance/:appname/:instanceid/*", routeHandlers.appDefault) + + router.use(authenticatedRoutes.routes()); + + return router +} diff --git a/packages/server/middleware/routes/components.js b/packages/server/middleware/routes/components.js new file mode 100644 index 0000000000..bc52863966 --- /dev/null +++ b/packages/server/middleware/routes/components.js @@ -0,0 +1,47 @@ +const Router = require("koa-router"); +const send = require("koa-send") +const { + getComponentDefinitions, + componentLibraryInfo, +} = require("../../utilities/builder") + + +const router = Router(); + +router.get("/_builder/api/:appname/components", async ctx => { + try { + ctx.body = getComponentDefinitions( + config, + ctx.params.appname, + ctx.query.lib + ) + ctx.response.status = StatusCodes.OK + } catch (e) { + if (e.status) { + ctx.response.status = e.status + } else { + throw e + } + } +}) + +router.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 +}) + +router.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 }) +}) + +module.exports = router \ No newline at end of file diff --git a/packages/server/middleware/routes/index.js b/packages/server/middleware/routes/index.js new file mode 100644 index 0000000000..1efaadbaeb --- /dev/null +++ b/packages/server/middleware/routes/index.js @@ -0,0 +1,14 @@ +const screenRoutes = require("./screens"); +const pageRoutes = require("./pages"); +const componentRoutes = require("./components"); +const userRoutes = require("./user"); +const appsRoutes = require("./apps"); +const authenticatedRoutes = require("./authenticated"); + +module.exports = { + screenRoutes, + pageRoutes, + componentRoutes, + authRoutes, + appsRoutes +}; \ No newline at end of file diff --git a/packages/server/middleware/routes/pages.js b/packages/server/middleware/routes/pages.js new file mode 100644 index 0000000000..ee954b36ff --- /dev/null +++ b/packages/server/middleware/routes/pages.js @@ -0,0 +1,70 @@ +const Router = require("@koa/router"); +const { + listScreens, + saveScreen, + buildPage +} = require("../../utilities/builder") + + +const router = Router() + +router.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 +}) + +router + .post("/_builder/api/:appname/pages/:pagename/screen", async ctx => { + ctx.body = await saveScreen( + config, + ctx.params.appname, + ctx.params.pagename, + ctx.request.body + ) + ctx.response.status = StatusCodes.OK + }) + +router + .patch("/_builder/api/:appname/pages/:pagename/screen", async ctx => { + await renameScreen( + config, + ctx.params.appname, + ctx.params.pagename, + ctx.request.body.oldname, + ctx.request.body.newname + ) + ctx.response.status = StatusCodes.OK + }) + +router + .delete("/_builder/api/:appname/pages/:pagename/screen/*", async ctx => { + const name = ctx.request.path.replace( + `/_builder/api/${ctx.params.appname}/pages/${ctx.params.pagename}/screen/`, + "" + ) + + await deleteScreen( + config, + ctx.params.appname, + ctx.params.pagename, + decodeURI(name) + ) + + ctx.response.status = StatusCodes.OK +}) + +router.post("/_builder/api/:appname/pages/:pageName", async ctx => { + await buildPage( + config, + ctx.params.appname, + ctx.params.pageName, + ctx.request.body + ) + ctx.response.status = StatusCodes.OK +}) + +module.exports = router \ No newline at end of file diff --git a/packages/server/middleware/routes/user.js b/packages/server/middleware/routes/user.js new file mode 100644 index 0000000000..72e8ac717b --- /dev/null +++ b/packages/server/middleware/routes/user.js @@ -0,0 +1,33 @@ +const Router = require("@koa/router") +const routeHandlers = require("../routeHandlers") + +const router = new Router() + +router.post("/:appname/api/authenticate", routeHandlers.authenticate) + +router.post( + "/_builder/instance/:appname/:instanceid/api/authenticate", + routeHandlers.authenticate +) + +router.post( + "/_builder/instance/:appname/:instanceid/api/setPasswordFromTemporaryCode", + routeHandlers.setPasswordFromTemporaryCode +) + +router.post( + "/_builder/instance/:appname/:instanceid/api/createTemporaryAccess", + routeHandlers.createTemporaryAccess +) + +router.post( + "/:appname/api/createTemporaryAccess", + routeHandlers.createTemporaryAccess +) + +router.post( + "/:appname/api/setPasswordFromTemporaryCode", + routeHandlers.setPasswordFromTemporaryCode +) + +module.exports = router \ No newline at end of file