Skip to content

Commit

Permalink
chore(repo): Clean up workers
Browse files Browse the repository at this point in the history
Force unwrapping nullable values is done in JS by calling `nullableValue.toString` which will throw an error if `nullableValue` is null. Browsers seem to handle this sort of error different than a thrown Dart error and the error is harder to trace when it happens.

Introduces an `unwrapParameter` method to the base worker bee class so that unwrap errors are strongly-typed and provide more context to the issue.
  • Loading branch information
Dillon Nys authored and dnys1 committed Sep 6, 2023
1 parent b02490f commit 17ab025
Show file tree
Hide file tree
Showing 13 changed files with 170 additions and 126 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,9 @@ abstract class ConfirmDeviceWorker
StreamSink<ConfirmDeviceResponse> respond,
) async {
await for (final message in listen) {
final deviceGroupKey = message.newDeviceMetadata.deviceGroupKey;
final deviceKey = message.newDeviceMetadata.deviceKey;
final ConfirmDeviceMessage(:newDeviceMetadata, :accessToken) = message;
final deviceGroupKey = newDeviceMetadata.deviceGroupKey;
final deviceKey = newDeviceMetadata.deviceKey;
if (deviceGroupKey == null || deviceKey == null) {
throw InvalidParameterException(message: 'Missing device metadata');
}
Expand All @@ -100,7 +101,7 @@ abstract class ConfirmDeviceWorker
);
final request = ConfirmDeviceRequest.build((b) {
b
..accessToken = message.accessToken
..accessToken = accessToken
..deviceKey = deviceKey
..deviceSecretVerifierConfig.passwordVerifier =
base64Encode(encodeBigInt(verifier))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import 'package:amplify_auth_cognito_dart/src/flows/srp/srp_device_password_veri
import 'package:amplify_auth_cognito_dart/src/flows/srp/srp_helper.dart';
import 'package:amplify_auth_cognito_dart/src/flows/srp/srp_init_result.dart';
import 'package:amplify_auth_cognito_dart/src/model/cognito_device_secrets.dart';
import 'package:amplify_auth_cognito_dart/src/model/sign_in_parameters.dart';
import 'package:amplify_auth_cognito_dart/src/sdk/cognito_identity_provider.dart';
import 'package:built_collection/built_collection.dart';
import 'package:built_value/built_value.dart';
Expand Down Expand Up @@ -46,9 +45,6 @@ abstract class SrpDevicePasswordVerifierMessage
/// User device secrets.
CognitoDeviceSecrets get deviceSecrets;

/// Parameters to the SRP flow.
SignInParameters get parameters;

/// Parameters of the current challenge.
BuiltMap<String, String> get challengeParameters;

Expand Down Expand Up @@ -78,48 +74,63 @@ abstract class SrpDevicePasswordVerifierWorker extends WorkerBeeBase<
StreamSink<RespondToAuthChallengeRequest> respond,
) async {
await for (final message in listen) {
final username =
message.challengeParameters[CognitoConstants.challengeParamUsername]!;
final deviceKey = message
.challengeParameters[CognitoConstants.challengeParamDeviceKey]!;
final secretBlock = message
.challengeParameters[CognitoConstants.challengeParamSecretBlock]!;
final encodedSalt =
message.challengeParameters[CognitoConstants.challengeParamSalt]!;
final encodedB =
message.challengeParameters[CognitoConstants.challengeParamSrpB]!;
final timestamp = DateTime.now().toUtc();
final formattedTimestamp = _dateFormat.format(timestamp);
final SrpDevicePasswordVerifierMessage(
:initResult,
:clientId,
:clientSecret,
:deviceSecrets,
:challengeParameters,
) = message;
final username = unwrapParameter(
CognitoConstants.challengeParamUsername,
challengeParameters[CognitoConstants.challengeParamUsername],
);
final deviceKey = unwrapParameter(
CognitoConstants.challengeParamDeviceKey,
challengeParameters[CognitoConstants.challengeParamDeviceKey],
);
final secretBlock = unwrapParameter(
CognitoConstants.challengeParamSecretBlock,
challengeParameters[CognitoConstants.challengeParamSecretBlock],
);
final encodedSalt = unwrapParameter(
CognitoConstants.challengeParamSalt,
challengeParameters[CognitoConstants.challengeParamSalt],
);
final encodedB = unwrapParameter(
CognitoConstants.challengeParamSrpB,
challengeParameters[CognitoConstants.challengeParamSrpB],
);
final formattedTimestamp = _dateFormat.format(DateTime.timestamp());

final encodedClaim = SrpHelper.createDeviceClaim(
deviceKey: deviceKey,
deviceSecrets: message.deviceSecrets,
deviceSecrets: deviceSecrets,
username: username,
initResult: message.initResult,
initResult: initResult,
encodedSalt: encodedSalt,
encodedB: encodedB,
secretBlock: secretBlock,
formattedTimestamp: formattedTimestamp,
);
final response = RespondToAuthChallengeRequest.build((b) {
b
..clientId = message.clientId
..clientId = clientId
..challengeName = ChallengeNameType.devicePasswordVerifier
..challengeResponses.addAll({
CognitoConstants.challengeParamPasswordSecretBlock: secretBlock,
CognitoConstants.challengeParamPasswordSignature: encodedClaim,
CognitoConstants.challengeParamUsername: username,
CognitoConstants.challengeParamTimestamp: formattedTimestamp,
CognitoConstants.challengeParamDeviceKey: deviceKey,
});

if (message.clientSecret != null) {
..challengeResponses[
CognitoConstants.challengeParamPasswordSecretBlock] = secretBlock
..challengeResponses[
CognitoConstants.challengeParamPasswordSignature] = encodedClaim
..challengeResponses[CognitoConstants.challengeParamUsername] =
username
..challengeResponses[CognitoConstants.challengeParamTimestamp] =
formattedTimestamp
..challengeResponses[CognitoConstants.challengeParamDeviceKey] =
deviceKey;

if (clientSecret != null) {
b.challengeResponses[CognitoConstants.challengeParamSecretHash] =
computeSecretHash(
username,
message.clientId,
message.clientSecret!,
);
computeSecretHash(username, clientId, clientSecret);
}
});

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 @@ -44,7 +44,6 @@ abstract class SrpInitWorker
Stream<SrpInitMessage> listen,
StreamSink<SrpInitResult> respond,
) async {
// ignore: no_leading_underscores_for_local_identifiers
await for (final _ in listen) {
respond.add(SrpHelper.deriveEphemeralValues());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ abstract class SrpPasswordVerifierMessage

@BuiltValueHook(finalizeBuilder: true)
static void _init(SrpPasswordVerifierMessageBuilder b) {
b.timestamp ??= DateTime.now().toUtc();
b.timestamp ??= DateTime.timestamp();
}

/// Result of the SRP initialization step.
Expand Down Expand Up @@ -85,25 +85,45 @@ abstract class SrpPasswordVerifierWorker extends WorkerBeeBase<
StreamSink<RespondToAuthChallengeRequest> respond,
) async {
await for (final message in listen) {
final username =
message.challengeParameters[CognitoConstants.challengeParamUsername]!;
final userId = message
.challengeParameters[CognitoConstants.challengeParamUserIdForSrp]!;
final SrpPasswordVerifierMessage(
:initResult,
:clientId,
:clientSecret,
:poolId,
:deviceKey,
:parameters,
:challengeParameters,
:timestamp,
) = message;
final username = unwrapParameter(
CognitoConstants.challengeParamUsername,
challengeParameters[CognitoConstants.challengeParamUsername],
);
final userId = unwrapParameter(
CognitoConstants.challengeParamUserIdForSrp,
challengeParameters[CognitoConstants.challengeParamUserIdForSrp],
);
final secretBlock = unwrapParameter(
CognitoConstants.challengeParamSecretBlock,
challengeParameters[CognitoConstants.challengeParamSecretBlock],
);
final encodedSalt = unwrapParameter(
CognitoConstants.challengeParamSalt,
challengeParameters[CognitoConstants.challengeParamSalt],
);
final encodedB = unwrapParameter(
CognitoConstants.challengeParamSrpB,
challengeParameters[CognitoConstants.challengeParamSrpB],
);

// Pool ID is in the form `{region}_{poolName}`
final poolName = message.poolId.split('_')[1];
final secretBlock = message
.challengeParameters[CognitoConstants.challengeParamSecretBlock]!;
final encodedSalt =
message.challengeParameters[CognitoConstants.challengeParamSalt]!;
final encodedB =
message.challengeParameters[CognitoConstants.challengeParamSrpB]!;
final timestamp = message.timestamp;
final poolName = poolId.split('_')[1];
final formattedTimestamp = _dateFormat.format(timestamp);

final encodedClaim = SrpHelper.createPasswordClaim(
userId: userId,
parameters: message.parameters,
initResult: message.initResult,
parameters: parameters,
initResult: initResult,
encodedSalt: encodedSalt,
encodedB: encodedB,
poolName: poolName,
Expand All @@ -112,25 +132,21 @@ abstract class SrpPasswordVerifierWorker extends WorkerBeeBase<
);
final response = RespondToAuthChallengeRequest.build((b) {
b
..clientId = message.clientId
..clientId = clientId
..challengeName = ChallengeNameType.passwordVerifier
..challengeResponses.addAll({
CognitoConstants.challengeParamPasswordSecretBlock: secretBlock,
CognitoConstants.challengeParamPasswordSignature: encodedClaim,
CognitoConstants.challengeParamUsername: username,
CognitoConstants.challengeParamTimestamp: formattedTimestamp,
});

if (message.clientSecret != null) {
..challengeResponses[
CognitoConstants.challengeParamPasswordSecretBlock] = secretBlock
..challengeResponses[
CognitoConstants.challengeParamPasswordSignature] = encodedClaim
..challengeResponses[CognitoConstants.challengeParamUsername] =
username
..challengeResponses[CognitoConstants.challengeParamTimestamp] =
formattedTimestamp;

if (clientSecret != null) {
b.challengeResponses[CognitoConstants.challengeParamSecretHash] =
computeSecretHash(
username,
message.clientId,
message.clientSecret!,
);
computeSecretHash(username, clientId, clientSecret);
}

final deviceKey = message.deviceKey;
if (deviceKey != null) {
b.challengeResponses[CognitoConstants.challengeParamDeviceKey] =
deviceKey;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -426,8 +426,7 @@ final class SignInStateMachine
..initResult = _initResult
..clientId = config.appClientId
..clientSecret = config.appClientSecret
..challengeParameters = BuiltMap(_publicChallengeParameters)
..parameters = parameters;
..challengeParameters = BuiltMap(_publicChallengeParameters);
});
worker.sink.add(workerMessage);
return worker.stream.first;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import 'dart:async';
import 'package:amplify_auth_cognito_dart/src/flows/constants.dart';
import 'package:amplify_auth_cognito_dart/src/flows/srp/srp_device_password_verifier_worker.dart';
import 'package:amplify_auth_cognito_dart/src/model/cognito_device_secrets.dart';
import 'package:amplify_auth_cognito_dart/src/model/sign_in_parameters.dart';
import 'package:amplify_auth_cognito_dart/src/sdk/src/cognito_identity_provider/model/respond_to_auth_challenge_request.dart';
import 'package:amplify_auth_cognito_test/common/mock_config.dart'
hide username;
Expand Down Expand Up @@ -38,11 +37,6 @@ void main() {
..deviceGroupKey = deviceGroupKey
..devicePassword = devicePassword,
)
..parameters = SignInParameters(
(p) => p
..username = srpUsername
..password = srpPassword,
)
..challengeParameters = BuiltMap({
CognitoConstants.challengeParamUsername: srpUsername,
CognitoConstants.challengeParamUserIdForSrp: srpUsername,
Expand Down Expand Up @@ -82,11 +76,7 @@ void main() {
..deviceGroupKey = deviceGroupKey
..devicePassword = devicePassword,
)
..parameters = SignInParameters(
(p) => p
..username = srpUsername
..password = srpPassword,
)
// No challenge parameters
..challengeParameters = BuiltMap(<String, String>{}),
);
worker.add(message);
Expand Down
Loading

0 comments on commit 17ab025

Please sign in to comment.