Skip to content

Commit

Permalink
fix: report PubNubException when message content is not valid for sub…
Browse files Browse the repository at this point in the history
…scribe and histroy api with crypto configuration.
  • Loading branch information
mohitpubnub committed Nov 27, 2023
1 parent 8b0cc96 commit 8fd36c2
Show file tree
Hide file tree
Showing 8 changed files with 41 additions and 35 deletions.
2 changes: 1 addition & 1 deletion pubnub/lib/src/core/message/base_message.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class BaseMessage {

/// If message decryption failed then [error]
/// field contains error message
final String? error;
final PubNubException? error;

/// Alias for `publishedAt`.
@deprecated
Expand Down
36 changes: 20 additions & 16 deletions pubnub/lib/src/dx/channel/channel_history.dart
Original file line number Diff line number Diff line change
Expand Up @@ -106,29 +106,31 @@ class ChannelHistory {

_cursor = result.endTimetoken;
_messages.addAll(await Future.wait(result.messages.map((message) async {
String? errorMessage;
PubNubException? error;
if (_keyset.cipherKey != null || _core.crypto is CryptoModule) {
try {
if (!(message['message'] is String)) {
throw FormatException('not a base64 string.');
}
message['message'] = _keyset.cipherKey ==
_core.keysets.defaultKeyset.cipherKey
? await _core.parser.decode(utf8.decode(_core.crypto.decrypt(
base64.decode(message['message'] as String).toList())))
: await _core.parser.decode(utf8.decode(_core.crypto
.decryptWithKey(_keyset.cipherKey!,
base64.decode(message['message'] as String).toList())));
} on CryptoException catch (e) {
errorMessage =
'Can not decrypt the message payload. Please check keyset or crypto configuration \n ${e.message}';
} catch (e) {
errorMessage =
'Can not decrypt the message payload. Please check keyset or crypto configuration';
} on PubNubException catch (e) {
error = e;
} on FormatException catch (e) {
error = PubNubException(
'Can not decrypt the message payload. Please check keyset or crypto configuration. ${e.message}');
}
}
return BaseMessage(
publishedAt: Timetoken(BigInt.from(message['timetoken'])),
content: message['message'],
originalMessage: message,
error: errorMessage);
error: error);
})));
} while (_cursor.value != BigInt.from(0));
}
Expand Down Expand Up @@ -218,29 +220,31 @@ class PaginatedChannelHistory {
}

_messages.addAll(await Future.wait(result.messages.map((message) async {
String? errorMessage;
PubNubException? error;
if (_keyset.cipherKey != null || _core.crypto is CryptoModule) {
try {
if (!(message['message'] is String)) {
throw FormatException('not a base64 string.');
}
message['message'] = _keyset.cipherKey ==
_core.keysets.defaultKeyset.cipherKey
? await _core.parser.decode(utf8.decode(_core.crypto
.decrypt(base64.decode(message['message'] as String))))
: await _core.parser.decode(utf8.decode(_core.crypto
.encryptWithKey(_keyset.cipherKey!,
base64.decode(message['message'] as String).toList())));
} on CryptoException catch (e) {
errorMessage =
'Can not decrypt the message payload. Please check keyset or crypto configuration.\n ${e.message}';
} catch (e) {
errorMessage =
'Can not decrypt the message payload. Please check keyset or crypto configuration';
} on PubNubException catch (e) {
error = e;
} on FormatException catch (e) {
error = PubNubException(
'Can not decrypt the message payload. Please check keyset or crypto configuration. ${e.message}');
}
}
return BaseMessage(
originalMessage: message,
publishedAt: Timetoken(BigInt.from(message['timetoken'])),
content: message['message'],
error: errorMessage);
error: error);
})));

return result;
Expand Down
2 changes: 1 addition & 1 deletion pubnub/lib/src/subscribe/envelope.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class Envelope extends BaseMessage {
final dynamic userMeta;

@override
String? error;
PubNubException? error;

dynamic get payload => content;

Expand Down
14 changes: 8 additions & 6 deletions pubnub/lib/src/subscribe/subscribe_loop/subscribe_loop.dart
Original file line number Diff line number Diff line change
Expand Up @@ -133,19 +133,21 @@ class SubscribeLoop {
!object['c'].endsWith('-pnpres')) {
try {
_logger.info('Decrypting message...');
if (!(object['d'] is String)) {
throw FormatException('not a base64 String');
}
object['d'] = state.keyset.cipherKey ==
core.keysets.defaultKeyset.cipherKey
? await core.parser.decode(utf8.decode(core.crypto
.decrypt(base64.decode(object['d'] as String).toList())))
: await core.parser.decode(utf8.decode(core.crypto
.decryptWithKey(state.keyset.cipherKey!,
base64.decode(object['d'] as String).toList())));
} on CryptoException catch (e) {
object['error'] =
'Can not decrypt the message payload. Please check keyset or crypto configuration.\n ${e.message}';
} catch (e) {
object['error'] =
'Can not decrypt the message payload. Please check keyset or crypto configuration.';
} on PubNubException catch (e) {
object['error'] = e;
} on FormatException catch (e) {
object['error'] = PubNubException(
'Can not decrypt the message payload. Please check keyset or crypto configuration. ${e.message}');
}
}
return Envelope.fromJson(object);
Expand Down
9 changes: 5 additions & 4 deletions pubnub/test/integration/subscribe/_utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ class Subscriber {
return subscription?.cancel();
}

Future<void> expectMessage(String channel, String message, [String? error]) {
Future<void> expectMessage(String channel, String message,
[PubNubException? error]) {
var actual = queue?.next;

return expectLater(actual,
Expand All @@ -47,7 +48,7 @@ class Subscriber {
class SubscriptionMessageMatcher extends Matcher {
final String expectedMessage;
final String channel;
String? error;
PubNubException? error;

SubscriptionMessageMatcher(this.channel, this.expectedMessage, this.error);

Expand All @@ -70,8 +71,8 @@ class SubscriptionMessageMatcher extends Matcher {
errorMatch(item);

bool errorMatch(envelope) {
if (!(error?.isEmpty ?? true)) {
return error == (envelope as Envelope).error;
if (error != null) {
return error is PubNubException;
}
return true;
}
Expand Down
7 changes: 5 additions & 2 deletions pubnub/test/integration/subscribe/subscribe_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,11 @@ void main() {
await Future.delayed(Duration(seconds: 2));
await pubnub.publish(channel, message);

await subscriber.expectMessage(channel, message,
'Can not decrypt the message payload. Please check keyset or crypto configuration.');
await subscriber.expectMessage(
channel,
message,
PubNubException(
'Can not decrypt the message payload. Please check keyset or crypto configuration.'));
});

tearDown(() async {
Expand Down
3 changes: 1 addition & 2 deletions pubnub/test/unit/dx/channel_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,7 @@ void main() {
await history.fetch();

expect(history.messages.length, equals(1));
expect(history.messages[0].error,
equals(_unEncryptedMessageErrorMessage));
expect(history.messages[0].error, isException);
});
});

Expand Down
3 changes: 0 additions & 3 deletions pubnub/test/unit/dx/fixtures/channel.dart
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,3 @@ final _historyMessagesFetchResponse = '''[
0,
0
]''';

final _unEncryptedMessageErrorMessage =
'Can not decrypt the message payload. Please check keyset or crypto configuration';

0 comments on commit 8fd36c2

Please sign in to comment.