Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Not Authorized to access on type Mutation - 2 #2970

Open
chrisbonifacio opened this issue Oct 21, 2024 · 9 comments
Open

Not Authorized to access on type Mutation - 2 #2970

chrisbonifacio opened this issue Oct 21, 2024 · 9 comments
Assignees
Labels
bug Something isn't working Gen 2

Comments

@chrisbonifacio
Copy link
Member

chrisbonifacio commented Oct 21, 2024

Amplify CLI Version

N/A

Question

Keep in mind I replaced some sensitive info with placeholders.

Here is the schema(schema.ql.ts) auto generated using this npx ampx generate schema-from-database --connection-uri-secret SQL_CONNECTION_STRING --out amplify/data/schema.sql.ts.

/* eslint-disable */
/* THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. */
import { a } from "@aws-amplify/data-schema";
import { configure } from "@aws-amplify/data-schema/internals";
import { secret } from "@aws-amplify/backend";

export const schema = configure({
    database: {
        identifier: "DATABASE_IDENTIFIER", // Placeholder for database identifier
        engine: "postgresql",
        connectionUri: secret("YOUR_SQL_CONNECTION_STRING"), // Placeholder for SQL connection string
        vpcConfig: {
            vpcId: "YOUR_VPC_ID", // Placeholder for VPC ID
            securityGroupIds: [
                "YOUR_SECURITY_GROUP_ID_1", // Placeholder for Security Group ID 1
                "YOUR_SECURITY_GROUP_ID_2"  // Placeholder for Security Group ID 2
            ],
            subnetAvailabilityZones: [
                {
                    subnetId: "YOUR_SUBNET_ID_1", // Placeholder for Subnet ID 1
                    availabilityZone: "YOUR_AVAILABILITY_ZONE_1" // Placeholder for Availability Zone 1
                },
                {
                    subnetId: "YOUR_SUBNET_ID_2", // Placeholder for Subnet ID 2
                    availabilityZone: "YOUR_AVAILABILITY_ZONE_2" // Placeholder for Availability Zone 2
                },
                {
                    subnetId: "YOUR_SUBNET_ID_3", // Placeholder for Subnet ID 3
                    availabilityZone: "YOUR_AVAILABILITY_ZONE_3" // Placeholder for Availability Zone 3
                },
                {
                    subnetId: "YOUR_SUBNET_ID_4", // Placeholder for Subnet ID 4
                    availabilityZone: "YOUR_AVAILABILITY_ZONE_4" // Placeholder for Availability Zone 4
                },
                {
                    subnetId: "YOUR_SUBNET_ID_5", // Placeholder for Subnet ID 5
                    availabilityZone: "YOUR_AVAILABILITY_ZONE_5" // Placeholder for Availability Zone 5
                },
                {
                    subnetId: "YOUR_SUBNET_ID_6", // Placeholder for Subnet ID 6
                    availabilityZone: "YOUR_AVAILABILITY_ZONE_6" // Placeholder for Availability Zone 6
                }
            ]
        }
    }
}).schema({
    "demographic_data": a.model({
        demographic_data_id: a.integer().required(),
        user_id: a.integer().required(),
        country: a.string(),
        state: a.string(),
        tribe: a.string(),
        height: a.integer(),
        weight: a.integer(),
        sex: a.string(),
        ethnic_group: a.string(),
        physical_activity_level: a.string(),
        smoking_history: a.string(),
        occupational_exposure: a.string(),
        previous_disease: a.string(),
        respiratory_medication_use: a.string(),
        pregnant: a.string()
    }).identifier([
        "demographic_data_id"
    ]),
    "test": a.model({
        test_id: a.integer().required(),
        source_id: a.integer().required(),
        user_name: a.string().required(),
        user_id: a.integer(),
        created_timestamp: a.string(),
        note: a.string(),
        input_filename: a.string(),
        demographic_data_id: a.integer()
    }).identifier([
        "test_id"
    ]),
    "test_data": a.model({
        test_data_id: a.integer().required(),
        test_id: a.integer().required(),
        source_id: a.integer().required(),
        time_stamp: a.string().required(),
        type: a.string(),
        fev1: a.float(),
        fvc: a.float(),
        fev1_over_fvc: a.float(),
        ivc: a.float(),
        pef: a.float(),
        heart_rate: a.float(),
        pressure: a.float(),
        air_quality: a.float(),
        co2: a.float()
    }).identifier([
        "test_data_id"
    ]),
    "user": a.model({
        user_id: a.integer().required(),
        email: a.string(),
        first: a.string(),
        last: a.string(),
        date_of_birth: a.date()
    }).identifier([
        "user_id"
    ])
});

Here is my data/resource.ts

import { type ClientSchema, a, defineData } from "@aws-amplify/backend";
import { websiteEmbed } from "../functions/website-embed/resource";
// Import the generated schema for your PostgreSQL database
import { schema as generatedSqlSchema } from './schema.sql';

// Define your existing schema (websiteEmbed ) 
const websiteEmbed Schema = a.schema({
  websiteEmbed: a
    .query()
    .arguments({
      email: a.string(),
      visualId: a.string(),
    })
    .returns(a.string())
    .handler(a.handler.function(websiteEmbed ))
    .authorization((allow) => allow.authenticated()),
});

// Wrap the generated SQL schema and add authentication authorization
const testSchema = generatedSqlSchema.authorization((allow) => allow.authenticated());

// Combine the schemas
const combinedSchema = a.combine([websiteEmbed Schema, testSchema]);

// Define the client schema type for both combined schemas
export type Schema = ClientSchema<typeof combinedSchema>;

// Define data with combined schema
export const data = defineData({
  schema: combinedSchema,
  authorizationModes: {
    defaultAuthorizationMode: "userPool",
  },
});

Here is my front end code:

import React, { useState, useEffect } from 'react';
import type { Schema } from './../../amplify/data/resource';
import { generateClient } from 'aws-amplify/api';

const YourComponent: React.FC = () => {
  const [events, setEvents] = useState<any[]>([]);
  const [loading, setLoading] = useState<boolean>(true);
  const [error, setError] = useState<string | null>(null);
  const client = generateClient<Schema>();

  useEffect(() => {
    const fetchEvents = async () => {
      try {
        const response = await client.models.demographic_data.list();
        console.log('API Response:', response);

        // Check if response has a 'data' property and set it accordingly
        if (Array.isArray(response.data)) {
          setEvents(response.data);
        } else {
          setEvents([]);
        }
      } catch (err) {
        console.error('Error fetching events:', err);
        setError('Failed to fetch events');
      } finally {
        setLoading(false);
      }
    };

    fetchEvents();
  }, [client]);

  if (loading) return <p>Loading...</p>;
  if (error) return <p>{error}</p>;

  return (
    <div>
      <h1>Test Data</h1>
      {events.length > 0 ? (
        <ul>
          {events.map((event, index) => (
            <li key={index}>{JSON.stringify(event)}</li>
          ))}
        </ul>
      ) : (
        <p>No events found.</p>
      )}
    </div>
  );
};

export default YourComponent;

I know this might be overkill but I want to provide as much as I can.

I think this might have been what you were looking for. I just posted the queries file. I used this command to generate it npx ampx generate graphql-client-code --format graphql-codegen --statement-target typescript --out ./src/graphql/. Not really sure how this file is then referenced...

API.ts

/* tslint:disable */
/* eslint-disable */
// this is an auto generated file. This will be overwritten

import * as APITypes from "./API";
type GeneratedQuery<InputType, OutputType> = string & {
  __generatedQueryInput: InputType;
  __generatedQueryOutput: OutputType;
};

export const getDemographic_data = /* GraphQL */ `query GetDemographic_data($demographic_data_id: Int!) {
  getDemographic_data(demographic_data_id: $demographic_data_id) {
    country
    demographic_data_id
    ethnic_group
    height
    occupational_exposure
    physical_activity_level
    pregnant
    previous_disease
    respiratory_medication_use
    sex
    smoking_history
    state
    tribe
    user_id
    weight
    __typename
  }
}
` as GeneratedQuery<
  APITypes.GetDemographic_dataQueryVariables,
  APITypes.GetDemographic_dataQuery
>;
export const getTest = /* GraphQL */ `query GetTest($test_id: Int!) {
  getTest(test_id: $test_id) {
    created_timestamp
    demographic_data_id
    input_filename
    note
    source_id
    test_id
    user_id
    user_name
    __typename
  }
}
` as GeneratedQuery<APITypes.GetTestQueryVariables, APITypes.GetTestQuery>;
export const getTest_data = /* GraphQL */ `query GetTest_data($test_data_id: Int!) {
  getTest_data(test_data_id: $test_data_id) {
    air_quality
    co2
    fev1
    fev1_over_fvc
    fvc
    heart_rate
    ivc
    pef
    pressure
    source_id
    test_data_id
    test_id
    time_stamp
    type
    __typename
  }
}
` as GeneratedQuery<
  APITypes.GetTest_dataQueryVariables,
  APITypes.GetTest_dataQuery
>;
export const getUser = /* GraphQL */ `query GetUser($user_id: Int!) {
  getUser(user_id: $user_id) {
    date_of_birth
    email
    first
    last
    user_id
    __typename
  }
}
` as GeneratedQuery<APITypes.GetUserQueryVariables, APITypes.GetUserQuery>;
export const listDemographic_data = /* GraphQL */ `query ListDemographic_data(
  $demographic_data_id: Int
  $filter: ModelDemographic_dataFilterInput
  $limit: Int
  $nextToken: String
  $sortDirection: ModelSortDirection
) {
  listDemographic_data(
    demographic_data_id: $demographic_data_id
    filter: $filter
    limit: $limit
    nextToken: $nextToken
    sortDirection: $sortDirection
  ) {
    items {
      country
      demographic_data_id
      ethnic_group
      height
      occupational_exposure
      physical_activity_level
      pregnant
      previous_disease
      respiratory_medication_use
      sex
      smoking_history
      state
      tribe
      user_id
      weight
      __typename
    }
    nextToken
    __typename
  }
}
` as GeneratedQuery<
  APITypes.ListDemographic_dataQueryVariables,
  APITypes.ListDemographic_dataQuery
>;
export const listTest_data = /* GraphQL */ `query ListTest_data(
  $filter: ModelTest_dataFilterInput
  $limit: Int
  $nextToken: String
  $sortDirection: ModelSortDirection
  $test_data_id: Int
) {
  listTest_data(
    filter: $filter
    limit: $limit
    nextToken: $nextToken
    sortDirection: $sortDirection
    test_data_id: $test_data_id
  ) {
    items {
      air_quality
      co2
      fev1
      fev1_over_fvc
      fvc
      heart_rate
      ivc
      pef
      pressure
      source_id
      test_data_id
      test_id
      time_stamp
      type
      __typename
    }
    nextToken
    __typename
  }
}
` as GeneratedQuery<
  APITypes.ListTest_dataQueryVariables,
  APITypes.ListTest_dataQuery
>;
export const listTests = /* GraphQL */ `query ListTests(
  $filter: ModelTestFilterInput
  $limit: Int
  $nextToken: String
  $sortDirection: ModelSortDirection
  $test_id: Int
) {
  listTests(
    filter: $filter
    limit: $limit
    nextToken: $nextToken
    sortDirection: $sortDirection
    test_id: $test_id
  ) {
    items {
      created_timestamp
      demographic_data_id
      input_filename
      note
      source_id
      test_id
      user_id
      user_name
      __typename
    }
    nextToken
    __typename
  }
}
` as GeneratedQuery<APITypes.ListTestsQueryVariables, APITypes.ListTestsQuery>;
export const listUsers = /* GraphQL */ `query ListUsers(
  $filter: ModelUserFilterInput
  $limit: Int
  $nextToken: String
  $sortDirection: ModelSortDirection
  $user_id: Int
) {
  listUsers(
    filter: $filter
    limit: $limit
    nextToken: $nextToken
    sortDirection: $sortDirection
    user_id: $user_id
  ) {
    items {
      date_of_birth
      email
      first
      last
      user_id
      __typename
    }
    nextToken
    __typename
  }
}
` as GeneratedQuery<APITypes.ListUsersQueryVariables, APITypes.ListUsersQuery>;
export const quicksightEmbed = /* GraphQL */ `query QuicksightEmbed($email: String, $visualId: String) {
  quicksightEmbed(email: $email, visualId: $visualId)
}
` as GeneratedQuery<
  APITypes.QuicksightEmbedQueryVariables,
  APITypes.QuicksightEmbedQuery
>;

@blipps199
Copy link

@chrisbonifacio I was able to get rid of the error by adding the authorization here: const testSchema = generatedSqlSchema.authorization((allow) => allow.authenticated()); but the query literally returns nothing. There is definitely data. I can query it just fine from AppSync and the Amplify console. Using the front end code above.

@chrisbonifacio
Copy link
Member Author

chrisbonifacio commented Oct 22, 2024

Hi @blipps199 ! thanks for the update. Can you check the network request that is being made from your application and share what the graphql query looks like? I'm curious to see the headers, input variables, the selection set (fields to be returned in the response), and how they compare to the AppSync console query.

@blipps199
Copy link

blipps199 commented Oct 22, 2024

@chrisbonifacio After doing a bit more digging I can query and get data back... but not from a list query. Only from get queries where I have to filter using a specific id for the record. I haven't tried a mutation yet but that will be soon.

@blipps199
Copy link

blipps199 commented Oct 22, 2024

@chrisbonifacio Here is the payload.

{"query":"query ($demographic_data_id: Int, $sortDirection: ModelSortDirection, $filter: ModelDemographic_dataFilterInput, $limit: Int, $nextToken: String) {\n listDemographic_data(\n demographic_data_id: $demographic_data_id\n sortDirection: $sortDirection\n filter: $filter\n limit: $limit\n nextToken: $nextToken\n ) {\n items {\n demographic_data_id\n user_id\n country\n state\n tribe\n height\n weight\n sex\n ethnic_group\n physical_activity_level\n smoking_history\n occupational_exposure\n previous_disease\n respiratory_medication_use\n pregnant\n }\n nextToken\n __typename\n }\n}\n","variables":{}}

When I tried to run this query through AppSync it told me sortDirection is not supported for List operations without a Sort key defined.

Once I removed that I was able to run the query. Wondering if this is what the issue is.

@blipps199
Copy link

@chrisbonifacio Could this be from postgres not having a sortkey field?

@chrisbonifacio
Copy link
Member Author

chrisbonifacio commented Oct 22, 2024

@blipps199 I'm not sure but this sounds like a potential duplicate of this other issue I was able to reproduce:

#2946

@chrisbonifacio
Copy link
Member Author

In the meantime, until we fix this bug, you should be able to use client.graphql to perform a list query with a custom graphql string.

If you want to generate graphql statements, you can use the following CLI command:

https://docs.amplify.aws/react/reference/cli-commands/#npx-ampx-generate-graphql-client-code

@blipps199
Copy link

blipps199 commented Oct 22, 2024

Thanks @chrisbonifacio. I was able to take my generated queries file, dupe it so I can make edits, removed sortDirection, imported the query, and use client.graphql to run the query. Its not nearly as clean but it works I suppose. Would you have any idea when this bug fix would be on the roadmap? I would really love to use client.models.model_name.list.

@chrisbonifacio chrisbonifacio added bug Something isn't working and removed data-schema question Further information is requested investigating labels Oct 24, 2024
@sundersc
Copy link
Contributor

sundersc commented Nov 6, 2024

@blipps199 Fix for #2946 has been published. The next time you make a deployment, you should receive the fix automatically. Could you check if this addresses your issue?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working Gen 2
Projects
None yet
Development

No branches or pull requests

3 participants