Files
alphane.ca/api/src/router.ts
T
2026-06-19 23:45:56 -07:00

92 lines
2.6 KiB
TypeScript

import path from "path"
import fs from "fs"
import {
Router,
type Request,
type Response,
type ErrorRequestHandler,
type NextFunction,
} from "express"
import { UnauthorizedError } from "express-jwt"
import { template } from "lodash"
import { APPLICATION_NAME, GIT_COMMIT_HASH, NODE_ENV, RELEASE_TAG } from "@/config"
import { logger } from "@/utils/logger"
import { jwtMiddleware, authorizationMiddleware } from "@/middlewares"
import { CurrentUserController, UsersController } from "@/controllers"
export const router = Router()
// non-api (no authentication is required) routes
router.route("/_status").get((_req: Request, res: Response) => {
return res.json({
RELEASE_TAG,
GIT_COMMIT_HASH,
})
})
// external (public) routes - no authentication required
// api routes
router.use("/api", jwtMiddleware, authorizationMiddleware)
router.route("/api/current-user").get(CurrentUserController.show)
router.route("/api/users").get(UsersController.index).post(UsersController.create)
router
.route("/api/users/:userId")
.get(UsersController.show)
.patch(UsersController.update)
.delete(UsersController.destroy)
// if no other routes match, return a 404
router.use("/api", (req: Request, res: Response) => {
return res.status(404).json({ message: "Not Found", url: req.path })
})
// Special error handler for all api errors
// See https://expressjs.com/en/guide/error-handling.html#writing-error-handlers
router.use("/api", (err: ErrorRequestHandler, _req: Request, res: Response, next: NextFunction) => {
if (res.headersSent) {
return next(err)
}
if (err instanceof UnauthorizedError) {
logger.error(err)
return res.status(err.status).json({ message: err.inner.message })
}
/* if (err instanceof DatabaseError) {
logger.error(err)
return res.status(422).json({ message: "Invalid query against database." })
}
*/
logger.error(err)
return res.status(500).json({ message: "Internal Server Error" })
})
// if no other non-api routes match, send the pretty 404 page
if (NODE_ENV == "development") {
router.use("/", (_req: Request, res: Response) => {
const templatePath = path.resolve(__dirname, "web/404.html")
try {
const templateString = fs.readFileSync(templatePath, "utf8")
const compiledTemplate = template(templateString)
const result = compiledTemplate({
applicationName: APPLICATION_NAME,
releaseTag: RELEASE_TAG,
gitCommitHash: GIT_COMMIT_HASH,
})
return res.status(404).send(result)
} catch (error) {
logger.error(error)
return res.status(500).send(`Error building 404 page: ${error}`)
}
})
}
export default router