Skip to content

Commit

Permalink
chore: supporting missing auth config options (#5011)
Browse files Browse the repository at this point in the history
  • Loading branch information
Jordan-Nelson authored and Nika Hassani committed Jun 13, 2024
1 parent 6671f1f commit 1f1552b
Show file tree
Hide file tree
Showing 4 changed files with 203 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import 'package:amplify_core/amplify_core.dart';
import 'package:amplify_core/src/config/amplify_outputs/auth/mfa.dart';
import 'package:amplify_core/src/config/amplify_outputs/auth/oauth_outputs.dart';
import 'package:amplify_core/src/config/amplify_outputs/auth/password_policy.dart';
import 'package:meta/meta.dart';

part 'auth_outputs.g.dart';

Expand All @@ -19,6 +20,7 @@ class AuthOutputs
required this.awsRegion,
this.userPoolId,
this.userPoolClientId,
this.appClientSecret,
this.identityPoolId,
this.passwordPolicy,
this.oauth,
Expand All @@ -42,6 +44,14 @@ class AuthOutputs
/// The Cognito User Pool Client ID.
final String? userPoolClientId;

/// A fixed string that must be used in all API requests to the app client
/// if the the app client has one configured.
///
/// Note: This attribute is not part of the Amplify Outputs schema.
/// This exists for backwards compatibility with the Gen 1 config.
@internal
final String? appClientSecret;

/// The Cognito Identity Pool ID.
final String? identityPoolId;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import 'package:amplify_core/amplify_core.dart';
import 'package:amplify_core/src/config/amplify_outputs/auth/identity_provider.dart';
import 'package:amplify_core/src/config/amplify_outputs/auth/oauth_response_type.dart';
import 'package:meta/meta.dart';

part 'oauth_outputs.g.dart';

Expand All @@ -19,7 +20,11 @@ class OAuthOutputs
required this.domain,
required this.scopes,
required this.redirectSignInUri,
this.redirectSignInUriQueryParameters,
required this.redirectSignOutUri,
this.redirectSignOutUriQueryParameters,
this.tokenUri,
this.tokenUriQueryParameters,
required this.responseType,
});

Expand All @@ -38,9 +43,39 @@ class OAuthOutputs
/// URIs used to redirect after signing in using an identity provider.
final List<String> redirectSignInUri;

/// Optional query params in the sign in URI.
///
/// Note: This attribute is not part of the Amplify Outputs schema.
/// This exists for backwards compatibility with the Gen 1 config.
@internal
final Map<String, String>? redirectSignInUriQueryParameters;

/// URIs used to redirect after signing out.
final List<String> redirectSignOutUri;

/// Optional query params in the sign in URI.
///
/// Note: This attribute is not part of the Amplify Outputs schema.
/// This exists for backwards compatibility with the Gen 1 config.
@internal
final Map<String, String>? redirectSignOutUriQueryParameters;

/// The OAuth token URI.
///
/// Defaults to '/oauth2/token'.
///
/// Note: This attribute is not part of the Amplify Outputs schema.
/// This exists for backwards compatibility with the Gen 1 config.
@internal
final String? tokenUri;

/// Optional query params in the OAuth token URI.
///
/// Note: This attribute is not part of the Amplify Outputs schema.
/// This exists for backwards compatibility with the Gen 1 config.
@internal
final Map<String, String>? tokenUriQueryParameters;

/// {@macro amplify_core.amplify_outputs.oauth_response_type}
final OAuthResponseType responseType;

Expand Down
11 changes: 9 additions & 2 deletions packages/amplify_core/lib/src/config/auth/auth_config.dart
Original file line number Diff line number Diff line change
Expand Up @@ -111,13 +111,19 @@ class AuthConfig extends AmplifyPluginConfigMap {
final oAuthConfig = plugin?.oAuth;
final identityProviders =
plugin?.socialProviders?.map((p) => p.toIdentityProvider()).toList();
final oauth = oAuthConfig != null && identityProviders != null
final oauth = oAuthConfig != null
? OAuthOutputs(
identityProviders: identityProviders,
identityProviders: identityProviders ?? [],
domain: oAuthConfig.webDomain,
scopes: oAuthConfig.scopes,
redirectSignInUri: oAuthConfig.signInRedirectUri.split(','),
redirectSignInUriQueryParameters:
oAuthConfig.signInUriQueryParameters,
redirectSignOutUri: oAuthConfig.signOutRedirectUri.split(','),
redirectSignOutUriQueryParameters:
oAuthConfig.signOutUriQueryParameters,
tokenUri: oAuthConfig.tokenUri,
tokenUriQueryParameters: oAuthConfig.tokenUriQueryParameters,
// Amplify Flutter only supports responseType:code
// "response_type" is set to "code" by `getAuthorizationUrl` from
// pkg:oauth2
Expand All @@ -129,6 +135,7 @@ class AuthConfig extends AmplifyPluginConfigMap {
awsRegion: region,
userPoolId: userPool?.poolId,
userPoolClientId: userPool?.appClientId,
appClientSecret: userPool?.appClientSecret,
identityPoolId: identityPool?.poolId,
passwordPolicy: passwordPolicy,
oauth: oauth,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'dart:convert';

import 'package:amplify_core/amplify_core.dart';
import 'package:amplify_core/src/config/amplify_outputs/auth/oauth_outputs.dart';
import 'package:test/test.dart';

import './data/amplify_outputs.g.dart' as outputs;
Expand Down Expand Up @@ -43,46 +44,7 @@ void main() {
});

test('maps config with multiple api plugins', () async {
// hand written config for testing purposes.
const config = '''
{
"api": {
"plugins": {
"awsAPIPlugin": {
"data1": {
"endpointType": "GraphQL",
"endpoint": "fake-data-url-1",
"region": "us-east-1",
"authorizationType": "AWS_IAM",
"apiKey": "fake-data-api-key"
},
"data2": {
"endpointType": "GraphQL",
"endpoint": "fake-data-url-2",
"region": "us-east-1",
"authorizationType": "AWS_IAM",
"apiKey": "fake-data-api-key"
},
"rest1": {
"endpointType": "REST",
"endpoint": "fake-rest-url-1",
"region": "us-east-1",
"authorizationType": "AWS_IAM",
"apiKey": "fake-data-api-key"
},
"rest2": {
"endpointType": "REST",
"endpoint": "fake-rest-url-2",
"region": "us-east-1",
"authorizationType": "AWS_IAM",
"apiKey": "fake-data-api-key"
}
}
}
}
}
''';
final configJson = jsonDecode(config) as Map<String, Object?>;
final configJson = jsonDecode(multiApiConfig) as Map<String, Object?>;
final amplifyConfig = AmplifyConfig.fromJson(configJson);
final mappedOutputs = amplifyConfig.toAmplifyOutputs();
expect(mappedOutputs.data?.length, 2);
Expand All @@ -92,9 +54,156 @@ void main() {
expect(dataUrls, ['fake-data-url-1', 'fake-data-url-2']);
expect(restUrls, ['fake-rest-url-1', 'fake-rest-url-2']);
});

test('maps config with all oauth options', () async {
final configJson = jsonDecode(oauthConfig) as Map<String, Object?>;
final amplifyConfig = AmplifyConfig.fromJson(configJson);
final mappedOutputs = amplifyConfig.toAmplifyOutputs();
final oauth = mappedOutputs.auth?.oauth as OAuthOutputs;
expect(oauth.redirectSignInUri, containsAll([signInUri1, signInUri2]));
expect(
oauth.redirectSignInUriQueryParameters,
{signInQueryParamKey: signInQueryParamValue},
);
expect(oauth.redirectSignOutUri, containsAll([signOutUri1, signOutUri2]));
expect(
oauth.redirectSignOutUriQueryParameters,
{signOutQueryParamKey: signOutQueryParamValue},
);
expect(oauth.tokenUri, tokenUri);
expect(
oauth.tokenUriQueryParameters,
{tokenQueryParamKey: tokenQueryParamValue},
);
expect(oauth.scopes, containsAll([scope1, scope2]));
});

test('maps config with app client secret', () async {
final configJson = jsonDecode(clientSecretConfig) as Map<String, Object?>;
final amplifyConfig = AmplifyConfig.fromJson(configJson);
final mappedOutputs = amplifyConfig.toAmplifyOutputs();
expect(mappedOutputs.auth?.appClientSecret, appClientSecret);
});
});
}

/// hand written config with multiple Rest and GraphQL objects
const multiApiConfig = '''{
"api": {
"plugins": {
"awsAPIPlugin": {
"data1": {
"endpointType": "GraphQL",
"endpoint": "fake-data-url-1",
"region": "us-east-1",
"authorizationType": "AWS_IAM",
"apiKey": "fake-data-api-key"
},
"data2": {
"endpointType": "GraphQL",
"endpoint": "fake-data-url-2",
"region": "us-east-1",
"authorizationType": "AWS_IAM",
"apiKey": "fake-data-api-key"
},
"rest1": {
"endpointType": "REST",
"endpoint": "fake-rest-url-1",
"region": "us-east-1",
"authorizationType": "AWS_IAM",
"apiKey": "fake-data-api-key"
},
"rest2": {
"endpointType": "REST",
"endpoint": "fake-rest-url-2",
"region": "us-east-1",
"authorizationType": "AWS_IAM",
"apiKey": "fake-data-api-key"
}
}
}
}
}
''';

const oAuthDomain = 'fake-web-domain-dev.auth.us-east-1.amazoncognito.com';
const signInUri1 = 'fake-sign-in-uri-1';
const signInUri2 = 'fake-sign-in-uri-2';
const signInQueryParamKey = 'fake-sign-in-query-param-key';
const signInQueryParamValue = 'fake-sign-in-query-param-value';
const signOutUri1 = 'fake-sign-ou-uri-1';
const signOutUri2 = 'fake-sign-out-uri-2';
const signOutQueryParamKey = 'fake-sign-out-query-param-key';
const signOutQueryParamValue = 'fake-sign-out-query-param-value';
const tokenUri = 'fake-token-uri';
const tokenQueryParamKey = 'fake-token-query-param-key';
const tokenQueryParamValue = 'fake-token-query-param-value';
const scope1 = 'scope1';
const scope2 = 'scope2';

/// hand written config with all oauth options including those not par of the
/// AmplifyOutputs schema (SignInURIQueryParameters, SignOutURIQueryParameters,
/// TokenURI, and TokenURIQueryParameters)
const oauthConfig = '''{
"auth": {
"plugins": {
"awsCognitoAuthPlugin": {
"CognitoUserPool": {
"Default": {
"PoolId": "us-east-fake-pool-id",
"AppClientId": "fake-client-id",
"Region": "us-east-1"
}
},
"Auth": {
"Default": {
"OAuth": {
"WebDomain": "$oAuthDomain",
"AppClientId": "fake-client-id",
"SignInRedirectURI": "$signInUri1,$signInUri2",
"SignInURIQueryParameters": {
"$signInQueryParamKey": "$signInQueryParamValue"
},
"SignOutRedirectURI": "$signOutUri1,$signOutUri2",
"SignOutURIQueryParameters": {
"$signOutQueryParamKey": "$signOutQueryParamValue"
},
"TokenURI": "$tokenUri",
"TokenURIQueryParameters": {
"$tokenQueryParamKey": "$tokenQueryParamValue"
},
"Scopes": [
"$scope1",
"$scope2"
]
}
}
}
}
}
}
}''';

const appClientSecret = 'fake-app-client-secret';

/// hand written config with app client secret
const clientSecretConfig = '''{
"auth": {
"plugins": {
"awsCognitoAuthPlugin": {
"CognitoUserPool": {
"Default": {
"PoolId": "us-east-fake-pool-id",
"AppClientId": "fake-client-id",
"AppClientSecret": "$appClientSecret",
"Region": "us-east-1"
}
}
}
}
}
}''';

/// Updates the Gen 1 Config to work around known issues
///
/// Issues:
Expand Down

0 comments on commit 1f1552b

Please sign in to comment.