budibase/packages/server/middleware/routers.js

137 lines
4.0 KiB
JavaScript
Raw Normal View History

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 {
componentLibraryInfo,
2020-04-06 15:16:21 +02:00
} = require("../utilities/builder")
2020-04-06 15:05:57 +02:00
const {
componentRoutes,
appsRoutes,
pageRoutes,
userRoutes,
authenticatedRoutes
2020-04-06 15:16:21 +02:00
} = require("./routes");
2019-06-28 23:59:27 +02:00
2020-04-06 15:05:57 +02: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) => {
const router = new Router()
2019-06-14 11:05:46 +02:00
router
2019-06-14 18:01:01 +02:00
.use(session(config, app))
.use(async (ctx, next) => {
ctx.sessionId = ctx.session._sessCtx.externalKey
ctx.session.accessed = true
2020-04-06 15:05:57 +02:00
ctx.config = config
2019-07-16 23:14:57 +02:00
const pathParts = ctx.path.split("/")
2019-07-16 23:14:57 +02:00
if (pathParts.length < 2) {
ctx.throw(StatusCodes.NOT_FOUND, "App Name not declared")
}
2019-07-16 23:14:57 +02:00
const appname = pathParts[1]
ctx.set("x-bbappname", appname)
2019-07-16 23:14:57 +02:00
if (appname === "_builder") {
if (!config.dev) {
ctx.response.status = StatusCodes.FORBIDDEN
ctx.body = "run in dev mode to access builder"
return
}
2020-04-06 15:05:57 +02:00
// Builder URLs should have admin access to the API
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
)
2019-07-15 07:59:46 +02: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
await next()
}
})
2020-04-06 15:16:21 +02:00
router
.get("/_builder", async ctx => {
await send(ctx, "/index.html", { root: builderPath })
2020-04-06 15:16:21 +02:00
})
.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 })
})
.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 })
}
})
2020-04-06 15:05:57 +02:00
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());
2020-04-06 15:05:57 +02:00
router
.get("/:appname", async ctx => {
await send(ctx, "/index.html", { root: ctx.publicPath })
2020-04-06 15:05:57 +02:00
})
.get("/:appname/*", routeHandlers.appDefault)
.get("/_builder/instance/:appname/:instanceid/*", routeHandlers.appDefault)
2020-04-06 15:05:57 +02:00
router.use(authenticatedRoutes.routes());
router.use(authenticatedRoutes.allowedMethods());
2019-06-28 23:59:27 +02:00
return router
}