aws-amplify / amplify-js

A declarative JavaScript library for application development using cloud services.
https://docs.amplify.aws/lib/q/platform/js
Apache License 2.0
9.43k stars 2.13k forks source link

Does graphql client support IAM? #12931

Closed johnf closed 8 months ago

johnf commented 9 months ago

Before opening, please confirm:

JavaScript Framework

Next.js

Amplify APIs

GraphQL API

Amplify Version

v6

Amplify Categories

api

Backend

Amplify CLI

Environment information

``` # Put output below this line System: OS: Linux 6.7 Ubuntu 23.10 23.10 (Mantic Minotaur) CPU: (32) x64 AMD Ryzen 9 7950X 16-Core Processor Memory: 42.20 GB / 61.95 GB Container: Yes Shell: 5.2.15 - /bin/bash Binaries: Node: 20.11.0 - /tmp/xfs-e6e7c4c1/node Yarn: 4.0.2 - /tmp/xfs-e6e7c4c1/yarn npm: 10.2.4 - ~/.nvm/versions/node/v20.11.0/bin/npm bun: 1.0.22 - ~/.bun/bin/bun Watchman: 4.9.0 - /usr/bin/watchman Browsers: Chrome: 121.0.6167.139 npmPackages: @amplitude/analytics-react-native: ^1.4.7 => 1.4.7 @aws-amplify/react-native: ^1.0.13 => 1.0.13 @aws-amplify/rtn-web-browser: ^1.0.13 => 1.0.13 @aws-sdk/client-cognito-identity: ^3.502.0 => 3.502.0 @babel/cli: ^7.23.9 => 7.23.9 @babel/core: ^7.23.9 => 7.23.9 @babel/eslint-parser: ^7.23.9 => 7.23.9 @babel/preset-env: ^7.23.9 => 7.23.9 @babel/preset-typescript: ^7.23.3 => 7.23.3 @babel/runtime: ^7.23.9 => 7.23.9 @faker-js/faker: ^8.4.0 => 8.4.0 @googlemaps/polyline-codec: ^1.0.28 => 1.0.28 @gorhom/bottom-sheet: ^4.6.0 => 4.6.0 @hookform/resolvers: ^3.3.4 => 3.3.4 @hookform/resolvers/ajv: 1.0.0 @hookform/resolvers/arktype: 1.0.0 @hookform/resolvers/class-validator: 1.0.0 @hookform/resolvers/computed-types: 1.0.0 @hookform/resolvers/io-ts: 1.0.0 @hookform/resolvers/joi: 1.0.0 @hookform/resolvers/nope: 1.0.0 @hookform/resolvers/superstruct: 1.0.0 @hookform/resolvers/typanion: 1.0.0 @hookform/resolvers/typebox: 1.0.0 @hookform/resolvers/valibot: 1.0.0 @hookform/resolvers/vest: 1.0.0 @hookform/resolvers/yup: 1.0.0 @hookform/resolvers/zod: 1.0.0 @intercom/intercom-react-native: ^6.4.0 => 6.4.0 @notifee/react-native: ^7.8.2 => 7.8.2 @react-native-async-storage/async-storage: ^1.21.0 => 1.21.0 @react-native-camera-roll/camera-roll: ^7.4.0 => 7.4.0 @react-native-clipboard/clipboard: ^1.13.2 => 1.13.2 @react-native-community/blur: ^4.4.0 => 4.4.0 @react-native-community/netinfo: ^11.2.1 => 11.2.1 @react-native-community/slider: ^4.5.0 => 4.5.0 @react-native-firebase/app: ^18.8.0 => 18.8.0 @react-native-firebase/messaging: ^18.8.0 => 18.8.0 @react-native/babel-preset: 0.73.20 => 0.73.20 (0.73.19) @react-native/eslint-config: 0.73.2 => 0.73.2 @react-native/metro-config: 0.73.3 => 0.73.3 @react-native/typescript-config: 0.73.1 => 0.73.1 @react-navigation/drawer: ^6.6.6 => 6.6.6 @react-navigation/native: ^6.1.9 => 6.1.9 @react-navigation/stack: ^6.3.20 => 6.3.20 @reeq/react-native-passkit: ^0.1.3 => 0.1.3 @rnx-kit/align-deps: ^2.3.3 => 2.3.3 @rnx-kit/babel-preset-metro-react-native: ^1.1.6 => 1.1.6 @rnx-kit/cli: ^0.16.22 => 0.16.22 @rnx-kit/metro-config: ^1.3.14 => 1.3.14 @rnx-kit/metro-resolver-symlinks: ^0.1.34 => 0.1.34 @sentry/cli: ^2.26.0 => 2.26.0 (2.25.2) @sentry/react-native: ^5.17.0 => 5.17.0 @stripe/stripe-react-native: ^0.35.1 => 0.35.1 @survicate/react-native-survicate: https://github.com/johnf/react-native-survicate.git#add-events => 3.0.2 @tanstack/eslint-plugin-query: ^5.17.22 => 5.17.22 @tanstack/query-codemods: 4.24.3 @tanstack/react-query: ^5.17.19 => 5.17.19 @total-typescript/ts-reset: ^0.5.1 => 0.5.1 @types/base-64: ^1.0.2 => 1.0.2 @types/google.maps: ^3.55.1 => 3.55.1 @types/qrcode: ^1.5.5 => 1.5.5 @types/react: ^18.2.48 => 18.2.48 @types/react-native-get-random-values: ^1.8.2 => 1.8.2 @types/react-native-vector-icons: ^6.4.18 => 6.4.18 @types/react-native-version-check: ^3.4.8 => 3.4.8 @types/react-test-renderer: ^18.0.7 => 18.0.7 @types/survicate__react-native-survicate: ^1.1.2 => 1.1.2 @types/uuid: ^9.0.8 => 9.0.8 @typescript-eslint/eslint-plugin: ^6.20.0 => 6.20.0 (5.62.0) @typescript-eslint/parser: ^6.20.0 => 6.20.0 (5.62.0) HelloWorld: 0.0.1 appcenter-cli: ^2.14.0 => 2.14.0 awesome-phonenumber: ^6.4.0 => 6.4.0 aws-amplify: ^6.0.13 => 6.0.13 aws-amplify/adapter-core: undefined () aws-amplify/analytics: undefined () aws-amplify/analytics/kinesis: undefined () aws-amplify/analytics/kinesis-firehose: undefined () aws-amplify/analytics/personalize: undefined () aws-amplify/analytics/pinpoint: undefined () aws-amplify/api: undefined () aws-amplify/api/server: undefined () aws-amplify/auth: undefined () aws-amplify/auth/cognito: undefined () aws-amplify/auth/cognito/server: undefined () aws-amplify/auth/enable-oauth-listener: undefined () aws-amplify/auth/server: undefined () aws-amplify/datastore: undefined () aws-amplify/in-app-messaging: undefined () aws-amplify/in-app-messaging/pinpoint: undefined () aws-amplify/push-notifications: undefined () aws-amplify/push-notifications/pinpoint: undefined () aws-amplify/storage: undefined () aws-amplify/storage/s3: undefined () aws-amplify/storage/s3/server: undefined () aws-amplify/storage/server: undefined () aws-amplify/utils: undefined () babel-jest: ^29.7.0 => 29.7.0 babel-loader: ^9.1.3 => 9.1.3 babel-plugin-inline-import: ^3.0.0 => 3.0.0 babel-plugin-module-resolver: ^5.0.0 => 5.0.0 babel-plugin-react-native-web: ^0.19.10 => 0.19.10 base-64: ^1.0.0 => 1.0.0 currency-symbol-map: ^5.1.0 => 5.1.0 dayjs: ^1.11.10 => 1.11.10 eslint: ^8.56.0 => 8.56.0 eslint-config-airbnb: ^19.0.4 => 19.0.4 eslint-config-airbnb-typescript: ^17.1.0 => 17.1.0 eslint-config-prettier: ^9.1.0 => 9.1.0 (8.10.0) eslint-import-resolver-alias: ^1.1.2 => 1.1.2 eslint-import-resolver-typescript: ^3.6.1 => 3.6.1 eslint-plugin-import: ^2.29.1 => 2.29.1 eslint-plugin-jsx-a11y: ^6.8.0 => 6.8.0 eslint-plugin-react: ^7.33.2 => 7.33.2 eslint-plugin-react-hooks: ^4.6.0 => 4.6.0 (5.0.0-canary-7118f5dd7-20230705) eslint-plugin-react-native: ^4.1.0 => 4.1.0 eslint-plugin-security-node: ^1.1.4 => 1.1.4 getstream: ^8.4.1 => 8.4.1 icon-set-creator: ^1.2.6 => 1.2.6 is-european: ^1.0.7 => 1.0.7 jest: ^29.7.0 => 29.7.0 jotai: ^2.6.3 => 2.6.3 knip: ^4.2.3 => 4.2.3 minisearch: ^6.3.0 => 6.3.0 nativewind: ^4.0.23 => 4.0.23 patch-package: ^8.0.0 => 8.0.0 postinstall-postinstall: ^2.1.0 => 2.1.0 qrcode: ^1.5.3 => 1.5.3 query-string: ^8.1.0 => 8.1.0 (7.1.3) react: ^18.2.0 => 18.2.0 react-dom: ^18.2.0 => 18.2.0 react-hook-form: ^7.49.3 => 7.49.3 react-native: ^0.73.2 => 0.73.2 react-native-avoid-softinput: ^5.0.0 => 5.0.0 react-native-bootsplash: ^5.3.0 => 5.3.0 react-native-branch: ^6.0.0 => 6.0.0 react-native-calendars: ^1.1303.0 => 1.1303.0 react-native-clean-project: ^4.0.3 => 4.0.3 react-native-code-push: ^8.2.1 => 8.2.1 react-native-confirmation-code-field: ^7.3.2 => 7.3.2 react-native-country-codes-picker: ^2.3.5 => 2.3.5 react-native-date-picker: ^4.3.5 => 4.3.5 react-native-device-info: ^10.12.0 => 10.12.0 react-native-dotenv: ^3.4.9 => 3.4.9 react-native-dropdown-picker: ^5.4.6 => 5.4.6 react-native-geolocation-service: ^5.3.1 => 5.3.1 react-native-gesture-handler: ^2.14.1 => 2.14.1 react-native-get-random-values: ^1.10.0 => 1.10.0 react-native-image-crop-picker: ^0.40.2 => 0.40.2 react-native-inappbrowser-reborn: ^3.7.0 => 3.7.0 react-native-linear-gradient: ^2.8.3 => 2.8.3 react-native-localize: ^3.0.6 => 3.0.6 react-native-maps: ^1.10.0 => 1.10.0 react-native-permissions: ^4.1.0 => 4.1.0 react-native-reanimated: ^3.6.2 => 3.6.2 react-native-reanimated-skeleton: ^1.5.0 => 1.5.0 react-native-safe-area-context: ^4.8.2 => 4.8.2 react-native-screens: ^3.29.0 => 3.29.0 react-native-share: ^10.0.2 => 10.0.2 react-native-svg: ^14.1.0 => 14.1.0 react-native-toast-notifications: ^3.4.0 => 3.4.0 react-native-url-polyfill: ^2.0.0 => 2.0.0 react-native-vector-icons: ^10.0.3 => 10.0.3 react-native-version-check: ^3.4.7 => 3.4.7 react-native-web: ^0.19.10 => 0.19.10 react-test-renderer: 18.2.0 => 18.2.0 tailwindcss: ^3.4.1 => 3.4.1 typescript: ^5.3.3 => 5.3.3 uuid: ^9.0.1 => 9.0.1 (8.3.2, 7.0.3, 3.4.0) webpack: ^5.90.0 => 5.90.0 webpack-cli: ^5.1.4 => 5.1.4 (4.9.2) yup: ^1.3.3 => 1.3.2 yup-phone: ^1.3.2 => 1.3.2 zod: ^3.22.4 => 3.22.4 npmGlobalPackages: @aws-amplify/cli: 12.10.1 corepack: 0.23.0 npm: 10.2.4 ```

Describe the bug

I've kicked off a new next.js app to use an existing amplify backend I have.

According to the documentation at https://docs.amplify.aws/react/build-a-backend/graphqlapi/connect-to-api/ it reads like IAM is a supported authentication mechanism.

However I get the following error

 {
  data: {},
  errors: [
    UnauthorizedException: Unknown error
        at buildRestApiServiceError (webpack-internal:///(rsc)/../../node_modules/@aws-amplify/api-rest/dist/esm/utils/serviceError.mjs:17:26)
        at parseRestApiServiceError (webpack-internal:///(rsc)/../../node_modules/@aws-amplify/api-rest/dist/esm/utils/serviceError.mjs:30:26)
        at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
        at async job (webpack-internal:///(rsc)/../../node_modules/@aws-amplify/api-rest/dist/esm/utils/createCancellableOperation.mjs:31:23)
        at async GraphQLAPIClass._graphql (webpack-internal:///(rsc)/../../node_modules/@aws-amplify/api-graphql/dist/esm/internals/InternalGraphQLAPI.mjs:246:44)
        at async runWithAmplifyServerContext (webpack-internal:///(rsc)/../../node_modules/aws-amplify/dist/esm/adapterCore/runWithAmplifyServerContext.mjs:23:24)
        at async findByHandle (webpack-internal:///(rsc)/../../src/models/User.ts:108:22)
        at async Home (webpack-internal:///(rsc)/./src/app/profiles/[handle]/page.tsx:17:21) {
      recoverySuggestion: `If you're calling an Amplify-generated API, make sure to set the "authMode" in generateClient({ authMode: '...' }) to the backend authorization rule's auth provider ('apiKey', 'userPool', 'iam', 'oidc', 'lambda')`
    }
  ]

I've traced the code paths and from what I can tell when authMode is set to IAM, it simply creates credentials from the userpool. It never looks at AWS_PROFILE or even AWS_ACCESS_KEY_ID

Is IAM actually supported?

Expected behavior

Request completes successfully

Reproduction steps

As per documentation at https://docs.amplify.aws/react/build-a-backend/graphqlapi/connect-to-api/

Code Snippet

import { Amplify } from 'aws-amplify';
import { generateServerClientUsingCookies } from '@aws-amplify/adapter-nextjs/api';
import { cookies } from 'next/headers';

import config from '@/amplifyconfiguration.json';
Amplify.configure(config);

const cookiesClient = generateServerClientUsingCookies({
  config,
  cookies,
  authMode: 'iam',
});

console.debug('cookiesClient', cookiesClient);

Log output

``` // Put your logs below this line ⨯ { data: {}, errors: [ UnauthorizedException: Unknown error at buildRestApiServiceError (webpack-internal:///(rsc)/../../node_modules/@aws-amplify/api-rest/dist/esm/utils/serviceError.mjs:17:26) at parseRestApiServiceError (webpack-internal:///(rsc)/../../node_modules/@aws-amplify/api-rest/dist/esm/utils/serviceError.mjs:30:26) at process.processTicksAndRejections (node:internal/process/task_queues:95:5) at async job (webpack-internal:///(rsc)/../../node_modules/@aws-amplify/api-rest/dist/esm/utils/createCancellableOperation.mjs:31:23) at async GraphQLAPIClass._graphql (webpack-internal:///(rsc)/../../node_modules/@aws-amplify/api-graphql/dist/esm/internals/InternalGraphQLAPI.mjs:246:44) at async runWithAmplifyServerContext (webpack-internal:///(rsc)/../../node_modules/aws-amplify/dist/esm/adapterCore/runWithAmplifyServerContext.mjs:23:24) at async findByHandle (webpack-internal:///(rsc)/../../src/models/User.ts:108:22) at async Home (webpack-internal:///(rsc)/./src/app/profiles/[handle]/page.tsx:17:21) { recoverySuggestion: `If you're calling an Amplify-generated API, make sure to set the "authMode" in generateClient({ authMode: '...' }) to the backend authorization rule's auth provider ('apiKey', 'userPool', 'iam', 'oidc', 'lambda')` } ] } ⨯ [Error: Error: [object Object]] { digest: '193452068' } ```

aws-exports.js

No response

Manual configuration

No response

Additional configuration

No response

Mobile Device

No response

Mobile Operating System

No response

Mobile Browser

No response

Mobile Browser Version

No response

Additional information and screenshots

No response

johnf commented 9 months ago

Also I think this error message is confusing.

      recoverySuggestion: `If you're calling an Amplify-generated API, make sure to set the "authMode" in generateClient({ authMode: '...' }) to the backend authorization rule's auth provider ('apiKey', 'userPool', 'iam', 'oidc', 'lambda')`

as it can mean authMode isn't set or permission is simply denied

cwomack commented 9 months ago

Hey there, @johnf 👋. I'm not sure what the shape of your config looks like that's being imported, but can you check if the region/endpoint look proper and the value for the defaultAuthMode is set to 'iam' within that file? And just to confirm, did you set up all your backend resources via the CLI?

cwomack commented 9 months ago

@johnf, after looking at this a little more... have an additional question or two. The code snippet you have in the config looks valid and you can assign a default Auth mode at the client level. But are you trying to use an existing IAM role that had been set up prior to this project? How did you configure the IAM role associated with this app?

We'll support IAM roles that are vended from Cognito Identity Pools, but not any manually configured/arbitrary IAM roles.

johnf commented 9 months ago

@cwomack I wrote the below before reading your last sentence :)

I'm trying to use a manually configured IAM role. My use case is SSR and server compoents for a nexst.js app. (NOTE: I think I've just understood what generateServerClientUsingCookies and guessing it gets the browser to pass the creds through using cookies. However, that would require some major changes to the auth model for my app so I wanted to handle it all with backend smarts for now)

Is there any reason that amplify doesn't support IAM roles, it would mean the library could more easily be used in lambda, and this complicated part of the docs could be removed https://docs.amplify.aws/react/build-a-backend/graphqlapi/connect-from-server-runtime/#iam-authorization

Also, possibly dumb question, if iam is using the cognito pool, how is it different from userPool?

Old Response

Below are two scripts, the first manually signs the request and works, the second uses amplify and doesn't work.

I'm calling the scripts like this

AWS_PROFILE=work ./manual.ts
AWS_PROFILE=work ./amplify.ts

The AWS profile, in my case, is SSO using wrapaws2, but I've also tested by explicitly setting AWS_ACCESS_KEY_ID etc

I've added the relevant snippets of my amplifyconfigration.json below as well. This was built using amplify G1.

From my code tracing it looks like amplify.Auth.fetchAuthSession(); is called when iam is set and generates a noauth role from the cognito pool.

I've grepped through the amplify code base and I can't find anything in api-graphql or api-rest that tries to sign the HTTP requests with a v4 signature. I might be missing something though.

Manual

#!/usr/bin/env bun

import config from '@/amplifyconfiguration.json';

import { GraphQLClient } from 'graphql-request';

import { Sha256 } from '@aws-crypto/sha256-js';
import { defaultProvider } from '@aws-sdk/credential-provider-node';
import { SignatureV4 } from '@aws-sdk/signature-v4';
import { HttpRequest } from '@aws-sdk/protocol-http';

const GRAPHQL_ENDPOINT = config.aws_appsync_graphqlEndpoint;
const AWS_REGION = config.aws_appsync_region;

export const signedFetch = async (url: RequestInfo | URL, options: RequestInit = {}) => {
  const endpoint = url instanceof URL ? url : new URL(typeof url === 'string' ? url : url.url);

  const signer = new SignatureV4({
    credentials: defaultProvider(),
    region: AWS_REGION,
    service: 'appsync',
    sha256: Sha256,
  });

  const headers = {
    ...options.headers,
    'Content-Type': 'application/json',
    host: endpoint.host,
  } as Record<string, string>;

  const requestToBeSigned = new HttpRequest({
    method: options.method,
    headers,
    hostname: endpoint.host,
    body: options.body,
    path: endpoint.pathname,
  });

  const signed = await signer.sign(requestToBeSigned);

  return fetch(url, { ...options, ...signed });
};

const client = new GraphQLClient(GRAPHQL_ENDPOINT, { fetch: signedFetch } as ConstructorParameters<
  typeof GraphQLClient
>[1]);

const graphql = async ({ query, variables }: { query: string; variables: Record<string, any> }) => {
  const response = await client.request(query, variables);
  return response;
};

export const getUserByHandle = /* GraphQL */ `
  query UserByHandle($handle: String!) {
    userByHandle(handle: $handle) {
      items {
        id
      }
    }
  }
`;

const test = async () => {
  const response = await graphql({
    query: getUserByHandle,
    variables: { handle: 'johnf' },
  });

  console.debug(JSON.stringify(response, null, 2));
};

test();

Amplify

#!/usr/bin/env bun

import { Amplify } from 'aws-amplify';
import { generateClient } from 'aws-amplify/api';

import config from '@/amplifyconfiguration.json';

Amplify.configure(config);

const client = generateClient({ authMode: 'iam' });

export const getUserByHandle = /* GraphQL */ `
  query UserByHandle($handle: String!) {
    userByHandle(handle: $handle) {
      items {
        id
      }
    }
  }
`;

const test = async () => {
  const response = await client.graphql({
    query: getUserByHandle,
    variables: { handle: 'johnf' },
  });

  console.debug(response);
};

test();

amplifyconfiguration.json

{
  "aws_project_region": "ap-southeast-2",
  "aws_appsync_graphqlEndpoint": "https://XXX.appsync-api.ap-southeast-2.amazonaws.com/graphql",
  "aws_appsync_region": "ap-southeast-2",
  "aws_appsync_authenticationType": "AMAZON_COGNITO_USER_POOLS",
  "aws_cognito_identity_pool_id": "ap-southeast-2:XXX",
  "aws_cognito_region": "ap-southeast-2",
  "aws_user_pools_id": "ap-southeast-2_XXX",
}
chrisbonifacio commented 9 months ago

Hi @johnf apologies for the delay. It looks like you're missing the ssr: true config option when calling Amplify.configure. Have you tried changing it to the following?

Amplify.configure(config, { ssr: true })

Also, you can set the authMode in the request of the cookie based client itself.

  const response = await graphql({
    query: getUserByHandle,
    variables: { handle: 'johnf' },
    authMode: 'iam'
  });
johnf commented 9 months ago

@chrisbonifacio I posted the wrong code above for the amplify code example above. I've fixed that now.

So I finally have it solved but let me provide some feedback.

Documentation Improvements.

The docs should give more detail on the differences between iam vs userpools. Something like

The SSR docs should say something to the effect that the backend is supposed to use the SSR Cookie provider so that it runs in the same context as the user. (I was treating it like my backend lambda functions which was most of why I went down this rabbit hole)

Unauthenticated users

Is there a good way to mix unauthenticated users and authenticated users? e.g. in a next.js app, think of a twitter clone. I want unauthenticated users to be able to read a users tweets, but need to be logged in for DMs.

I think right now the answer is that you need to use different functions for noauth vs auth users and set the authMode to iam vs userPool.

It would be great if amplify auto fell back to iam if there were no userpool credentials in the cookie. Right now it just sends a request with no auth headers at all.

asp3 commented 8 months ago

+1 on falling back to IAM if there are no userpool credentials

chrisbonifacio commented 8 months ago

The original issue here seems to do with using public iam as an auth mode on the server side. We identified there was an issue in the library causing such requests to fail.

We have a tagged release that you can use to test whether it resolves your issue. Please note these are not meant for production, only for verification.

Install these packages and versions in your project and let us know if it fixes the issue for you.

npm i aws-amplify@6.0.16-iam-auth-server.ebba1a4.0 @aws-amplify/adapter-nextjs@1.0.16-iam-auth-server.ebba1a4.0
cwomack commented 8 months ago

Updating this issue to indicate that it's a bug, not a setup issue or question. Fix is linked above, and until this is merged/released please refer to @chrisbonifacio comment above.

johnf commented 8 months ago

@chrisbonifacio When I try using the fixed modules I get

Import trace for requested module:
../../src/models/User.ts
./src/app/profiles/[handle]/page.tsx
 ⨯ ../../src/core/graphql.web.ts:1:0
Module not found: Can't resolve '@aws-amplify/adapter-nextjs/api'
> 1 | import { generateServerClientUsingCookies } from '@aws-amplify/adapter-nextjs/api';
  2 |
  3 | // import '@/core/amplify';
  4 | import config from '@/amplifyconfiguration.json';

https://nextjs.org/docs/messages/module-not-found
chrisbonifacio commented 8 months ago

Hi @johnf I realized the way I provided the install commands was broken because there was a newline and that might've prevented the second package, @aws-amplify/adapter-nextjs, from getting installed correctly.

This is the correct formatting, try this and confirm that it is installed. You might have to use --force if you run into a ERESOLVE overriding peer dependency error.

npm i aws-amplify@6.0.16-iam-auth-server.ebba1a4.0 @aws-amplify/adapter-nextjs@1.0.16-iam-auth-server.ebba1a4.0
chrisbonifacio commented 8 months ago

Thank you everyone for reporting this issue, your patience is appreciated! Closing this issue as the fix was just released. Please upgrade to v6.0.17.

rexwreyes commented 7 months ago

@chrisbonifacio I am still getting this issue with v6.0.20 and adapter v1.0.20