How to reference the authenticated user with the entity that is going to be created

Hey, let’s take an example:
If I want to create a Todo, that references to the currently authenticated user(email as the field to uniquely identify and pass in auth headers). Like how can I pass the authenticated user to the owner field of the Todo.
Currently the API explorer is asking me to provide the email of the user in the input field but this would enable any user to create Todos on someone else’s behalf just by editing the mutation.

TLDR; I want to pass the user email from auth headers to todo mutation securely(not by providing the email in the input field)

1 Like

I also have use cases for this. Right now I use the auth directive with an add query rule to make sure the data the user is adding matches the JWT. It would be nice to automate this and be able to add in data from the JWT on a mutation.

FYI, I moved this to the GraphQL category as this affects the graphql endpoint even for users not on Slash GraphQL.

@amaster507 I am trying to add an “add query” inside the auth directive, but I have been getting warnings after hitting deploy, not sure what is wrong. Can you share some resources which elaborate on the “add query” part? FYI: I have gone through your 4-part series on Auth but “add query” part is a little blurry to me.

I didn’t really cover the add auth rules much there.

Do you have an example you are working with so far?

yup, so I want to create an App where users can ask for help from other users. For that purpose, we have two very-basic entities, namely, User and Help.

type User @auth(
    	query: { rule: """query($EMAIL: String!) { 
            		queryUser(filter: { 
                    			email: { eq: $EMAIL }
                    			}) { 
                email 
            } 
            		}"""}
) {
    id: ID!
    email: String! @id
    helps: [Help]
}

type Help @withSubscription @auth(
    ???what goes here???
) {
    id: ID!
    title: String!
    description: String!
    fromUser: User! @hasInverse(field: helps)
}

note: I am using Auth0 in the frontend, so the only way to communicate between the App and Slash is their unique email ids

let me know if you need more clarity

Thanks for your time and consideration @amaster507

FYI: https://dgraph.io/docs/graphql/authorization/mutations/#add

Rules for add authorization state that the rule must hold of nodes created by the mutation data once committed to the database.

Delete rules filter the nodes that can be deleted. A user can only ever delete a subset of the nodes that the delete rules allow.

Currently, Dgraph evaluates update rules before the mutation.

How Dgraph handles update rules would allow a user to take a Help and assign it to a different User, just be aware of this limitation. I have created a feature request to allow for both before and after rules on updates to handle this.


Another issue that may arise with your schema. You are restricting Users so a user can only see their own. If you then try to view the Help.fromUser edge you will get errors because it could return an null edge when it is requried. This is just some of the limitations right now of how auth works and how GraphQL handles required fields. There is no way right now in Dgraph’s generation of the GraphQL schema to make an edge required for mutations but not required for queries to suppress this missing required field error from GraphQL.


Here are a few basic mutation rules to get you started with some comments:

type User @auth(
  query: { rule: "query($EMAIL: String!) { queryUser(filter: { email: { eq: $EMAIL } }) { email } }"}
) {
    id: ID!
    email: String! @id
    helps: [Help]
}

type Help @withSubscription @auth(
  # Users can only add Help if it is from them
  add: { rule: "query($EMAIL: String!) { queryHelp { fromUser(filter: { email: { eq: $EMAIL } }) { email } } }"}
  # Users can only update Help if they created it
  update: { rule: "query($EMAIL: String!) { queryHelp { fromUser(filter: { email: { eq: $EMAIL } }) { email } } }"}
  # Users can only delete their own Help requests
  delete: { rule: "query($EMAIL: String!) { queryHelp { fromUser(filter: { email: { eq: $EMAIL } }) { email } } }"}
) {
    id: ID!
    title: String!
    description: String!
    fromUser: User! @hasInverse(field: helps)
}
2 Likes

Wow, it worked, thank you, really appreciate your efforts. :slightly_smiling_face:

1 Like

Hi @sourabhbagrecha, I guess this is the one @amaster507 is referring to:

We will discuss and update if we plan to work on it, given we have @lambda now.

1 Like

Cool, no problem.
Thanks @abhimanyusinghgaur