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

PaginatedResult<T>.requestForNextResult does not use the authorizationMode from the previous query. #4585

Closed
2 of 14 tasks
naedx opened this issue Mar 20, 2024 · 6 comments
Closed
2 of 14 tasks
Assignees
Labels
auth Issues related to the Auth Category bug Something is not working; the issue has reproducible steps and has been reproduced GraphQL API Issues related to the API (GraphQL) Category pending-release Issues that have been addressed in main but have not been released

Comments

@naedx
Copy link

naedx commented Mar 20, 2024

Description

PaginatedResult<T>.requestForNextResult does not use the authorizationMode from the query that it follows.

This manifests when the first query overrides the authorizationMode by using a custom OIDC Provider to provide the ID Token instead of the Access Token. The subsequent queries using PaginatedResult<T>.requestForNextResult defaults back to the the cognito access token, causing the query to fail.

Categories

  • Analytics
  • API (REST)
  • API (GraphQL)
  • Auth
  • Authenticator
  • DataStore
  • Notifications (Push)
  • Storage

Steps to Reproduce

  1. Create a CustomOIDCProvider to override to provide the ID Token instead of the Access Token provided by the cognito auth plugin by default as described here:
import 'package:amplify_api/amplify_api.dart';
import 'package:amplify_auth_cognito/amplify_auth_cognito.dart';

class CustomOIDCProvider extends OIDCAuthProvider {
  const CustomOIDCProvider();

  @override
  Future<String?> getLatestAuthToken() async {
    final session = await Amplify.Auth.fetchAuthSession() as CognitoAuthSession;
    return session.userPoolTokens?.idToken;
  }
}
  1. Create a function following the List subsequent pages of items example and update it to include the override the AuthorizationMode:
const limit = 100;

Future<List<Todo?>> queryPaginatedListItems() async {
  final firstRequest = ModelQueries.list<Todo>(
    Todo.classType, 
    limit: limit, 
    authorizationMode: APIAuthorizationType.oidc // <=== ID Token override here
  );

  final firstResult = await Amplify.API.query(request: firstRequest).response;
  final firstPageData = firstResult.data;

  // Indicates there are > 100 todos and you can get the request for the next set.
  if (firstPageData?.hasNextResult ?? false) {
    final secondRequest = firstPageData!.requestForNextResult;
    final secondResult =
        await Amplify.API.query(request: secondRequest!).response;
    return secondResult.data?.items ?? <Todo?>[];
  } else {
    return firstPageData?.items ?? <Todo?>[];
  }
}
  1. Execute the first request

  2. Execute the second request using .requestForNextResult from the previous query:

    final secondRequest = firstPageData!.requestForNextResult;
    final secondResult = await Amplify.API.query(request: secondRequest!).response;
  1. Observe that the second query does not use the overridden Authorization key.

Screenshots

No response

Platforms

  • iOS
  • Android
  • Web
  • macOS
  • Windows
  • Linux

Flutter Version

3.19.0

Amplify Flutter Version

1.7.0

Deployment Method

Amplify CLI

Schema

type Todo @model {
  content: String
}
@khatruong2009 khatruong2009 added auth Issues related to the Auth Category GraphQL API Issues related to the API (GraphQL) Category pending-triage This issue is in the backlog of issues to triage labels Mar 20, 2024
@naedx
Copy link
Author

naedx commented Mar 20, 2024

I suspect the issue comes from this line:

 
if (modelType is PaginatedModelType) {
      final filter = request.variables['filter'] as Map<String, dynamic>?;
      final limit = request.variables['limit'] as int?;

      final resultNextToken = dataJson![_nextToken] as String?;
      dynamic requestForNextResult;
      // If result has nextToken property, prepare a request for the next page of results.
      if (resultNextToken != null) {
        final variablesWithNextToken = <String, dynamic>{
          ...request.variables,
          _nextToken: resultNextToken,
        };
        requestForNextResult = GraphQLRequest<T>(                          // <<=================== here (line 97)
          document: request.document,
          decodePath: request.decodePath,
          variables: variablesWithNextToken,
          modelType: request.modelType,
        );
      }
      decodedData = modelType.fromJson(
        dataJson!,
        limit: limit,
        filter: filter,
        requestForNextResult:
            requestForNextResult as GraphQLRequest<PaginatedResult<Model>>?,
      ) as T;
    } else {
      decodedData = modelType.fromJson(dataJson!) as T;
    }
    return GraphQLResponse<T>(data: decodedData, errors: errors);

It omits copying over the authorizationMode from the previous request.

@naedx
Copy link
Author

naedx commented Mar 20, 2024

A workaround to the problem is to copy the requestForNextResultwhile adding in the value for the authorizationMode:

    final nextRequest = result.data?.requestForNextResult?.copyWith(
        authorizationMode: APIAuthorizationType.oidc,
    );

Sidenote:

Currently, ModelQueries.list<T>() accepts several parameters but not the nextToken which forces us to try to use the requestForNextResult value just to perform a paginated request.

@khatruong2009
Copy link
Member

Hi @naedx, thank you for submitting this issue. We'll take a look at it and get back to you when there is an update.

@khatruong2009 khatruong2009 added bug Something is not working; the issue has reproducible steps and has been reproduced Investigating and removed pending-triage This issue is in the backlog of issues to triage labels Mar 21, 2024
@Jordan-Nelson
Copy link
Member

A fix for this was merged an should be included in the next release

@Jordan-Nelson Jordan-Nelson added the pending-release Issues that have been addressed in main but have not been released label Apr 1, 2024
@naedx
Copy link
Author

naedx commented Apr 1, 2024

Awesome, thank you! Looking forward to it.

@NikaHsn
Copy link
Member

NikaHsn commented Apr 17, 2024

Thank you for your patience. The issue has been fixed in version 1.8.0. and I'm closing it. However, if you encounter any issues after updating to version 1.8.0, please don't hesitate to reopen it.

@NikaHsn NikaHsn closed this as completed Apr 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
auth Issues related to the Auth Category bug Something is not working; the issue has reproducible steps and has been reproduced GraphQL API Issues related to the API (GraphQL) Category pending-release Issues that have been addressed in main but have not been released
Projects
None yet
Development

No branches or pull requests

5 participants