Skip to content

chore(auth): Remove package:oauth2 dependency #3119

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

Closed
wants to merge 5 commits into from
Closed
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 @@ -12,9 +12,8 @@ import 'package:amplify_auth_cognito_dart/src/state/state.dart';
import 'package:amplify_auth_cognito_test/amplify_auth_cognito_test.dart';
import 'package:amplify_auth_integration_test/amplify_auth_integration_test.dart';
import 'package:amplify_flutter/amplify_flutter.dart';
import 'package:aws_common/testing.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:http/http.dart' as http;
import 'package:http/testing.dart';

import 'test_runner.dart';

Expand All @@ -34,8 +33,8 @@ void main() {
dependencyManager = DependencyManager()
..addInstance<CognitoOAuthConfig>(hostedUiConfig)
..addInstance<SecureStorageInterface>(MockSecureStorage())
..addInstance<http.Client>(
MockClient((request) {
..addInstance<AWSHttpClient>(
MockAWSHttpClient((request, isCancelled) {
throw UnimplementedError();
}),
);
Expand All @@ -44,7 +43,7 @@ void main() {

asyncTest('signInWithUrl', (_) async {
const options = CognitoSignInWithWebUIPluginOptions(
isPreferPrivateSession: true,
isPreferPrivateSession: false,
browserPackageName: browserPackage,
);
dependencyManager
Expand All @@ -58,7 +57,7 @@ void main() {
) async {
expect(argUrl, contains(hostedUiConfig.webDomain));
expect(argCallbackurlscheme, testUrlScheme);
expect(argPreferprivatesession, isTrue);
expect(argPreferprivatesession, isFalse);
expect(argBrowserpackagename, browserPackage);
return {'code': 'code', 'state': 'state'};
}),
Expand All @@ -72,7 +71,7 @@ void main() {

asyncTest('signOutWithUrl', (_) async {
const options = CognitoSignInWithWebUIPluginOptions(
isPreferPrivateSession: true,
isPreferPrivateSession: false,
browserPackageName: browserPackage,
);
dependencyManager
Expand All @@ -86,7 +85,7 @@ void main() {
) async {
expect(argUrl, contains(hostedUiConfig.webDomain));
expect(argCallbackurlscheme, testUrlScheme);
expect(argPreferprivatesession, isTrue);
expect(argPreferprivatesession, isFalse);
expect(argBrowserpackagename, browserPackage);
}),
),
Expand Down
2 changes: 1 addition & 1 deletion packages/auth/amplify_auth_cognito/example/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,14 @@ dev_dependencies:
amplify_lints:
path: ../../../amplify_lints
async: ^2.10.0
aws_common: any
aws_signature_v4: any
checks: ^0.2.0
collection: any
flutter_driver:
sdk: flutter
flutter_test:
sdk: flutter
http: ^0.13.5
integration_test:
sdk: flutter
io: ^1.0.0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ include: package:amplify_lints/library.yaml

analyzer:
exclude:
- '**/*.g.dart'
- "**/*.g.dart"
- lib/src/sdk/src/**
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ include: package:amplify_lints/app.yaml

analyzer:
exclude:
- build
- lib/**/*.g.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import 'dart:async';
import 'dart:convert';

import 'package:amplify_api_dart/amplify_api_dart.dart';
import 'package:amplify_auth_cognito_test/amplify_auth_cognito_test.dart';
import 'package:amplify_auth_cognito_test/hosted_ui/hosted_ui_client.dart';
import 'package:amplify_auth_cognito_test/hosted_ui/hosted_ui_common.dart';
Expand Down Expand Up @@ -55,6 +56,7 @@ void main() {
application = await runApp();
addTearDown(application.close);

await Amplify.addPlugin(AmplifyAPIDart());
await Amplify.configure(jsonEncode(config));
addTearDown(Amplify.reset);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import 'dart:async';
import 'dart:convert';
import 'dart:io';

import 'package:amplify_api_dart/amplify_api_dart.dart';
import 'package:amplify_auth_cognito_dart/amplify_auth_cognito_dart.dart';
// ignore: invalid_use_of_internal_member,implementation_imports
import 'package:amplify_auth_cognito_dart/src/credentials/cognito_keys.dart';
Expand Down Expand Up @@ -63,13 +64,16 @@ Future<void> buildAndRun(Compiler compiler) async {
if (buildDir.existsSync()) {
buildDir.deleteSync(recursive: true);
}

switch (compiler) {
case Compiler.ddc:
// Throwaway port. We use `webdev serve` to build with DDC but will
// re-serve the files with our own server which can better handle
// redirects.
const servePort = 9000;
await processManager.spawnBackgroundInTest('webdev', [
await processManager.spawnBackgroundInTest('dart', [
'run',
'webdev',
'serve',
'--output=web:$buildPath',
'web:$servePort',
Expand All @@ -96,7 +100,9 @@ Future<void> buildAndRun(Compiler compiler) async {
}
});
case Compiler.dart2js:
final buildProc = await processManager.spawn('webdev', [
final buildProc = await processManager.spawn('dart', [
'run',
'webdev',
'build',
'--',
'--define=build_web_compilers:entrypoint=dart2js_args=["-DAMPLIFY_ENVIRONMENT=hosted-ui"]',
Expand Down Expand Up @@ -165,6 +171,7 @@ Future<void> main() async {
setUp(() async {
await buildAndRun(compiler);

await Amplify.addPlugin(AmplifyAPIDart());
await Amplify.configure(jsonEncode(config));
addTearDown(Amplify.reset);

Expand Down Expand Up @@ -333,45 +340,50 @@ const [
const databaseVersion = 1;
const storeName = 'default.store';

const db = await new Promise((resolve, reject) => {
const request = indexedDB.open(databaseName, databaseVersion);
request.onsuccess = (req) => {
resolve(req.target.result);
};
request.onupgradeneeded = (_) => {
reject('Invalid version');
};
request.onerror = (err) => {
reject(`Could not complete request: ${err}`);
};
});

const items = new Map();
await new Promise((resolve, reject) => {
const tx = db.transaction(storeName, 'readwrite').objectStore(storeName);
const request = tx.openCursor();
request.onsuccess = (event) => {
const cursor = event.target.result;
if (!cursor) {
return resolve();
}
const key = cursor.primaryKey;
const value = cursor.value;
items[key] = value;
cursor.continue();
};
request.onerror = (err) => {
reject(`Could not complete cursor req: ${err}`);
};
tx.onerror = (err) => {
reject(`Could not complete tx: ${err}`);
};
});

callback(JSON.stringify(items));
try {
const db = await new Promise((resolve, reject) => {
const request = indexedDB.open(databaseName, databaseVersion);
request.onsuccess = (req) => {
resolve(req.target.result);
};
request.onupgradeneeded = (_) => {
reject('Invalid version');
};
request.onerror = (err) => {
reject(`Could not complete request: ${err}`);
};
});

const items = new Map();
await new Promise((resolve, reject) => {
const tx = db.transaction(storeName, 'readwrite').objectStore(storeName);
const request = tx.openCursor();
request.onsuccess = (event) => {
const cursor = event.target.result;
if (!cursor) {
return resolve();
}
const key = cursor.primaryKey;
const value = cursor.value;
items[key] = value;
cursor.continue();
};
request.onerror = (err) => {
reject(`Could not complete cursor req: ${err}`);
};
tx.onerror = (err) => {
reject(`Could not complete tx: ${err}`);
};
});

callback(JSON.stringify(items));
} catch (e) {
callback(e.toString());
}
''',
[webDatabaseName],
) as String;
logger.debug('Got JavaScript response', json);
final data =
(jsonDecode(json) as Map<String, Object?>).cast<String, String?>();
final keys = HostedUiKeys(
Expand Down
14 changes: 11 additions & 3 deletions packages/auth/amplify_auth_cognito_dart/example/lib/common.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import 'package:amplify_auth_cognito_dart/amplify_auth_cognito_dart.dart';
// ignore: implementation_imports
import 'package:amplify_auth_cognito_dart/src/flows/hosted_ui/hosted_ui_platform.dart';
import 'package:amplify_auth_cognito_test/amplify_auth_cognito_test.dart'
show webDatabaseName;
import 'package:amplify_core/amplify_core.dart';
import 'package:amplify_secure_storage_dart/amplify_secure_storage_dart.dart';

Expand All @@ -18,9 +20,15 @@ Future<void> configure({
}
await Amplify.addPlugin(
AmplifyAuthCognitoDart(
secureStorageFactory: AmplifySecureStorageWorker.factoryFrom(
// ignore: invalid_use_of_visible_for_testing_member
macOSOptions: MacOSSecureStorageOptions(useDataProtection: false),
// ignore: invalid_use_of_visible_for_testing_member, invalid_use_of_internal_member
secureStorageFactory: (scope) => AmplifySecureStorageWorker(
config: AmplifySecureStorageConfig.byNamespace(
namespace: webDatabaseName,
).rebuild((config) {
// enabling useDataProtection requires adding the app to an
// app group, which requires setting a development team
config.macOSOptions.useDataProtection = false;
}),
),
hostedUiPlatformFactory: hostedUiPlatformFactory,
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ environment:

dependencies:
amplify_auth_cognito_dart: any
amplify_auth_cognito_test: any
amplify_core: any
amplify_secure_storage_dart: any
example_common:
path: ../../../example_common

dev_dependencies:
amplify_api_dart: any
amplify_auth_cognito_test: any
amplify_integration_test: any
amplify_lints:
path: ../../../amplify_lints
Expand All @@ -29,4 +29,5 @@ dev_dependencies:
path: ^1.8.0
shelf: ^1.4.0
test: ^1.22.1
webdev: ^3.0.4
webdriver: ^3.0.0
Original file line number Diff line number Diff line change
Expand Up @@ -40,5 +40,7 @@ String createCodeVerifier() {
/// Creates a `Basic` authorization header for identifiying clients.
String createBasicAuthorization(String clientId, [String? clientSecret]) {
clientSecret ??= '';
return 'Basic ${base64Encode('$clientId:$clientSecret'.codeUnits)}';
final userPass =
'${Uri.encodeFull(clientId)}:${Uri.encodeFull(clientSecret)}';
return 'Basic ${base64Encode(ascii.encode(userPass))}';
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,11 @@ import 'package:amplify_auth_cognito_dart/src/flows/hosted_ui/hosted_ui_platform
if (dart.library.html) 'package:amplify_auth_cognito_dart/src/flows/hosted_ui/hosted_ui_platform_html.dart'
if (dart.library.io) 'package:amplify_auth_cognito_dart/src/flows/hosted_ui/hosted_ui_platform_io.dart';
import 'package:amplify_auth_cognito_dart/src/model/hosted_ui/oauth_parameters.dart';
import 'package:amplify_auth_cognito_dart/src/oauth/oauth.dart' as oauth2;
import 'package:amplify_auth_cognito_dart/src/state/state.dart';
import 'package:amplify_core/amplify_core.dart';
import 'package:amplify_secure_storage_dart/amplify_secure_storage_dart.dart';
import 'package:http/http.dart' as http;
import 'package:meta/meta.dart';
import 'package:oauth2/oauth2.dart' as oauth2;

/// A factory constructor for a [HostedUiPlatform] instance.
typedef HostedUiPlatformFactory = HostedUiPlatform Function(
Expand Down Expand Up @@ -45,10 +44,6 @@ abstract class HostedUiPlatform implements Closeable {
/// The secure storage plugin.
SecureStorageInterface get _secureStorage => dependencyManager.getOrCreate();

/// The HTTP client to use for internal HTTP requests.
@protected
http.Client get httpClient => dependencyManager.getOrCreate();

/// The state machine dispatcher.
@protected
Dispatcher<AuthEvent, AuthState> get dispatcher => dependencyManager.expect();
Expand Down Expand Up @@ -121,7 +116,6 @@ abstract class HostedUiPlatform implements Closeable {
_authCodeGrant = createGrant(
config,
codeVerifier: codeVerifier,
httpClient: httpClient,
provider: provider,
);
final uri = _authCodeGrant!.getAuthorizationUrl(
Expand Down Expand Up @@ -161,14 +155,13 @@ abstract class HostedUiPlatform implements Closeable {
CognitoOAuthConfig config, {
AuthProvider? provider,
String? codeVerifier,
http.Client? httpClient,
}) {
return oauth2.AuthorizationCodeGrant(
config.appClientId,
HostedUiConfig(config).signInUri(provider),
HostedUiConfig(config).tokenUri,
secret: config.appClientSecret,
httpClient: httpClient,
httpClient: dependencyManager.getOrCreate(),
codeVerifier: codeVerifier,

// The spec recommends against this, but it's what Cognito expects. Basic
Expand All @@ -186,12 +179,10 @@ abstract class HostedUiPlatform implements Closeable {
CognitoOAuthConfig config, {
required String state,
required String codeVerifier,
http.Client? httpClient,
}) {
final grant = createGrant(
config,
codeVerifier: codeVerifier,
httpClient: httpClient,
);

return grant
Expand Down Expand Up @@ -226,19 +217,12 @@ abstract class HostedUiPlatform implements Closeable {
}

try {
final client = await authCodeGrant.handleAuthorizationResponse(
final tokens = await authCodeGrant.handleAuthorizationResponse(
parameters.toJson(),
);
final oAuthCredentials = client.credentials;
final tokens = CognitoUserPoolTokens(
signInMethod: CognitoSignInMethod.hostedUi,
accessToken: JsonWebToken.parse(oAuthCredentials.accessToken),
refreshToken: oAuthCredentials.refreshToken!,
idToken: JsonWebToken.parse(oAuthCredentials.idToken!),
)..validate(
nonce: await _secureStorage.read(key: _keys[HostedUiKey.nonce]),
);

tokens.validate(
nonce: await _secureStorage.read(key: _keys[HostedUiKey.nonce]),
);
return tokens;

// Transform FormatExceptions from `oauth2` package to Amplify types.
Expand All @@ -258,7 +242,6 @@ abstract class HostedUiPlatform implements Closeable {
config,
state: state,
codeVerifier: codeVerifier,
httpClient: httpClient,
);
return parameters;
}
Expand Down
Loading