AppSync error: Not Authorized to access listTodos on type Query - aws-amplify

I've set up a basic app to test Amplify's #auth rules. I have this simple graphql.schema:
type Todo #model #auth(rules: [{ allow: public }]) {
id: ID!
name: String!
description: String
}
type Blog #model #auth(rules: [{ allow: owner }]) {
id: ID!
name: String!
posts: [Post] #hasMany
}
...
When I try to perform a simple list operation with AppSync, Blog succeeds, but Todo returns an error: Not Authorized to access listTodos on type Query
I have set my API (amplify update api) to use Cognito User Pools as the default auth, and to use API key as a secondary auth type. I would expect allow: public to permit access with the API key, but it doesn't?

Related

AWS Amplify Unauthorized Error - Not Authorized to access [...] on type [...]

I have an AWS Amplify app using google federate sign in.
This is my data model.
type TriadeMetric #model #auth(rules: [{allow: owner}]) {
id: ID!
NoteMetrics: [NoteMetric] #hasMany(indexName: "byTriadeMetric", fields: ["id"])
}
enum MetricEnum {
ACCURACY
DURATION
}
type NoteMetric #model #auth(rules: [{allow: owner}]) {
id: ID!
metricType: MetricEnum
value: Float
triademetricID: ID! #index(name: "byTriadeMetric")
semitones: Int
}
When I try to create a new record using
const triadeMetric = await DataStore.save(new TriadeMetric({}));
I got this warning message:
[{"errorType":"Unauthorized","message":"Not Authorized to access onCreateTriade on type Triade"}]}
and this error:
{"errors":[{"errorType":"Unauthorized to access onCreateTriade on type Triade"}]}
I was using the wrong authentification type:
In aws-exports.js
I replaced "aws_appsync_authenticationType": "API_KEY"
with "aws_appsync_authenticationType": "AMAZON_COGNITO_USER_POOLS"

Amplify datastore "Unauthorized" error on custom auth identityClaim

When I change the identityClaim field in my model, I got the error ""Unauthorized","message":"Not Authorized to access..." when I try to start Datastore in the app.
But, it works as expected when I run the query in AWS AppSync.(It saves the groupID in owner field)
Here is the configuration:
type Book
#model
#auth(rules: [{ allow: owner, identityClaim: "custom:groupID" }]) {
id: ID!
name: String!
owner: Strin
}
i had this same issue and resolved it by using the graphql_headers Amplify.config option to override the default datastore Authorization header. it was using the Access token by default, but to use a custom cognito attribute as the identity claim, you need to use the ID token, because those custom attributes aren’t present on the Access token (i documented all the gory details in a GitHub issue). in my app, it looks like:
Amplify.configure({
...awsconfig,
// https://github.com/aws-amplify/amplify-cli/issues/3794
graphql_headers: async () => {
try {
const token = (await Auth.currentSession()).getIdToken().getJwtToken();
return { Authorization: token };
} catch (e) {
console.error(e);
return {};
}
},
});
note that your owner field has a typo (Strin → String), but i’m guessing that’s just a copy/paste issue.

Amplify JS API GraphQL Elasticsearch throws "ResolverExecutionLimitReached" error

I've implemented the Amplify JS Library with a Vue project and have had success with all of the features of the library except this issue. When I query a model with Elasticsearch, it returns the appropriate results, but also the error of "ResolverExecutionLimitReached".
This is the request:
let destinations = await API.graphql(graphqlOperation(queries.searchDestinations, {filter: { deviceId: { eq: params.id }}}))
This is the schema:
type Destination
#model
#searchable
#auth(rules: [{ allow: public }, { allow: private }])
#key(name: "byXpoint", fields: ["xpoint"])
#key(name: "byDevice", fields: ["deviceId"])
{
id: ID!
index: Int!
levels: [String]
name: String!
xpoint: String
sourceId: ID
Source: Source #connection
lock: Boolean
breakaway: Boolean
breakaways: String
probeId: ID!
probe: Probe #connection(fields: ["probeId"])
deviceId: ID!
device: Device #connection(fields: ["deviceId"])
orgId: ID!
org: Org #connection(fields: ["orgId"])
}
And this returns:
{
data: {
searchDestinations: {items: Array(100), nextToken: "ba1dc119-2266-4567-9b83-f7eee4961e63", total: 384}
},
errors: [
{
data: null
errorInfo: null
errorType: "ResolverExecutionLimitReached"
locations: []
message: "Resolver invocation limit reached."
path: []
}
]
}
My understanding is the AppSync API has a hard limit of returning more than 1000 entries, but this query is on a table with only ~600 entries and is only returning 384. I am executing the same command via AppSync directly via a NodeJS application and it works without issue.
Not sure where to investigate further to determine what is triggering this error. Any help or direction is greatly appreciated.
Connections in the schema were causing the single request to go beyond the 1000 request limit (exactly as stated by Mickers in the comments). Updated schema with less connections on fetch and issue was resolved.

Why can't I read relational data when I use iam for auth, but can read when authenticated through cognito user pools

My project uses cognito user pools as the default authentication method and also uses iam for my custom graphql lambda resolver.
I've been using the AppSync console to run tests on my queries/mutations.
I have a many-to-many relationship between User and Group types which I've implemented in this schema.graphql file.
type User
#model
#auth(
rules: [
{ allow: owner, ownerField: "id", operations: [create, update, delete] }
{ allow: private, provider: iam, operations: [read, update, delete] }
{ allow: private, provider: userPools, operations: [read] }
]
) {
id: ID!
displayName: String!
groups: [GroupMemberLink] #connection(keyName: "byMember", fields: ["id"])
}
type Group
#model
#auth(
rules: [
{ allow: owner, ownerField: "members", operations: [create, update, delete] }
{ allow: private, provider: iam, operations: [read, update, delete] }
{ allow: private, provider: userPools, operations: [read] }
]
) {
id: ID!
name: String!
members: [String]!
associated: [GroupMemberLink] #connection(keyName: "byGroup", fields: ["id"])
}
type GroupMemberLink
#model(queries: null, subscriptions: null)
#key(name: "byGroup", fields: ["groupID", "memberID"])
#key(name: "byMember", fields: ["memberID", "groupID"])
#auth(
rules: [
{ allow: private, provider: userPools, operations: [read] }
# what am I doing wrong below?
{ allow: private, provider: iam, operations: [create, read, update, delete] }
]
) {
id: ID!
groupID: ID!
memberID: ID!
group: Group! #connection(fields: ["groupID"])
member: User! #connection(fields: ["memberID"])
}
My Intentions:
To only allow my lambda function (using iam) to both read and do mutations (create/update/delete)
To allow users authenticated with cognito user pools to only read.
My Problem:
My lambda function is not able to read this relational type/field when I query either from the User or Group type. It also seems like users are able to create this type of object which is something I absolutely do not want.
What am I doing wrong? I understand that multi-auth was recently added so this might be tricky.
Reading the documentation hasn't helped me much so I've been trying many different combinations of rules and hoping one would work.
Update: I get this error whenever I try to access the connected field on either the User or Group type: Not Authorized to access items on type ModelGroupMemberLinkConnection" from the appsync console using iam as the auth type.
To clarify: users authenticated with cognito user pools have both read/write access (Shouldn't have write access), but my lambda function using iam doesn't have read or write access.
Things I've tried that still result in not being to access the related field while being authenticated with iam:
Remove the auth directive altogether.
Changed the auth rule in GroupMemberLink to #auth(rules: [{ allow: private, provider: iam, operations: [read, update, delete] }])
Update:
These are the queries I've been testing in the AppSync console:
query GetUser {
getUser(id: "funksouldev") {
id
displayName
groups {
items {
group {
id
name
}
}
}
}
}
query GetGroup($groupID: ID!) {
getGroup(id: $groupID) {
id
associated {
items {
id
member {
id
displayName
}
}
}
}
}
Okay, Finally I think this would solve the problem.
type ModelGroupMemberLinkConnection #aws_iam
#aws_cognito_user_pools
{
items: [GroupMemberLink]
nextToken: String
}

Error: Resolver associated with data sources

I'm having the serverless error:
Resolver associated with data sources when building from serverless.yml config file:
# serverless.yml
...
mappingTemplates:
- dataSource: Wallet
type: Query
field: walletFromId
request: "_dynamo-get-wallet.txt"
response: "_generic-result-response.txt"
- dataSource: Wallet
type: Query
field: walletsFromUser
request: "_dynamo-get-wallets-from-user.txt"
response: "_generic-result-response.txt"
- dataSource: Wallet
type: Mutation
field: registerWallet
request: "_dynamo-put-wallet.txt"
response: "_generic-result-response.txt"
dataSources:
- type: AMAZON_DYNAMODB
name: Wallet
description: 'Wallet DataSource'
config:
tableName: "${self:custom.stage}-Wallet"
serviceRoleArn: "arn:aws:iam::${self:custom.accountId}:role/${self:custom.appSync.serviceRole}"
...
I also have a schema.graphql:
type Query {
# query the wallet with given id and get the output with detail info
walletFromId(walletId: String!): Wallet!
# query wallets with given user id and get list of cards
walletsFromUser(userId: String!): [Wallet!]!
}
type Mutation {
# Add a wallet to an existing user
registerWallet(userId: String!, number: String!, cvx: String!, expirationDate: String!): Wallet!
}
type Wallet {
walletId: String!
userId: String!
number: String!
cvx: String!
expirationDate: String!
}
type Subscription {
addWallet: Wallet
#aws_subscribe(mutations: ["registerWallet"])
}
schema {
query: Query
mutation: Mutation
subscription: Subscription
}
I could not find a single clue as to what this error mean, and there isn't anything else I can get from the build logs.
This error usually means you are trying to delete a data source that is currently being used by a resolver. If you can identify the resolver pointing to the data source and delete it then you should no longer see the error message.

Resources