'How can I implement a chat schema with @manyToMany using Amplify GraphQL with non private/public auth rules?

I was trying to implement a chat feature that has three models; message, user and conversation. A user can have many conversations, a conversation can have many users and a conversation can have many messages.

I tried using @manytomany between the user and conversation models with authenticated rules set to owner, this however fails because of " Not Authorized to access on type error". Im using graphql API (Not Datastore) with cognito user pool.

If I set the allow rule to private then it works but then that would mean that the users in a conversation would have access to each others user model and through that access to other conversations that the users might have.

One could maybe use a query filter and only show the relevant conversations but it would still mean that the user data is accessible to all signed in users. Maybe one could use a lambda function.

The simple explanation however is that my model is incorrect. My question is as follows, how can we create a simple chat with the above three models where the users in a conversation would only have access to the relevant data (messages in a conversation) and not have have access to each others, other conversations and messages.

The chat schema

type User @model @auth(rules: [{ allow: owner }]) {
id:ID!
username: String!
conversations: [Conversation] @manytomany(relationName: "ConversationUser")
}

type Conversation @model @auth(rules: [{ allow: owner }]) {
id: ID!
users: [User] @manytomany(relationName: "ConversationUser")
Messages: [Message] @hasmany(indexName: "byConversation", fields: ["id"])
}

type Message @model @auth(rules: [{ allow: owner }]) {
id: ID!
author: ID!
content: String!
conversationID: ID! @Index(name: "byConversation", sortKeyFields: ["createdAt"])
}

Using Amplify CLI version 8.0.2, with appsync and cognito userpool



Solution 1:[1]

You can add a dynamic user based auth rule that would work for group chats as well and dynamically add the id of this in in the conversation users to the authors array:

type Todo @model @auth(rules: [{ allow: owner, ownerField: "authors" }]) {
  content: String
  authors: [String]
}

As per documentation:

https://docs.amplify.aws/cli/graphql/authorization-rules/#per-user--owner-based-data-access

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 alionthego