Skip to content

Usage

Example

import mongoose from 'mongoose';
import express from 'express';
import macl from 'express-mongoose-acl';
import { Permissions } from 'express-mongoose-acl/permission';
const router = express.Router();

mongoose.model(
  'User',
  new mongoose.Schema({
    name: { type: String },
    address: { type: String },
    roles: { type: String },
    creditBalance: { type: Number },
    loginDate: { type: Date },
  }),
);

macl.set('globalPermissions', function (req) {
  const user = req.user;

  if (!user) return { isGuest: true };

  return {
    isGuest: false,
    isAdmin: user.roles.includes('admin'),
    isManager: user.roles.includes('manager'),
  };
});

const userRouter = macl.createRouter('User', { baseUrl: null });

userRouter.routeGuard({
  list: true,
  read: ['isAdmin', 'isManager'],
  update: 'isAdmin',
  create: function (permissions: Permissions) {
    // `this` refers to Express request object
    if (permissions.isAdmin) return true;
    return false;
  },
  delete: false,
});

userRouter.baseQuery({
  list: function (permissions: Permissions) {
    return true;
  },
  read: function (permissions: Permissions) {
    if (permissions.isAdmin) return {};
    else return { $or: [{ _id: this.user._id }, { role: ['user'] }] };
  },
  update: function (permissions: Permissions) {
    if (permissions.isAdmin) return {};
    else return { _id: this.user._id };
  },
  delete: function (permissions: Permissions) {
    return permissions.isAdmin;
  },
});

userRouter.permissionSchema({
  name: { list: true, read: true, update: 'edit.name', create: true },
  roles: {
    list: ['isAdmin', 'isManager'],
    read: 'isAdmin',
    update: function (permissions: Permissions, docPermissions) {
      // `this` refers to Express request object
      if (docPermissions['edit.roles']) return true;
      return false;
    },
    create: 'isAdmin',
  },
});

userRouter.docPermissions(function (docOrObject, permissions: Permissions) {
  const isMe = String(docOrObject._id) === String(this.user._id);

  return {
    'edit.name': permissions.isAdmin || isMe,
    'edit.roles': permissions.isAdmin,
  };
});

userRouter.prepare({
  create: function (docObject, permissions: Permissions, context) {
    const { originalData } = context;
    // add create prepare function
    return docObject;
  },
  update: function (docObject, permissions: Permissions, context) {
    const { originalDoc, originalData, currentDoc } = context;
    // add update prepare function
    return docObject;
  },
});

userRouter.transform(function (doc, permissions: Permissions, context) {
  const { originalDoc, originalData, currentDoc, preparedData, modifiedPaths } = context;
  // add transform function
  return doc;
});

userRouter.decorate({
  list: function (docObject, permissions: Permissions, context) {
    const { docPermissions } = context;
    // add list decorator function
    return docObject;
  },
  read: function (docObject, permissions: Permissions, context) {
    const { docPermissions } = context;
    // add read decorator function
    return docObject;
  },
  create: function (docObject, permissions: Permissions, context) {
    const { originalData, preparedData, docPermissions } = context;
    // add create decorator function
    return docObject;
  },
  update: function (docObject, permissions: Permissions, context) {
    const { originalDoc, originalData, currentDoc, preparedData, modifiedPaths, docPermissions } = context;
    // add update decorator function
    return docObject;
  },
});

userRouter.decorateAll(function (docObjects, permissions: Permissions) {
  // add decorator-all function
  return docObjects;
});

userRouter.identifier(function (id) {
  return { name: id };
});

router.use('/api/users', userRouter.routes);