I'm using Loopback to access/update/make changes to my database. I've created a method called deleteSingleHearingTest in my common/models folder:
Account.deleteSingleHearingTest = function (req, callback) {
console.log('accounts.js: deleteSingleHearingTest: are we being reached????', req)
Account.findById(req.accessToken.userId)
.then(account => {
if (!account) {
throw new Error('Cannot find user');
}
console.log('account.js: deleteSingleHearingTest: req: ', req);
return app.models.HearingTest.updateAll({ accountId: account.id, id: req.body.hearingTestId }, { isDeleted: new Date() });
})
.then(() => {
callback(null);
})
.catch(error => {
callback(error);
});
}
after which I created a remote method:
Account.remoteMethod(
'deleteSingleHearingTest', {
http: {
path: '/deleteSingleHearingTest',
verb: 'post'
},
accepts: [
{ arg: 'req', type: 'object', http: { source: 'req' } }
],
returns: { "wtf": "wtf" }
});
When I attempt to use this via fetch inside a method called deleteSingleHearingTest in my actions folder(redux) I receive a 401 status error message:
export const deleteSingleHearingTest = (hearingTestNumber) => {
return (dispatch, getState) => {
let state = getState();
if (!state.user || !state.user.accessToken || !state.user.accessToken.id || !state.user.accessToken.userId) {
console.debug('writeTestResult', state.user);
// TODO: ERROR
return;
}
dispatch({
type: DELETE_SINGLE_REPORT_REQUEST
});
console.log('here is your access token', state.user.accessToken);
fetch(SERVERCONFIG.BASEURL + '/api/Accounts/deleteSingleHearingTest?access_token=' + state.user.accessToken.id, {
method: 'POST',
headers: SERVERCONFIG.HEADERS,
body: JSON.stringify({ "hearingTestId": hearingTestNumber })
})
.then(response => {
if (response.status === 200) {
console.log('actions/user.js deleteSingleReport were in the pipe 5x5', response.json());
}
console.log('actions/user.js failed to delete item: response: ', response)
})
}
};
Two errors I'm noticing:
1. the Account.deleteSingleHearingTest never gets reached. I know this because the console.log never shows up in the window where I ran node .
Here is a picture of my StrongLoop gui.
here is the picture of my account.json file
Here's a picture of a method that a previous developer created that currently works with no status errors. deleteSingleHearingTest is nearly identical.
From what I can tell by looking at your API Explorer screenshot, your Account
model is extending LoopBack's built-in User
model. The User
model has ACLs configured to deny access to all methods except few explicitly allowed ones. You can find the ACL configuration in common/models/user.json.
"acls": [
{
"principalType": "ROLE",
"principalId": "$everyone",
"permission": "DENY"
},
{
"principalType": "ROLE",
"principalId": "$everyone",
"permission": "ALLOW",
"property": "create"
},
{
"principalType": "ROLE",
"principalId": "$owner",
"permission": "ALLOW",
"property": "deleteById"
},
{
"principalType": "ROLE",
"principalId": "$everyone",
"permission": "ALLOW",
"property": "login"
},
// etc.
]
The first entry denies access to all methods, the subsequent entries allow access to certain methods for certain groups of users. For example, anybody ($everyone
) can create a new user or invoke a login
method, but the details of a User model can be retrieved only by the user themselves ($owner
).
Please refer to Controlling data access and Understanding the built-in User model in LoopBack's documentation to learn more.
In order to allow your users to execute Account.deleteSingleHearingTest
method, you need to add a new ACL entry to your Account
configuration. I believe LoopBack can merge ACL defined in the base model (User)
with the additional ACL entries defined in a subclassing model (Account
) as of pull request #1289. If that's the case then you need to simply add a new ACL entry in your common/models/account.json
file. Assuming any logged-in user can invoke deleteSingleHearingTest
, but anonymous (unauthenticated) users cannot:
{
"name": "Account",
"base": "User",
// ...
"acls": [
{
"principalType": "ROLE",
"principalId": "$authenticated",
"permission": "ALLOW",
"property": "deleteSingleHearingTest"
}
]
}