0

I am following Hasura basic tutorial on creating a todo app https://hasura.io/learn/graphql/hasura-advanced/introduction/ and want to extend it and have few additional operations, but don't seem to be able. Setup is as in the tutorial - you have Tasks table with title, description, authorId, isComplete, isPublic column. Table permissions are setup as in the tutorial, so a user can only select their own or public tasks. They can also update only their own tasks. Operations I want to add:

  1. Query only public tasks that are NOT theirs (additionally, inverse also - only theirs without public ones).
  2. Mutate public tasks to complete that are not theirs (update isComplete without having permissions to other columns).

I could create views for the first case, but it seems too much of an effort for such a simple logic. I think both cases could simply be done with access to Request Header (x-hasura-user-id) like so:

query PublicTasksOnly {
  tasks(where: {isPublic: {_eq: true}, authorId: {_neq: x-hasura-user-id}}) {
    description
    isComplete
    title
  }
}

But it seems that this is not possible. Any ideas/suggestions how to achieve this?

2 Answers2

0

To my knowledge I do not think it is possible to reference http headers in your graphql queries. Have you tried passing the userId as a variable to the query? Something like the following:

query PublicTasksOnly($userId: String!) {
  tasks(where: {isPublic: {_eq: true}, authorId: {_neq: $userId}}) {
    description
    isComplete
    title
  }
}
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Luke O'Malley
  • 23
  • 1
  • 4
  • Did not try it, but I also though about this approach. Seems like an anti-pattern. Sending duplicate `userId` when you're already using JWT for auth. Also, seems like a security risk - in the second example an authorized user can mutate another users public task by faking `userId` in a request. – Haroldas Valčiukas Nov 08 '22 at 12:32
  • There is no security risk. The userId variable is just used to filter out the allowed data. If you also want to store who mutated the public task to isComplete= true, you can use 'presets' in the permissions to take userId from jwt. – lokesh kumar Dec 01 '22 at 16:16
0

I am not quite sure what you want to achieve but if your problem gets solved by adding this header x-hasura-user-id then I can help you out.

You can copy the graphql endpoint from hasura console and hit simple http request to that endpoint with query and it's variables in request body. Sharing sample code here using http library axios:

   



import axios from 'axios';
axios({
  method: 'post',
  url: 'https://your-hasura-project-url.hasura.app/v1/graphql',
  headers: { 'x-hasura-user-id': '< Your user id >' },
  data: {
    query: `query PublicTasksOnly {
             tasks(where: {isPublic: {_eq: true}}) {
             description
             isComplete
             title
            }
           }`,
    variables: { userId: 'abc-xyz' }
  }
})

This should solve your issue.