Skip to content

Commit

Permalink
Merge pull request AOSSIE-Org#23 from bhavik-mangla/gsoc-2024
Browse files Browse the repository at this point in the history
Gsoc 2024
  • Loading branch information
ManavSarkar authored Aug 26, 2024
2 parents 9f9abc1 + 4e1a178 commit a601f36
Show file tree
Hide file tree
Showing 22 changed files with 373 additions and 232 deletions.
67 changes: 0 additions & 67 deletions GSOC/2024/BhavikMangla.md

This file was deleted.

94 changes: 94 additions & 0 deletions GSOC/2024/Bhavik_Mangla.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
## **GSOC AOSSIE 2024**

## _OpenPeerChat - Peer to Peer Messaging App_

## Project Description
The OpenPeerChat app is a secure, peer-to-peer messaging platform designed to prioritize user privacy and data protection. Built using Flutter, it enables users to communicate and share files directly with one another without relying on centralized servers. The application will be hugely beneficial in disaster-prone areas or remote areas where the cellular connections are too weak to communicate through general messaging applications. The app emphasizes robust encryption, secure authentication methods and offer a seamless and user-friendly messaging experience making it an ideal choice for those who value confidentiality in their digital communications.

## Chosen Idea:
- Implementation of RSA in messages.
- Enabling Sending files, images, audio and video.
- Make the UI suitable to view those files sent.
- Update dependencies.

## **Updates:**
### User Authentication:
- Added a password lock and a fingerprint lock for on-device authentication of the user using the `local_auth` package.
- Ensured secure and seamless authentication methods to enhance user security.

### Dependencies and Testing:
- Updated all dependencies and packages to the latest versions.
- Set the version and build number, and upgraded to the latest Kotlin version in `build.gradle`.
- Tested the app's functionality across multiple devices and platforms to ensure compatibility and stability.

### RSA Encryption:
- Implemented Public and Private Key Generation for secure communications.
- Integrated RSA Encryption, and developed methods for encoding and parsing public/private keys to and from PEM format using libraries such as `asn1lib`, `dart:typed_data`, `dart:convert`, and `pointycastle`.
- Stored primary and public keys securely using `flutter_secure_storage`, `sqflite`, and `flutter_nearby_connections`.
- Shared encrypted public keys between users upon establishing a connection to ensure secure communication.
- Implemented the storage and transmission of encrypted messages in global cache and sqflite tables, decrypting them with the user's private key.
- Added RSA encryption specifically for file sharing to further enhance security.

### Chat Functionality:
- Improved the Chat Page UI by adding dates and chat bubbles to make it visually similar to WhatsApp chats. (`bubble`)
- Developed a separate, clean UI for file viewing within the chat interface.

### File Handling:
- Completed the implementation of file viewing, which supports all file types.
- Implemented secure file sharing and storing on device between users, ensuring that files are encrypted during transmission. (`file_picker`, `open_filex`, `permission_handler`, `path_provider`)
- Set a maximum limit for file sizes to ensure quick and efficient file transfers.

### Additional Enhancements:
- Added a powerful search feature on the home screen, enabling users to quickly find and connect with others in All Chats and Devices pages.
- Enhanced the overall user experience by refining the UI and addressing visual bugs.
- Engaged in regular code reviews and optimizations to maintain code quality and performance.


## App Flow:

- User Authentication:
Upon opening the app, users are prompted to authenticate using a password or fingerprint, ensuring secure access.

- New User Setup:
New users are prompted to enter their name after successful authentication, establishing their identity within the app.

- Home Screen:
After setup, users are taken to the home screen, which features a search bar to quickly find and connect with other users or devices.

- Chat Interface:
The chat page displays conversations with dates and chat bubbles, offering a familiar and intuitive experience similar to WhatsApp.

- File Viewing and Sharing:
Users can view and share files securely within the chat interface. File transfers are encrypted using RSA encryption, with a maximum file size limit to ensure efficiency.

- Secure Communication:
RSA-encrypted messages are stored and transmitted securely, with public keys shared between users upon connection.

## **Future Work:**
- Develop a robust notification system to alert users about new messages, file transfers, and other critical updates, ensuring timely and reliable communication.
- Add an upload progress indicator for larger file transfers, visible on both sender and receiver screens, to improve user experience during file sharing.
- Ensure that changes to a user's profile name are reflected in nearby devices, maintaining consistency in chat history and user identification.
- Verify and enhance cross-platform compatibility, ensuring seamless communication and functionality between Android and iOS devices, fostering a unified user experience across different platforms.
- Prepare for publishing the app on the Google Play Store and Apple App Store, including meeting all necessary guidelines and requirements for app submission.


## Demonstration Links
- Video: [OpenPeerChat GSOC 2024](https://drive.google.com/file/d/1cSx_MPT7jJ-pKTPfi6foHkJKkLGvqt3h/view?usp=sharing)
- APK: [OpenPeerChat App](https://drive.google.com/file/d/1Nlz8oKXRIaQC5KVznvr2fus-8CM9JZlv/view?usp=sharing)


## Merge Requests
https://github.com/AOSSIE-Org/OpenPeerChat-flutter/pull/21
https://github.com/AOSSIE-Org/OpenPeerChat-flutter/pull/23

## Contributor Details
- Name: Bhavik Mangla
- GitHub: [bhavik-mangla](https://github.com/bhavik-mangla)
- Email: [email protected]
- LinkedIn: [bhavikmangla](https://www.linkedin.com/in/bhavikmangla/)
- Organization: [Australian Open Source Software Innovation and Education (AOSSIE)](https://aossie.org/)
- Project: [Resonate - Open Source Social Voice Platform](https://github.com/AOSSIE-Org/Resonate)

## **Conclusion:**
The app has made tremendous strides in improving security, user experience, and overall functionality. By implementing advanced RSA encryption and secure authentication mechanisms, the foundation for safe and private communication has been firmly established. The chat interface has been refined with thoughtful enhancements, making conversations more visually appealing and easier to navigate. File handling capabilities have been expanded to support all file types, with secure sharing and storage features ensuring that user data is protected at every step.
Looking ahead, by introducing a notification system, refining the UI, and enhancing profile management, the app is poised to offer a robust, secure, and user-friendly environment. It will elevate the app’s performance and user customization options, ensuring it remains a secure and versatile tool for communication.
4 changes: 4 additions & 0 deletions android/build.gradle
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
buildscript {
ext.kotlin_version = '2.0.10'
}

allprojects {
repositories {
google()
Expand Down
2 changes: 1 addition & 1 deletion android/settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ pluginManagement {
plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
id "com.android.application" version "7.3.0" apply false
id "org.jetbrains.kotlin.android" version "1.7.10" apply false
id "org.jetbrains.kotlin.android" version "2.0.10" apply false
}

include ":app"
2 changes: 1 addition & 1 deletion ios/Runner/AppDelegate.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import UIKit
import Flutter

@UIApplicationMain
@main
@objc class AppDelegate: FlutterAppDelegate {

override func application(
Expand Down
2 changes: 2 additions & 0 deletions lib/classes/global.dart
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ class Global extends ChangeNotifier {

Future<String> decodeAndStoreFile(String encodedFile, String fileName) async {
Uint8List fileBytes = base64.decode(encodedFile);

//to send files encrypted using RSA
// Uint8List fileData = rsaDecrypt(Global.myPrivateKey!, fileBytes);

Directory documents ;
Expand Down
49 changes: 47 additions & 2 deletions lib/components/message_panel.dart
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ class _MessagePanelState extends State<MessagePanel> {
return Padding(
padding: const EdgeInsets.all(8.0),
child: TextFormField(
//multiline text field
maxLines: null,
controller: myController,
decoration: InputDecoration(
icon: const Icon(Icons.person),
Expand Down Expand Up @@ -112,9 +114,50 @@ class _MessagePanelState extends State<MessagePanel> {
myController.clear();
}

/// This function is used to navigate to the file preview page and check the file size.
void _navigateToFilePreviewPage(BuildContext context) async {
//max size of file is 30 MB
double sizeKbs = 0;
const int maxSizeKbs = 30 * 1024;
FilePickerResult? result = await FilePicker.platform.pickFiles();
if(result != null) {
sizeKbs = result.files.single.size / 1024;
}


if (sizeKbs > maxSizeKbs) {
if (!context.mounted) return;
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: const Text('File Size Exceeded'),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
ListTile(
//file size in MB
title: Text('File Size: ${(sizeKbs / 1024).ceil()} MB'),
subtitle: const Text(
'File size should not exceed 30 MB'),
),
],
),
actions: [
TextButton(
onPressed: () {
Navigator.of(context).pop();
},
child: const Text('Close'),
),
],
);
},
);
return;
}

//this function is used to open the file preview dialog
if (result != null) {
setState(() {
_selectedFile = File(result.files.single.path!);
Expand All @@ -129,11 +172,12 @@ class _MessagePanelState extends State<MessagePanel> {
mainAxisSize: MainAxisSize.min,
children: [
ListTile(

title: Text('File Name: ${_selectedFile.path
.split('/')
.last}'),
.last}', overflow: TextOverflow.ellipsis,),
subtitle: Text(
'File Size: ${_selectedFile.lengthSync()} bytes'),
'File Size: ${(sizeKbs / 1024).floor()} MB'),
),
ElevatedButton(
onPressed: () => FilePreview.openFile(_selectedFile.path),
Expand Down Expand Up @@ -167,6 +211,7 @@ class _MessagePanelState extends State<MessagePanel> {
}


/// This function is used to send the file message.
void _sendFileMessage(BuildContext context, File file) async{
var msgId = nanoid(21);

Expand Down
47 changes: 45 additions & 2 deletions lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_nearby_connections_example/pages/home_page.dart';
import 'package:flutter_nearby_connections_example/pages/auth_fail.dart';
import 'package:flutter_nearby_connections_example/pages/profile.dart';
import 'package:local_auth/local_auth.dart';
import 'package:provider/provider.dart';
import 'classes/global.dart';
import 'encyption/key_storage.dart';
Expand Down Expand Up @@ -53,8 +56,48 @@ class MyApp extends StatelessWidget {
}
}


Future<void> _authenticate(BuildContext context) async {
final LocalAuthentication auth = LocalAuthentication();
bool authenticated = false;

try {
authenticated = await auth.authenticate(
localizedReason: 'Please authenticate to proceed',
options: const AuthenticationOptions(
stickyAuth: true,
sensitiveTransaction: true,
),
);
} catch (e) {
if (kDebugMode) {
print(e);
}
}
if (!context.mounted) return;
if (authenticated) {
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => const Profile(onLogin: true)),
);
} else {
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => AuthFailedPage(onRetry: () => _authenticate(context))),
);
}
}

Route<dynamic> generateRoute(RouteSettings settings) {
return MaterialPageRoute(
builder: (_) => const HomePage(),
builder: (context) {
_authenticate(context);
return const Scaffold(
body: Center(
child: CircularProgressIndicator(),
),
);
},
);
}

9 changes: 6 additions & 3 deletions lib/p2p/adhoc_housekeeping.dart
Original file line number Diff line number Diff line change
Expand Up @@ -148,11 +148,12 @@ void broadcast(BuildContext context) async {
File file = File(message['filePath']);
Uint8List encryptedBytes = await file.readAsBytes();

// // Encrypt the message
//to send the file encrypted with the RSA
// Encrypt the message
// Uint8List encryptedMessage = rsaEncrypt(publicKey, encryptedBytes);
// // Encode the message to base64
// Encode the message to base64
// String encodedMessage = base64.encode(encryptedMessage);
//


String encodedMessage = base64.encode(encryptedBytes);

Expand Down Expand Up @@ -297,6 +298,7 @@ void checkDevices(BuildContext context) {
// The the protocol service. It receives the messages from the
// dataReceivedSubscription service and decode it.
void init(BuildContext context) async {

initiateNearbyService();
checkDevices(context);

Expand Down Expand Up @@ -385,6 +387,7 @@ void initiateNearbyService() async {
strategy: Strategy.P2P_CLUSTER,
callback: (isRunning) async {
if (isRunning) {

startAdvertising();
startBrowsing();

Expand Down
Loading

0 comments on commit a601f36

Please sign in to comment.