Skip to content

Commit

Permalink
Blip chat
Browse files Browse the repository at this point in the history
 - Public Key Pinning
 - General Adjustments
  • Loading branch information
leonardo.gabriel committed Sep 15, 2022
1 parent cc532f9 commit e589b03
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 27 deletions.
2 changes: 1 addition & 1 deletion .fvm/fvm_config.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"flutterSdkVersion": "3.0.4",
"flutterSdkVersion": "3.3.1",
"flavors": {}
}
66 changes: 44 additions & 22 deletions lib/src/client.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import 'dart:async';
import 'dart:io';
import 'dart:math';
import 'package:blip_sdk/src/config.dart';
import 'package:lime/lime.dart';
import 'package:ssl_pinning_plugin/ssl_pinning_plugin.dart';
import 'application.dart';
import 'extensions/base.extension.dart';
import 'extensions/enums/extension_type.enum.dart';
Expand All @@ -14,6 +17,7 @@ class Client {
final String uri;
final Application application;
final Transport transport;
final bool forceSecureConnection;

ClientChannel _clientChannel;
final _notificationListeners = <Listener<Notification>>[];
Expand All @@ -29,46 +33,62 @@ class Client {
bool _closing = false;
int _connectionTryCount = 0;

Client({required this.uri, required this.transport, required this.application})
: _clientChannel = ClientChannel(transport) {
ClientChannel get clientChannel => _clientChannel;

Client({
required this.uri,
required this.transport,
required this.application,
this.forceSecureConnection = false,
}) : _clientChannel = ClientChannel(transport) {
_initializeClientChannel();
}

/// Allows connection with an identifier
Future<Session> connectWithGuest(identifier) {
if (!identifier) throw ArgumentError.notNull('The identifier is required');
Future<Session> connectWithGuest(String identifier) {
application.identifier = identifier;
application.authentication = GuestAuthentication();
return connect();
}

/// Allows connection with an identifier and password
Future<Session> connectWithPassword(identifier, password, presence) {
if (!identifier) throw ArgumentError.notNull('The identifier is required');
if (!password) throw ArgumentError.notNull('The password is required');

Future<Session> connectWithPassword(String identifier, String password, {Presence? presence}) {
application.identifier = identifier;
application.authentication = PlainAuthentication(password: password);

if (presence) application.presence = presence;
if (presence != null) application.presence = presence;
return connect();
}

/// Allows connection with an identifier and key
Future<Session> connectWithKey(identifier, key, presence) {
if (!identifier) throw ArgumentError.notNull('The identifier is required');
if (!key) throw ArgumentError.notNull('The key is required');

Future<Session> connectWithKey(String identifier, String key, {Presence? presence}) {
application.identifier = identifier;
application.authentication = KeyAuthentication(key: key);

if (presence) application.presence = presence;
if (presence != null) application.presence = presence;

return connect();
}

/// Starts the process of connecting to the server and establish a session
Future<Session> connect() {
Future<Session> connect() async {
if (forceSecureConnection) {
const wssProtocol = 'wss://';
const httpsProtocol = 'https://';
var uri = this.uri;

if (Platform.isAndroid && uri.contains(wssProtocol)) {
uri = uri.replaceFirst(wssProtocol, httpsProtocol);
}

await SslPinningPlugin.check(
serverURL: uri,
sha: SHA.SHA256,
allowedSHAFingerprints: Config.allowedFingerprints,
timeout: 300,
);
}

if (_connectionTryCount >= maxConnectionTryCount) {
throw Exception(
'Could not connect: Max connection try count of $maxConnectionTryCount reached. Please check you network and refresh the page.');
Expand All @@ -78,11 +98,13 @@ class Client {
_closing = false;
return transport
.open(uri)
.then((_) => _clientChannel.establishSession(
application.identifier + '@' + application.domain,
application.instance,
application.authentication,
))
.then(
(_) => _clientChannel.establishSession(
application.identifier + '@' + application.domain,
application.instance,
application.authentication,
),
)
.then((session) => _sendPresenceCommand().then((_) => session))
.then((session) => _sendReceiptsCommand().then((_) => session))
.then((session) {
Expand All @@ -104,8 +126,8 @@ class Client {
// try to reconnect after the timeout
Future.delayed(Duration(milliseconds: timeout.round()), () async {
if (!_closing) {
transport.onEvelope?.close();
transport.onEvelope = StreamController<Map<String, dynamic>>();
transport.onEnvelope?.close();
transport.onEnvelope = StreamController<Map<String, dynamic>>();

transport.onClose.close();
transport.onClose = StreamController<bool>();
Expand Down
22 changes: 18 additions & 4 deletions lib/src/client_builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,12 @@ import 'client.dart';
class ClientBuilder {
Application application;
Transport transport;
bool forceSecureConnection;

ClientBuilder({required this.transport}) : application = Application();
ClientBuilder({
required this.transport,
this.forceSecureConnection = false,
}) : application = Application();

/// Allows you to set a custom application for configuration
ClientBuilder withApplication(Application application) {
Expand Down Expand Up @@ -116,11 +120,21 @@ class ClientBuilder {
application.commandTimeout = timeoutInMilliSecs;
return this;
}

/// Set a secure connection
ClientBuilder withSecureConnection() {
forceSecureConnection = true;
return this;
}

/// Returns a new instance of SDK Client
Client build() {
final uri =
'${application.scheme}://${application.hostName}:${application.port}';
return Client(uri: uri, transport: transport, application: application);
final uri = '${application.scheme}://${application.hostName}:${application.port}';
return Client(
uri: uri,
transport: transport,
application: application,
forceSecureConnection: forceSecureConnection,
);
}
}
7 changes: 7 additions & 0 deletions lib/src/config.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
abstract class Config {
static const allowedFingerprints = [
'6C A1 D2 B6 C4 FF 3C 9D CA E8 0F 37 B9 52 AA 94 88 37 13 35 94 AA 18 3B 72 1D C7 8D C8 8D 1E 9E',
'AB 5F B0 A0 A5 90 88 AA 61 3A 11 5B 8A CC F2 62 86 E9 E9 D7 6E 8B 35 75 A6 18 71 F5 DE 44 F5 64',
'27 FE A7 4D 91 EC C0 1B A9 90 94 0A 18 9F EA 4B 90 A2 EA 81 96 D0 05 6A 8A 74 E5 A3 E9 00 3C 7B',
];
}

0 comments on commit e589b03

Please sign in to comment.