Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -53,16 +53,65 @@ void main() {
dependencyManager
..addInstance<NativeAuthBridge>(
MockNativeAuthBridge(
signInWithUrl: expectAsync4((
argUrl,
argCallbackurlscheme,
argPreferprivatesession,
argBrowserpackagename,
) async {
expect(argUrl, contains(mockConfig.auth?.oauth?.domain));
expect(argCallbackurlscheme, testUrlScheme);
expect(argPreferprivatesession, isFalse);
expect(argBrowserpackagename, browserPackage);
signInWithUrl: expectAsync1((argSignInOut) async {
expect(
argSignInOut.url,
contains(mockConfig.auth?.oauth?.domain),
);
expect(argSignInOut.callbackurlscheme, testUrlScheme);
expect(argSignInOut.preferprivatesession, isFalse);
expect(argSignInOut.browserPackageName, browserPackage);
return {'code': 'code', 'state': 'state'};
}),
),
)
..addInstance<Dispatcher<AuthEvent, AuthState>>(
const MockDispatcher(),
);
await platform.signIn(options: options);
});

asyncTest('signInWithUrl with OIDC parameters', (_) async {
const options = CognitoSignInWithWebUIPluginOptions(
isPreferPrivateSession: false,
browserPackageName: browserPackage,
nonce: 'nonce',
language: 'en',
loginHint: 'username',
prompt: [
CognitoSignInWithWebUIPrompt.login,
CognitoSignInWithWebUIPrompt.consent,
],
resource: 'myapp://',
);
dependencyManager
..addInstance<NativeAuthBridge>(
MockNativeAuthBridge(
signInWithUrl: expectAsync1((argSignInOut) async {
expect(
argSignInOut.url,
contains(mockConfig.auth?.oauth?.domain),
);
expect(argSignInOut.callbackurlscheme, testUrlScheme);
expect(argSignInOut.preferprivatesession, isFalse);
expect(argSignInOut.browserPackageName, browserPackage);
expect(argSignInOut.nonce, 'nonce');
expect(argSignInOut.language, 'en');
expect(argSignInOut.loginHint, 'username');
expect(argSignInOut.prompt, isNotNull);
expect(
argSignInOut.prompt?.contains(
CognitoSignInWithWebUIPrompt.login.value,
),
isTrue,
);
expect(
argSignInOut.prompt?.contains(
CognitoSignInWithWebUIPrompt.consent.value,
),
isTrue,
);
expect(argSignInOut.resource, 'myapp://');
return {'code': 'code', 'state': 'state'};
}),
),
Expand All @@ -81,16 +130,14 @@ void main() {
dependencyManager
..addInstance<NativeAuthBridge>(
MockNativeAuthBridge(
signOutWithUrl: expectAsync4((
argUrl,
argCallbackurlscheme,
argPreferprivatesession,
argBrowserpackagename,
) async {
expect(argUrl, contains(mockConfig.auth?.oauth?.domain));
expect(argCallbackurlscheme, testUrlScheme);
expect(argPreferprivatesession, isFalse);
expect(argBrowserpackagename, browserPackage);
signOutWithUrl: expectAsync1((argSignInOut) async {
expect(
argSignInOut.url,
contains(mockConfig.auth?.oauth?.domain),
);
expect(argSignInOut.callbackurlscheme, testUrlScheme);
expect(argSignInOut.preferprivatesession, isFalse);
expect(argSignInOut.browserPackageName, browserPackage);
}),
),
)
Expand All @@ -103,13 +150,31 @@ void main() {
);
}

typedef SignInOutFn<T> =
Future<T> Function(
String argUrl,
String argCallbackurlscheme,
bool argPreferprivatesession,
String? argBrowserpackagename,
);
class SignInOut {
SignInOut(
this.url,
this.callbackurlscheme,
this.preferprivatesession,
this.browserPackageName,
this.nonce,
this.language,
this.loginHint,
this.prompt,
this.resource,
);

String url = '';
String callbackurlscheme = '';
bool preferprivatesession = false;
String? browserPackageName;
String? nonce;
String? language;
String? loginHint;
List<String>? prompt;
String? resource;
}

typedef SignInOutFn<T> = Future<T> Function(SignInOut signInOut);

class MockNativeAuthBridge extends Fake implements NativeAuthBridge {
MockNativeAuthBridge({
Expand All @@ -127,12 +192,24 @@ class MockNativeAuthBridge extends Fake implements NativeAuthBridge {
String argCallbackurlscheme,
bool argPreferprivatesession,
String? argBrowserpackagename,
String? argNonce,
String? argLanguage,
String? argLoginHint,
List<String>? argPrompt,
String? argResource,
) async {
return _signInWithUrl?.call(
argUrl,
argCallbackurlscheme,
argPreferprivatesession,
argBrowserpackagename,
SignInOut(
argUrl,
argCallbackurlscheme,
argPreferprivatesession,
argBrowserpackagename,
argNonce,
argLanguage,
argLoginHint,
argPrompt,
argResource,
),
) ??
(throw UnimplementedError());
}
Expand All @@ -145,10 +222,17 @@ class MockNativeAuthBridge extends Fake implements NativeAuthBridge {
String? argBrowserpackagename,
) async {
return _signOutWithUrl?.call(
argUrl,
argCallbackurlscheme,
argPreferprivatesession,
argBrowserpackagename,
SignInOut(
argUrl,
argCallbackurlscheme,
argPreferprivatesession,
argBrowserpackagename,
null,
null,
null,
null,
null,
),
) ??
(throw UnimplementedError());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,11 @@ class HostedUiPlatformImpl extends io.HostedUiPlatformImpl {
signInRedirectUri.scheme,
options.isPreferPrivateSession,
options.browserPackageName,
options.nonce,
options.language,
options.loginHint,
options.prompt?.map((obj) => obj.value).toList(),
options.resource,
);
dispatcher
.dispatch(
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,11 @@ final class ThrowingNativeBridge extends Fake implements NativeAuthBridge {
String arg_callbackUrlScheme,
bool arg_preferPrivateSession,
String? arg_browserPackageName,
String? arg_nonce,
String? arg_language,
String? arg_loginHint,
List<String>? arg_prompt,
String? arg_resource,
) async {
throw PlatformException(code: 'CANCELLED');
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export 'src/model/signin/cognito_confirm_sign_in_plugin_options.dart';
export 'src/model/signin/cognito_sign_in_plugin_options.dart';
export 'src/model/signin/cognito_sign_in_result.dart';
export 'src/model/signin/cognito_sign_in_with_web_ui_plugin_options.dart';
export 'src/model/signin/cognito_sign_in_with_web_ui_plugin_options_prompt.dart';
export 'src/model/signout/cognito_sign_out_plugin_options.dart';
export 'src/model/signout/cognito_sign_out_result.dart';
export 'src/model/signup/cognito_confirm_sign_up_plugin_options.dart';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

import 'package:amplify_auth_cognito_dart/amplify_auth_cognito_dart.dart';
import 'package:amplify_core/amplify_core.dart';
// ignore: implementation_imports
import 'package:amplify_core/src/config/amplify_outputs/auth/oauth_outputs.dart';
Expand All @@ -26,7 +27,10 @@ extension HostedUiConfig on OAuthOutputs {
/// References:
/// - https://docs.aws.amazon.com/cognito/latest/developerguide/authorization-endpoint.html
/// - https://docs.aws.amazon.com/cognito/latest/developerguide/login-endpoint.html
Uri signInUri([AuthProvider? provider]) {
Uri signInUri([
AuthProvider? provider,
CognitoSignInWithWebUIPluginOptions? options,
]) {
Uri baseUri;
// ignore: invalid_use_of_internal_member
if (this.signInUri != null) {
Expand All @@ -35,9 +39,20 @@ extension HostedUiConfig on OAuthOutputs {
} else {
baseUri = _webDomain.replace(path: '/oauth2/authorize');
}

final nonce = options?.nonce;
final language = options?.language;
final loginHint = options?.loginHint;
final prompt = options?.prompt?.map((obj) => obj.value).toList().join(' ');
final resource = options?.resource;
return baseUri.replace(
queryParameters: <String, String>{
if (provider != null) 'identity_provider': provider.uriParameter,
if (nonce != null) 'nonce': nonce,
if (language != null) 'lang': language,
if (loginHint != null) 'login_hint': loginHint,
if (prompt != null) 'prompt': prompt,
if (resource != null) 'resource': resource,
// ignore: invalid_use_of_internal_member
...?signInUriQueryParameters,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,11 @@ abstract class HostedUiPlatform implements Closeable {
@protected
@visibleForTesting
@nonVirtual
Future<Uri> getSignInUri({Uri? redirectUri, AuthProvider? provider}) async {
Future<Uri> getSignInUri({
Uri? redirectUri,
AuthProvider? provider,
CognitoSignInWithWebUIPluginOptions? options,
}) async {
final state = generateState();
final codeVerifier = createCodeVerifier();

Expand All @@ -124,6 +128,7 @@ abstract class HostedUiPlatform implements Closeable {
codeVerifier: codeVerifier,
httpClient: httpClient,
provider: provider,
options: options,
);
final uri = _authCodeGrant!.getAuthorizationUrl(
redirectUri ?? signInRedirectUri,
Expand Down Expand Up @@ -162,12 +167,13 @@ abstract class HostedUiPlatform implements Closeable {
String userPoolClientId, {
String? appClientSecret,
AuthProvider? provider,
CognitoSignInWithWebUIPluginOptions? options,
String? codeVerifier,
http.Client? httpClient,
}) {
return oauth2.AuthorizationCodeGrant(
userPoolClientId,
HostedUiConfig(authOutputs.oauth!).signInUri(provider),
HostedUiConfig(authOutputs.oauth!).signInUri(provider, options),
HostedUiConfig(authOutputs.oauth!).tokenUri,
secret: appClientSecret,
httpClient: httpClient,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,10 @@ class HostedUiPlatformImpl extends HostedUiPlatform {
required CognitoSignInWithWebUIPluginOptions options,
AuthProvider? provider,
}) async {
final signInUrl = (await getSignInUri(provider: provider)).toString();
final signInUrl = (await getSignInUri(
provider: provider,
options: options,
)).toString();
await launchUrl(signInUrl);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ class HostedUiPlatformImpl extends HostedUiPlatform {
try {
final signInUrl = (await getSignInUri(
provider: provider,
options: options,
redirectUri: localServer.uri,
)).toString();
await launchUrl(signInUrl);
Expand Down
Loading
Loading