node.js - 将 createBy 字段添加到 keystone.js 中的 User 模型中

标签 node.js mongoose keystonejs

我将“createdBy”字段添加到模型中,但它允许管理员选择所有用户作为“createdBy”用户。我希望此字段自动填充当前登录的管理员,但似乎无法使其工作。

理想情况下,这根本不会出现在用户界面中,而只是在保存用户时存储。

User.add({
    name: { type: Types.Name, required: true, index: true },
    email: { type: Types.Email, initial: true, required: true, index: true },
    company: { type: String, required: true, index: true, initial: true },
    phone: { type: String, required: true, index: true, initial: true },
    password: { type: Types.Password, initial: true, required: true },
    createdBy: { type: Types.Relationship, initial:true, required:true, ref: 'User' },
    createdAt: { type: Date, default: Date.now }
    }, 'Permissions', {
      level : { type: Types.Select, numeric: true, options: [{ value: 1, label: 'User'   }, {     value: 2, label: 'Group Administrator' }, { value: 3, label: 'System Administrator' }] }
    },
    'Screening', {
      rooms : { type: Types.Select, numeric: true, options: [{ value: 1, label: 'Screening room 1' }, { value: 2, label: 'Screening room 2' }, { value: 3, label: 'Screening room 3' }] }
});

最佳答案

虽然您的实现可以正常运行,但许多 Keystone 开发人员(包括我自己)对通过 POST 发送 user.id 的安全风险提出了担忧。当您说目前在 Keystone 中没有好的方法时,您也是正确的。

我的解决方案是在 Keystone 本身上实现该功能。我添加了一个可选的元模式,我将其称为“审核元”。这会向 List 添加两个字段(createdByupdatedBy),我使用以下方法将其填充到 UpdateHandler() 中: req.user 的现有缓存副本。这样就不需要通过 POST 发送 user._id

要使用它,您只需在定义列表后添加 List.addPattern('audit meta'); 即可,就像使用标准元 一样。我的 audit meta 实现还添加了 standard meta 字段,因此无需同时使用两者。

为了实现这一点,我对 Keystone 进行了以下更改

首先,在 lib\list.js 中,我将以下代码(以 + 为前缀)添加到 addPatern() 方法中:

List.prototype.addPattern = function(pattern) {

    switch (pattern) {
        ...

+       case 'audit meta':
+           var userModel = keystone.get('user model');
+
+           if(!this.schema.path('createdOn') && !this.schema.path('updatedOn')) {
+               this.addPattern('standard meta');
+           }
+
+           if (userModel) {
+               this.add({
+                   createdBy: { type: Field.Types.Relationship, ref: userModel, hidden: true, index: true },
+                   updatedBy: { type: Field.Types.Relationship, ref: userModel, hidden: true, index: true }
+               });
+               this.map('createdBy', 'createdBy');
+               this.map('modifiedBy', 'updatedBy');
+           }
+       break;
+
    }

    return this;

然后在lib/updateHandler.js中,我将以下代码添加到UpdateHandler.prototype.process(),就在progress()之前在该方法结束时调用。

+   // check for audit meta fields (mapped to createdBy/modifiedBy)
+   if (this.list.mappings.createdBy && this.item.isNew) {
+       this.item.set(this.list.mappings.createdBy, this.user._id);
+   }
+   if (this.list.mappings.modifiedBy) {
+       this.item.set(this.list.mappings.modifiedBy, this.user._id);
+   }

之前我向 Keystone 提交了一个拉取请求 ( https://github.com/JedWatson/keystone/pull/490 ),其中包括我的实现的详细说明。因此,如果您迫切需要这个,您可以随时 fork Keystone 的副本并合并我的 PR。

关于node.js - 将 createBy 字段添加到 keystone.js 中的 User 模型中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24923185/

相关文章:

javascript - 使用流式 JSON 输出构建简单的 Nodejs API

javascript - Node 未找到文件 ENOENT 错误

javascript - 有没有办法在Linux上从Electron读取缓存文件?

javascript - Node.js:Promise.all(promises).then(...) 从未执行但程序完成

node.js - Mongoose - 在 'pre' 中间件中返回错误

javascript - Array.push(Object) 插入对象数组

javascript - 尝试在 Mongoose 中填充,但它不起作用(nodejs)

javascript - 如何在 Keystone.js 项目中使用 Express.js 中间件?

javascript - keystone.js : how can I display content from 2 different models on my index page

javascript - 在 Keystonejs 部分 View 中使用预定义的模型数据