169 lines
3.8 KiB
JavaScript
169 lines
3.8 KiB
JavaScript
import passport from "passport"
|
|
import createError from "http-errors"
|
|
import autobind from "autobind-decorator"
|
|
import { catchAll } from "."
|
|
|
|
// The list of functions you can list in options.nonAdmin is:
|
|
//
|
|
// listItems
|
|
// createItem
|
|
// updateItem
|
|
// getItem
|
|
// deleteItem
|
|
|
|
@autobind
|
|
export class BaseRoutes {
|
|
constructor(options) {
|
|
const { container } = options
|
|
this.options = options
|
|
this.log = container.log
|
|
this.db = container.db
|
|
|
|
const basePath = "/" + options.model.collection.collectionName
|
|
const app = container.app
|
|
|
|
app
|
|
.route(basePath)
|
|
.get(
|
|
passport.authenticate("bearer", { session: false }),
|
|
catchAll(this.listItems)
|
|
)
|
|
.post(
|
|
passport.authenticate("bearer", { session: false }),
|
|
catchAll(this.createItem)
|
|
)
|
|
.put(
|
|
passport.authenticate("bearer", { session: false }),
|
|
catchAll(this.updateItem)
|
|
)
|
|
|
|
app
|
|
.route(basePath + "/:_id([a-f0-9]{24})")
|
|
.get(
|
|
passport.authenticate("bearer", { session: false }),
|
|
catchAll(this.getItem)
|
|
)
|
|
.delete(
|
|
passport.authenticate("bearer", { session: false }),
|
|
catchAll(this.deleteItem)
|
|
)
|
|
}
|
|
|
|
async listItems(req, res, next) {
|
|
const isAdmin = !!req.user.administrator
|
|
|
|
if (!this.options.nonAdmin.listItems && !isAdmin) {
|
|
throw createError.Forbidden()
|
|
}
|
|
|
|
const ItemModel = this.options.model
|
|
const limit = req.query.limit || 20
|
|
const skip = req.query.skip || 0
|
|
const partial = !!req.query.partial
|
|
let query = {}
|
|
|
|
const total = await ItemModel.count({})
|
|
|
|
let items = []
|
|
let cursor = ItemModel.find(query)
|
|
.limit(limit)
|
|
.skip(skip)
|
|
.cursor()
|
|
.map((doc) => {
|
|
return doc.toClient(partial)
|
|
})
|
|
|
|
cursor.on("data", (doc) => {
|
|
items.push(doc)
|
|
})
|
|
cursor.on("end", () => {
|
|
res.json({
|
|
total: total,
|
|
offset: skip,
|
|
count: items.length,
|
|
items: items,
|
|
})
|
|
})
|
|
cursor.on("error", (err) => {
|
|
throw createError.InternalServerError(err.message)
|
|
})
|
|
}
|
|
|
|
async createItem(req, res) {
|
|
const isAdmin = !!req.user.administrator
|
|
|
|
if (!this.options.nonAdmin.createItem && !isAdmin) {
|
|
throw createError.Forbidden()
|
|
}
|
|
|
|
const ItemModel = this.options.model
|
|
let item = new ItemModel(req.body)
|
|
|
|
const newItem = await item.save()
|
|
|
|
res.json(newItem.toClient())
|
|
}
|
|
|
|
async updateItem(req, res) {
|
|
const isAdmin = !!req.user.administrator
|
|
|
|
if (!this.options.nonAdmin.updateItem && !isAdmin) {
|
|
throw createError.Forbidden()
|
|
}
|
|
|
|
// Do this here because Mongoose will add it automatically otherwise
|
|
if (!req.body._id) {
|
|
throw createError.BadRequest("No _id given in body")
|
|
}
|
|
|
|
let ItemModel = this.options.model
|
|
let item = await ItemModel.findById(req.body._id)
|
|
|
|
if (!item) {
|
|
throw createError.NotFound(`Item with _id ${_id} was not found`)
|
|
}
|
|
|
|
item.merge(new ItemModel(req.body))
|
|
|
|
const savedItem = await item.save()
|
|
|
|
res.json(savedItem.toClient())
|
|
}
|
|
|
|
async getItem(req, res) {
|
|
const isAdmin = !!req.user.administrator
|
|
|
|
if (!this.options.nonAdmin.getItem && !isAdmin) {
|
|
throw createError.Forbidden()
|
|
}
|
|
|
|
const ItemModel = this.options.model
|
|
const _id = req.params._id
|
|
const item = await ItemModel.findById(_id)
|
|
|
|
if (!item) {
|
|
throw createError.NotFound(`Item with _id ${_id} not found`)
|
|
}
|
|
|
|
res.json(item.toClient())
|
|
}
|
|
|
|
async deleteItem(req, res) {
|
|
const isAdmin = !!req.user.administrator
|
|
|
|
if (!this.options.nonAdmin.deleteItem && !isAdmin) {
|
|
throw createError.Forbidden()
|
|
}
|
|
|
|
const ItemModel = this.options.model
|
|
const _id = req.params._id
|
|
const item = await ItemModel.remove({ _id })
|
|
|
|
if (!item) {
|
|
throw createError.NotFound(`Item with _id ${_id} not found`)
|
|
}
|
|
|
|
res.json({})
|
|
}
|
|
}
|