Describe the bug
Hello, seems like something changed in amplify or appsync not so long time ago.
When I try to perform GraphQL query which returns empty result, now I have error:
Not Authorized to access getSomeObject on type Query
There is code in resolver which leads to this behavior:
#if( !($isStaticGroupAuthorized == true || $isDynamicGroupAuthorized == true || $isOwnerAuthorized == true) )
$util.unauthorized()
#end
Thats right code, but somehow previously when $ctx.result was empty I did not get this error.
The problem is that Apollo don't cache query because error occurred.
This is wrong behavior, because if $ctx.result is NULL there should not be error
To Reproduce
@auth(rules: [{allow: owner, ownerField: "owner"}])
Expected behavior
On empty result error is not necessary because no data returned.
Using
We were able to reproduce this using [email protected], with queries from both react native and plain HTTP requests.
reverting to [email protected] and re-running amplify push fixes the issue.
We're experiencing the same behavior after upgrading to 4.24.3 from 4.22.0. Reverting to 4.24.2 didn't work for us.
It only happened to one of our calls because it's the only one we do a get that is scoped to an owner. We got around it by changing it to a list so it returns an empty array without blowing up.
We are facing the same issue after updating from 4.24.1 to 4.25.0
Reverting to 4.24.1 and pushing fixed the issue.
We are experiencing this problem too. I tried pinning the version 4.24.1 but it failed after a while.
I got more success with a monkey patch. Not ideal but it fixes the issue for us with no code rewrite required.
Add this to main.ts:
import API from '@aws-amplify/api';
const originalGraphQL = API.graphql;
API.graphql = async function (__namedParameters) {
let result;
try {
result = await originalGraphQL.bind(API)(__namedParameters);
}
catch (err) {
err.errors = err.errors.filter((e) => {
// ignore unauthorized errors with null values
// fix for amplify error: https://github.com/aws-amplify/amplify-cli/issues/4907
if (e.message.indexOf("Not Authorized to access") === 0) {
const val = get(err.data, e.path);
if (val === null) {
return false;
}
}
return true;
});
if (err.errors.length !== 0) {
throw err;
}
result = err;
}
return result;
function get(obj, path) {
let cur = obj;
for (let i = 0; i < path.length; i++) {
cur = cur[path[i]];
}
return cur;
}
};
Please let me know if it fixes the problem for you or not.
Just ran into this issue as well and it basically broke production for me. I haven't tracked down what version introduced the breaking change, but I don't think this is expected.
Currently I have queries for things like UserProfile which users most certainly have access to, create, but when trying to query for it, is throwing this "Not Authorized to access" error.
Just as an update, this appears to be fixed as of 4.27.3
I don't know what version exactly this was fixed in, but a small change to the VTL templates can be seen now:
#if( $util.isNullOrEmpty($ctx.result) )
#return
#end
Which... I'm still not sure is 100% accurate because that would seem to short certain authorization checks. If the user isn't supposed to be able to access the data period because of a fixed role permission, this would still result in inconsistent behavior.
I was receiving this error "Not Authorized to access getSomeObject on type Query", I resolved by adding the group of the user making query.
From:
@model
@searchable
{ allow: groups, groups: ["Admins"] }
{ allow: owner, operations: [create, update] }
])
To
@model
@searchable
{ allow: groups, groups: ["Admins"] }
{ allow: groups, groups: ["Customers"], operations: [read] }
{ allow: owner, operations: [create, update] }
])