aws-amplify / amplify-category-api

The AWS Amplify CLI is a toolchain for simplifying serverless web and mobile development. This plugin provides functionality for the API category, allowing for the creation and management of GraphQL and REST based backends for your amplify project.
https://docs.amplify.aws/
Apache License 2.0
89 stars 77 forks source link

Custom mutation not accessible with IAM #2837

Closed VincentvdE closed 2 weeks ago

VincentvdE commented 2 months ago

Environment information

System:
  OS: macOS 14.6.1
  CPU: (24) arm64 Apple M2 Ultra
  Memory: 117.35 GB / 192.00 GB
  Shell: /bin/zsh
Binaries:
  Node: 18.20.4 - ~/.nvm/versions/node/v18.20.4/bin/node
  Yarn: 1.22.22 - /opt/homebrew/bin/yarn
  npm: 10.7.0 - ~/.nvm/versions/node/v18.20.4/bin/npm
  pnpm: undefined - undefined
NPM Packages:
  @aws-amplify/auth-construct: 1.3.0
  @aws-amplify/backend: 1.1.1
  @aws-amplify/backend-auth: 1.1.3
  @aws-amplify/backend-cli: 1.2.4
  @aws-amplify/backend-data: 1.1.2
  @aws-amplify/backend-deployer: 1.0.6
  @aws-amplify/backend-function: 1.3.3
  @aws-amplify/backend-output-schemas: 1.2.0
  @aws-amplify/backend-output-storage: 1.1.1
  @aws-amplify/backend-secret: 1.0.1
  @aws-amplify/backend-storage: 1.1.2
  @aws-amplify/cli-core: 1.1.2
  @aws-amplify/client-config: 1.2.1
  @aws-amplify/deployed-backend-client: 1.4.0
  @aws-amplify/form-generator: 1.0.1
  @aws-amplify/model-generator: 1.0.5
  @aws-amplify/platform-core: 1.0.6
  @aws-amplify/plugin-types: 1.2.1
  @aws-amplify/sandbox: 1.1.3
  @aws-amplify/schema-generator: 1.2.1
  aws-amplify: 6.5.1
  aws-cdk: 2.153.0
  aws-cdk-lib: 2.153.0
  typescript: 5.5.4
AWS environment variables:
  AWS_STS_REGIONAL_ENDPOINTS = regional
  AWS_NODEJS_CONNECTION_REUSE_ENABLED = 1
  AWS_SDK_LOAD_CONFIG = 1
No CDK environment variables

Describe the bug

A custom mutation ("increment") is not accessible by a Lambda function. Upon checking the generated schema in AppSync, the mutation is missing the @aws_iam directive, which is likely causing the access issue.

Reproduction steps

amplify/data/resource.ts:

import { type ClientSchema, a, defineData } from "@aws-amplify/backend";
  import { postConfirmation } from "../auth/post-confirmation/resource";
  const schema = a
    .schema({
      UserProfile: a
        .model({
          email: a.string(),
          profileOwner: a.string(),
          kdnr: a.integer(),
        })
        .authorization((allow) => [
          allow.ownerDefinedIn("profileOwner"),
        ]),
      AtomicCounter: a
        .model({
          id: a.id(),
          value: a.integer()
        })
        .authorization((allow)=> [
          allow.authenticated()
        ]),
      increment: a
        .mutation()
        .arguments({
          id: a.string().required()
        })
        // return type of the query
        .returns(a.integer())
        .handler(a.handler.custom({
          dataSource: a.ref('AtomicCounter'),
          entry: './increment.js',
        }))
        .authorization((allow)=> [
          allow.authenticated()
        ])
      })
    .authorization((allow) => [allow.resource(postConfirmation)]);

  export type Schema = ClientSchema<typeof schema>

  export const data = defineData({
    schema: schema,
    authorizationModes: {
      defaultAuthorizationMode: "userPool",
      apiKeyAuthorizationMode: {
        expiresInDays: 365,
      },
    },
  });

amplify/data/increment.js

export function request(ctx) {
    return {
      operation: 'UpdateItem',
      key: {
          id: { S: ctx.args.id }
      },
      update: {
        expression: 'ADD #value :one',
        expressionValues: { ':one': { N: 1 } },
        expressionNames: { '#value': 'value' },
      }
    }
  }

  export function response(ctx) {
      return ctx.result.value;
  }

The generated schema looks like this:

  type Mutation {
    increment(id: String!): Int
      @aws_cognito_user_pools
    createUserProfile(input: CreateUserProfileInput!, condition: ModelUserProfileConditionInput): UserProfile
      @aws_iam
  @aws_cognito_user_pools
    updateUserProfile(input: UpdateUserProfileInput!, condition: ModelUserProfileConditionInput): UserProfile
      @aws_iam
  @aws_cognito_user_pools
    deleteUserProfile(input: DeleteUserProfileInput!, condition: ModelUserProfileConditionInput): UserProfile
      @aws_iam
  @aws_cognito_user_pools
    createAtomicCounter(input: CreateAtomicCounterInput!, condition: ModelAtomicCounterConditionInput): AtomicCounter
      @aws_iam
  @aws_cognito_user_pools
    updateAtomicCounter(input: UpdateAtomicCounterInput!, condition: ModelAtomicCounterConditionInput): AtomicCounter
      @aws_iam
  @aws_cognito_user_pools
    deleteAtomicCounter(input: DeleteAtomicCounterInput!, condition: ModelAtomicCounterConditionInput): AtomicCounter
      @aws_iam
  @aws_cognito_user_pools
  }

The increment is missing the "@aws_iam". After manually adding it, it works. Shouldn't the .authorization((allow) => [allow.resource(postConfirmation)]); add that?

ykethan commented 2 months ago

Hey,👋 thanks for raising this! I'm going to transfer this over to our API repository for better assistance 🙂

AnilMaktala commented 1 month ago

Hi @VincentvdE, Apologies for the delay. Thanks for bringing this up. We’re able to reproduce the issue by following the steps outlined in the description, so we’re marking it as a bug for the team to investigate further.

image
github-actions[bot] commented 3 weeks ago

This issue is now closed. Comments on closed issues are hard for our team to see. If you need more assistance, please open a new issue that references this one.

palpatim commented 3 weeks ago

Reopening pending release of fix

palpatim commented 3 weeks ago

We have released this in @aws-amplify/graphql-api-construct@1.15.0, @aws-amplify/data-construct@1.11.0. Update your project dependencies with an npm update to consume the fix.

github-actions[bot] commented 2 weeks ago

This issue is now closed. Comments on closed issues are hard for our team to see. If you need more assistance, please open a new issue that references this one.