From 3519d0f21044a912f044a9c4609d0a714207713f Mon Sep 17 00:00:00 2001 From: Martin McKeaveney Date: Mon, 6 Apr 2020 14:05:57 +0100 Subject: [PATCH] restructuring server routers --- packages/server/middleware/routers.js | 246 ++---------------- packages/server/middleware/routes/apps.js | 5 +- .../server/middleware/routes/authenticated.js | 7 +- .../server/middleware/routes/builderRouter.js | 117 --------- .../server/middleware/routes/components.js | 19 +- packages/server/middleware/routes/pages.js | 9 +- packages/server/yarn.lock | 16 +- 7 files changed, 56 insertions(+), 363 deletions(-) delete mode 100644 packages/server/middleware/routes/builderRouter.js diff --git a/packages/server/middleware/routers.js b/packages/server/middleware/routers.js index f0bdd8dd77..336df0b5c2 100644 --- a/packages/server/middleware/routers.js +++ b/packages/server/middleware/routers.js @@ -4,21 +4,18 @@ const StatusCodes = require("../utilities/statusCodes") const { resolve } = require("path") const send = require("koa-send") const routeHandlers = require("./routeHandlers") - const { - getPackageForBuilder, - getComponentDefinitions, - getApps, - saveScreen, - renameScreen, - deleteScreen, - buildPage, componentLibraryInfo, - listScreens, - saveBackend, -} = require("../utilities/builder") +} = require("../../utilities/builder") +const { + componentRoutes, + appsRoutes, + pageRoutes, + userRoutes, + authenticatedRoutes +} = require("./"); -const builderPath = resolve(__dirname, "../builder") +const builderPath = resolve(__dirname, "../../builder") module.exports = (config, app) => { const router = new Router() @@ -28,6 +25,7 @@ module.exports = (config, app) => { .use(async (ctx, next) => { ctx.sessionId = ctx.session._sessCtx.externalKey ctx.session.accessed = true + ctx.config = config const pathParts = ctx.path.split("/") @@ -45,6 +43,7 @@ module.exports = (config, app) => { return } + // Builder URLs should have admin access to the API if (ctx.path.startsWith("/_builder/instance/_master")) { const { instance, @@ -92,7 +91,7 @@ module.exports = (config, app) => { }) .get("/_builder/:appname/componentlibrary", async ctx => { const info = await componentLibraryInfo( - config, + ctx.config, ctx.params.appname, ctx.query.lib ) @@ -111,220 +110,25 @@ module.exports = (config, app) => { await send(ctx, "/index.html", { root: builderPath }) } }) - .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 - ) - .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 => { - const application = await ctx.master.getApplicationWithInstances( - ctx.params.appname - ) - ctx.body = await getPackageForBuilder(config, application) - ctx.response.status = StatusCodes.OK - }) - .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 - } - } - }) - .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 - }) - .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 - }) - .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 - }) - .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 => { - ctx.body = await saveScreen( - config, - ctx.params.appname, - ctx.params.pagename, - ctx.request.body - ) - ctx.response.status = StatusCodes.OK - }) - .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 - }) - .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) - ) + router.use(userRoutes.routes()); + router.use(userRoutes.allowedMethods()); + router.use(appsRoutes.routes()) + router.use(appsRoutes.allowedMethods()); + router.use(componentRoutes.routes()); + router.use(componentRoutes.allowedMethods()); + router.use(pageRoutes.routes()); + router.use(pageRoutes.allowedMethods()); - ctx.response.status = StatusCodes.OK - }) + router .get("/:appname", async ctx => { await send(ctx, "/index.html", { root: ctx.publicPath }) - }) + }) .get("/:appname/*", routeHandlers.appDefault) .get("/_builder/instance/:appname/:instanceid/*", routeHandlers.appDefault) - // EVERYTHING BELOW HERE REQUIRES AUTHENTICATION - .use(async (ctx, next) => { - if (ctx.isAuthenticated) { - await next() - } else { - ctx.response.status = StatusCodes.UNAUTHORIZED - } - }) - .post( - "/_builder/instance/:appname/:instanceid/api/upgradeData", - routeHandlers.upgradeData - ) - .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) + + router.use(authenticatedRoutes.routes()); + router.use(authenticatedRoutes.allowedMethods()); return router } diff --git a/packages/server/middleware/routes/apps.js b/packages/server/middleware/routes/apps.js index 941be4eabc..96ab556217 100644 --- a/packages/server/middleware/routes/apps.js +++ b/packages/server/middleware/routes/apps.js @@ -1,4 +1,5 @@ const Router = require("@koa/router"); +const StatusCodes = require("../../utilities/statusCodes") const { getPackageForBuilder, getApps, @@ -8,7 +9,7 @@ const { const router = Router(); router.get("/_builder/api/apps", async ctx => { - ctx.body = await getApps(config, ctx.master) + ctx.body = await getApps(ctx.config, ctx.master) ctx.response.status = StatusCodes.OK }) @@ -16,7 +17,7 @@ router.get("/_builder/api/:appname/appPackage", async ctx => { const application = await ctx.master.getApplicationWithInstances( ctx.params.appname ) - ctx.body = await getPackageForBuilder(config, application) + ctx.body = await getPackageForBuilder(ctx.config, application) ctx.response.status = StatusCodes.OK }) diff --git a/packages/server/middleware/routes/authenticated.js b/packages/server/middleware/routes/authenticated.js index d6c791aedc..505dec7e84 100644 --- a/packages/server/middleware/routes/authenticated.js +++ b/packages/server/middleware/routes/authenticated.js @@ -1,15 +1,18 @@ const Router = require("@koa/router"); +const StatusCodes = require("../../utilities/statusCodes") const routeHandlers = require("../routeHandlers") const router = Router(); -router.use(async (ctx, next) => { +async function isAuthenticated(ctx, next) { if (ctx.isAuthenticated) { await next() } else { ctx.response.status = StatusCodes.UNAUTHORIZED } -}) +} + +router.use(isAuthenticated) router.post( "/_builder/instance/:appname/:instanceid/api/upgradeData", diff --git a/packages/server/middleware/routes/builderRouter.js b/packages/server/middleware/routes/builderRouter.js deleted file mode 100644 index 0071db0a14..0000000000 --- a/packages/server/middleware/routes/builderRouter.js +++ /dev/null @@ -1,117 +0,0 @@ -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 - ctx.config = config - - 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 index 8c770d57be..a72ebfccd4 100644 --- a/packages/server/middleware/routes/components.js +++ b/packages/server/middleware/routes/components.js @@ -1,5 +1,6 @@ const Router = require("@koa/router"); const send = require("koa-send") +const StatusCodes = require("../../utilities/statusCodes") const { getComponentDefinitions, componentLibraryInfo, @@ -8,6 +9,15 @@ const { const router = Router(); +router.get("/_builder/:appname/componentlibrary", async ctx => { + const info = await componentLibraryInfo( + ctx.config, + ctx.params.appname, + ctx.query.lib + ) + await send(ctx, info.components._lib || "index.js", { root: info.libDir }) +}) + router.get("/_builder/api/:appname/components", async ctx => { try { ctx.body = getComponentDefinitions( @@ -35,13 +45,4 @@ router.get("/_builder/api/:appname/componentlibrary", async ctx => { ctx.response.status = StatusCodes.OK }) -router.get("/_builder/:appname/componentlibrary", async ctx => { - const info = await componentLibraryInfo( - ctx.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/pages.js b/packages/server/middleware/routes/pages.js index 08a9418c9d..bde3aeeb4c 100644 --- a/packages/server/middleware/routes/pages.js +++ b/packages/server/middleware/routes/pages.js @@ -1,4 +1,5 @@ const Router = require("@koa/router"); +const StatusCodes = require("../../utilities/statusCodes") const { listScreens, saveScreen, @@ -10,7 +11,7 @@ const router = Router() router.get("/_builder/api/:appname/pages/:pagename/screens", async ctx => { ctx.body = await listScreens( - config, + ctx.config, ctx.params.appname, ctx.params.pagename ) @@ -20,7 +21,7 @@ router.get("/_builder/api/:appname/pages/:pagename/screens", async ctx => { router .post("/_builder/api/:appname/pages/:pagename/screen", async ctx => { ctx.body = await saveScreen( - config, + ctx.config, ctx.params.appname, ctx.params.pagename, ctx.request.body @@ -31,7 +32,7 @@ router router .patch("/_builder/api/:appname/pages/:pagename/screen", async ctx => { await renameScreen( - config, + ctx.config, ctx.params.appname, ctx.params.pagename, ctx.request.body.oldname, @@ -48,7 +49,7 @@ router ) await deleteScreen( - config, + ctx.config, ctx.params.appname, ctx.params.pagename, decodeURI(name) diff --git a/packages/server/yarn.lock b/packages/server/yarn.lock index 7e65f2f2d4..de31b9e9fc 100644 --- a/packages/server/yarn.lock +++ b/packages/server/yarn.lock @@ -131,10 +131,10 @@ lodash "^4.17.13" to-fast-properties "^2.0.0" -"@budibase/client@^0.0.27": - version "0.0.27" - resolved "https://registry.yarnpkg.com/@budibase/client/-/client-0.0.27.tgz#d43a66202a23103ae5ac89d9fa69c3cd36b2a090" - integrity sha512-emS6L66fzfr/CdnpazlqveVKqcSQA9+sQRcbzLZ+sJLFk6FNIezRQcMjGHz+ooeYS91OVgOfleqXDCnvHO+MNg== +"@budibase/client@^0.0.32": + version "0.0.32" + resolved "https://registry.yarnpkg.com/@budibase/client/-/client-0.0.32.tgz#76d9f147563a0bf939eae7f32ce75b2a527ba496" + integrity sha512-jmCCLn0CUoQbL6h623S5IqK6+GYLqX3WzUTZInSb1SCBOM3pI0eLP5HwTR6s7r42SfD0v9jTWRdyTnHiElNj8A== dependencies: "@nx-js/compiler-util" "^2.0.0" bcryptjs "^2.4.3" @@ -145,10 +145,10 @@ shortid "^2.2.8" svelte "^3.9.2" -"@budibase/core@^0.0.27": - version "0.0.27" - resolved "https://registry.yarnpkg.com/@budibase/core/-/core-0.0.27.tgz#05bbacce692222089a1ae85b7ea4bb322e327f64" - integrity sha512-V8qGB9Lcwz8CFGzYct6i1oI+WiYgEOCsBBQ6DPPRLLVg07i2DHI9Ynwa35QXWTO3WeyWIxy//WSmVwSlYPAtOw== +"@budibase/core@^0.0.32": + version "0.0.32" + resolved "https://registry.yarnpkg.com/@budibase/core/-/core-0.0.32.tgz#c5d9ab869c5e9596a1ac337aaf041e795b1cc7fa" + integrity sha512-B6DHlz/C/m3jrxHbImT4bphdJlL7r2qmGrmcVBSc9mGHvwcRh1xfFGrsPCOU2IEJow+DWD63BIjyHzLPI3cerQ== dependencies: "@nx-js/compiler-util" "^2.0.0" bcryptjs "^2.4.3"