Getting this error: "Uncaught Error: Not permitted. Untrusted code may only update documents by ID. [403]", but I am using document IDs


#1

I am creating my own version of Meteor’s Todo app. I am using one collection called “Lists” and am combining lists and tasks into one document where the tasks are nested within their corresponding list document. This is what gets inserted into each new list document that gets created:

const listId = Lists.insert({
    listName: newList,
    creationDate: new Date(),
    tasks: []
});

When a user adds tasks to an existing list, those tasks will get pushed to the “tasks” array within the current list document, like this:

Lists.update({ _id: listId }, { 
    $push: { tasks: {
        _id: new Mongo.ObjectID().toHexString(),
        taskName: newTask,
        completed: false,
        creationDate: new Date() 
        }
    }
});

I run into a problem when I try to update the name of a task. This is the code that I am using to update task names:

<template name="tasks">
  <h2>{{list.listName}}</h2>
  {{> create_tasks}}
  <div class="row">
    <ul style="list-style-type:none;">
      {{#each list.tasks}}
        <li class="{{selected}}">
          <div class="small-3 medium-1 columns">
            <input type="checkbox" {{selected}} class="checkbox">
          </div>
          <div class="small-9 medium-9 columns">
            <input type="text" value="{{taskName}}" name="taskField" class="taskField">
          </div>
          <div class="small-12 medium-2 columns">
            <button class="delete-task">Delete</button>
          </div>
        </li>
      {{/each}}
    </ul>
  </div>
</template>

Template.tasks.events({
    'keyup .taskField'(event) { 
        const listId = FlowRouter.getParam("_id");
        const taskId = this._id;
        const newTaskName = event.target.value;
        Lists.update(
            { _id: listId, "tasks._id": taskId }, 
            { $set: { "tasks.$.taskName": newTaskName } }
        );
    },
});

I keep getting this error:

Uncaught Error: Not permitted. Untrusted code may only update documents by ID. [403]

…but I am using document IDs to select both the list and the tasks within that list. Am I missing something?

Any help would be appreciated.

Thank you.


#2

This is a restriction of Meteor’s allow-deny package. Your update selector has to be a single string based _id, a Mongo.ObjectID, or an Object with an _id property and only an _id property (there is a size check to make sure the object selector only has one property).

Here are links to the relevant source code sections:


#3

Thank you for your response, hwilson. Do you have any suggestions to fix this error? Will the problem be fixed if I move my code to a method or do I have to completely rewrite my schemas?


#4

I’d suggest handling this via a Method. That way you get the added security benefits of following the Guide’s “don’t use allow/deny” recommendation (see the Avoid allow/deny section of the Guide).


#5

Thank you very much for your help! I will implement methods in my app.