I came across this issue when writing some tests to validate the security of an API. In one of the tests, it validates that calls to patch() a resource are limited to the owning user, which is a fairy common requirement in most APIs.
As a simple example, using feathers-authentication-hooks, here the patch method will rewrite the userId in the query, effectively causing calls made by a user which doesn't own the resource to return 404.
const { setField } = require('feathers-authentication-hooks');
const limitToUser = setField({
from: 'params.user.id',
as: 'params.query.userId'
});
before: {
all: [],
find: [],
get: [],
create: [],
update: [],
patch: [
authenticate('jwt'),
limitToUser
],
remove: []
},
If you update the service to include 'allowedUpsert`, the call to patch ignores the userId set on the query. In this scenario this means user2 could update user1's resource.
const options = {
Model: createModel(app),
paginate: app.get('paginate'),
whitelist: ['$eager'],
allowedEager: '[images]',
allowedUpsert: 'images'
};
This isn't specific to the userId - any params which are set on the query are ignored if allowedUpsert is enabled. This doesn't repro for calls to update.
I believe this is a bug, since the behavior is not documented, and it goes against the expected behavior of patch() - but if not, curious as to why this happens and what the best practice is here. Thanks for your help!