maoosi / prisma-appsync

⚡ Turns your ◭ Prisma Schema into a fully-featured GraphQL API, tailored for AWS AppSync.

Home Page:https://prisma-appsync.vercel.app

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Issue: shield rule on model with WhereUniqueInput results in error

jeremy-white opened this issue · comments

Related to issue #87

In a new repository with Prisma-AppSync 1.0.0-rc.5 and Prisma 4.11.0

WIth the extendedWhereUnique preview feature enabled, a model defined as

model User {
  id            String       @id @default(uuid())
  username      String       @unique 
}

and a shield rule of

'{update,upsert,delete}User{,/**}': {
     rule: { id: identity?.sub },
     reason: ({ model }) => `${model} can only be modified by their owner.`,
 },

executing the mutation

mutation updateUser {
  updateUser(where: {id: "10eeced1-80a6-4551-801c-58a884e59c57"}, data: {username: "updated"}) {
    id
  }
}

results in the error

  error: 'Prisma Client validation error. https://www.prisma.io/docs/reference/api-reference/error-reference#prismaclientvalidationerror',
  type: 'INTERNAL_SERVER_ERROR',
  code: 500,
  cause: PrismaClientValidationError: 
  Invalid `prisma.user.update()` invocation:
  
  {
    data: {
      username: 'jw'
    },
    where: {
      AND: [
        {
          id: '10eeced1-80a6-4551-801c-58a884e59c57'
        },
        {
          id: '10eeced1-80a6-4551-801c-58a884e59c57'
        }
      ]
    },
    select: {
      id: true
    }
  }
  
  Argument where of type UserWhereUniqueInput needs at least one argument and at least one argument for id. Available args are listed in green.

As a quick test I've changed the code here

prismaArgs[operator] = {

to be

prismaArgs[operator] = {
    ...prismaArgs[operator],
    AND: [query[operator]],
}

Which allows everything to work as far as I can tell so far, but I'm sure there may be a better way to address it.

Am willing to work on it further and open a PR if that would be of help

+1

I am having the same issue with @unique columns when connecting relationships.

When I do:

mutation UpsertfixtureEvent(
  $dateTime: AWSDateTime
  $eventTypeId: String!
  $reason: String
  $teamFixtureId: String!
  $teamPlayerId: String
  $teamPlayerOffId: String
  $teamStaffId: String
  $id: String!
) {
  upsertFixtureEvent(
    data: {
      id: $id
      dateTime: $dateTime
      eventType: { connect: { id: $eventTypeId } }
      reason: $reason
      teamFixture: { connect: { id: $teamFixtureId } }
      teamPlayer: { connect: { id: $teamPlayerId } }
      teamPlayerOffId: $teamPlayerOffId
      teamStaff: { connect: { id: $teamStaffId } }
    }
    where: { id: $id }
  ) {
    id
  }
}

My model looks like:

/// @gql(subscriptions: null)
/// @auth(mutations: [{ allow: userPools, groups: ["Admin"] }])
model EventType {
  id                String             @id @default(dbgenerated("public.uuid_generate_v4()")) @db.Uuid
  type              String             
  description       String?
  lookup_key        Int                @default(0) @db.SmallInt
  sortOrder         Int                @default(0) @map("sort_order") @db.SmallInt
  fixtureEvents     FixtureEvent[]
  leagueTableEvents LeagueTableEvent[]

  @@map("event_type")
  @@unique([type], map: "event_type_type_unique_key")
}

When I attempt to run this mutation, it complains that 'type' is not supplied for the connect on $eventTypeId. I have tried this as a @@unique and @unique on the property, but both have the same output.

How can I connect a relationship where one of the columns has a unique key simply for data integrity and no for connecting?

@maoosi I was wondering if it was worth me cloning this repo and potentially looking to resolve this as a collaborator, or does it tie in to a bigger story for you at the moment.

We are using this package in our production application, and this is now blocking us on our latest release. I more than happy to play around, just don't want to waste any time if you are aligned to this or have specific sights on what the solution should look like specifically?

@micklaw Happy for you to open a PR.

I don't think the issue has anything to do with shield rules, but what suggested @jeremy-white is a good place to start:

As a quick test I've changed the code here

prisma-appsync/packages/client/src/resolver.ts

Line 34 in 1d9b0f1

to be

prismaArgs[operator] = {
...prismaArgs[operator],
AND: [query[operator]],
}

We just need to make sure it still works with broader use cases and with the extendedWhereUnique preview feature disabled.

@micklaw all other tasks for the 1.0.0-rc.6 release milestone are ready, so I might be able to work on this issue sometime this week. Are you still wanting to contribute, or should I take this one over?

Please take it over, I actually done some testing on my use case and could not duplicate the issue in your test suite, so I think my issue lies in my application code. Thank you.

@jeremy-white I ended up implementing your suggested change. I noticed some edge cases for which Prisma Shield rules will not be able to merge automatically with the existing where conditions, but it should fix the issue for most common use cases already.

@all-contributors please add @jeremy-white for code.