Giter Site home page Giter Site logo

muke1908 / chat-e2ee Goto Github PK

View Code? Open in Web Editor NEW
311.0 311.0 193.0 3.65 MB

End-to-end encrypted disposable chat sessions, exchange sensitive information with peer safely and securely.

Home Page: https://chat-e2ee-2.azurewebsites.net/

License: Apache License 2.0

JavaScript 2.03% HTML 1.22% CSS 14.76% Dockerfile 0.67% Shell 0.40% TypeScript 80.93%
chat encryption javascript react socket-io typescipt typescript

chat-e2ee's Introduction

chat-e2ee

Disposable chat session: this app will allow two mutually agreed users to have a chat in end-to-end encrypted environment. The app itself doesn't track you or ask for any information from you. Data is owned by only you and only while chatting. Your private key is generated on your device and never leaves your device. This is not a replacement for your usual chat application.

The project is still in development phase and open for contribution.
Demo: https://chat-e2ee-2.azurewebsites.net

Open in Gitpod


Code Smells

Features

  1. No login/signup - the end users don't identify themselves.
  2. Data is not stored on any remote server, encrypted data is just relayed to other users, the data can't be decrypted by any man in the middle.
  3. No history i.e. once chat is closed the data is not recoverable, however encrypted data can be found on memory trace. Read More

โญ JS SDK

Spin up your own frontend: JS SDK and use chat-e2ee backend as service - @chate2ee/service
๐Ÿ“ƒ Documentation


For installation instruction, go to developer section.

How to initiate chat

  1. Generate a unique link.
  2. Share the link or PIN with the person you want to chat with.
  3. Start chatting.
  4. The messages are end-to-end encrypted; therefore, no one can decrypt your message other than you.

How the encryption works

  1. Alice and Bob generate a public and private key pair.
  2. Alice and Bob share their public keys with each other.
  3. Alice encrypts her message with Bob's public key and sends it to Bob.
  4. Bob receives the encrypted message and decrypts it with his private key.

In this way, no one else can decrypt the message because your private key is never exposed/shared to the internet. More detailed explanation: https://www.youtube.com/watch?v=GSIDS_lvRv4&t=1s

We are using browser window.crypto library for encryption.


Flow

flow


๐Ÿ’ป For developers

Open Source Love GitHub last commit Quality Gate Status Gitter

Frontend (UI):
This project includes a light weight frontend UI - bootstrapped with create-react-app. The FE client is located in ./client folder.

Backend:
The backend runs on express/nodejs. In production mode, express server exposes the API endpoints and serves the static frontend from ./client/build.

JS SDK:
@chat-e2ee/service - located in ./service - A SDK that client uses to interact with backend. More info: Readme

Custom frontend
Import @chat-e2ee/service SDK in your client project and build your own chat client.

Installation

  1. Fork this repository by clicking on the fork button on the top of this page. This will create a copy of this repository in your account.
  2. Now clone the forked repository to your machine.
  3. Run npm install in root dir i.e. inside cloned repo.
  4. Run npm run dev to spin up your client/server. This will run your react app in dev mode and server in watch mode by nodemon.

โ—โ—Important: If you are making changes to ./service i.e. @chat-e2ee/service, make sure you run npm run build-service-sdk to reflect changes.

NOTE: by default, create-react-app runs webpack-dev-server on port 3000. The server is configured to run on 3001 port. So, make sure that these ports are not blocked on your system.

Important:
Check .env.sample to configure your .env file.
Please use node 16 or above.

To start with docker read the instructions.
For native build read the instructions.

Folder structure

  • The FE client is located in ./client which is coupled with the backend.
  • All the backend controllers go to ./backend folder.
  • Client uses a package @chate2ee/service to communicate with the backend. Located in ./service.
  • Express instance is on ./app.js.
  • Entry point is ./index.js.

Please follow the convention for the commit message.
https://github.com/conventional-changelog/commitlint/#what-is-commitlint

Example:
git commit -m"feat: some relevant message"


โœจ Contributors


๐Ÿ” Cryptographic notice

This distribution includes cryptographic software. The country in which you currently reside may have restrictions on the import, possession, use, and/or re-export to another country, of encryption software. BEFORE using any encryption software, please check your country's laws, regulations and policies concerning the import, possession, or use, and re-export of encryption software, to see if this is permitted. See http://www.wassenaar.org/ for more information.

The U.S. Government Department of Commerce, Bureau of Industry and Security (BIS) has classified this software as Export Commodity Control Number (ECCN) 5D002.C.1, which includes information security software using or performing cryptographic functions with asymmetric algorithms. The form and manner of this distribution makes it eligible for export under the License Exception ENC Technology Software Unrestricted (TSU) exception (see the BIS Export Administration Regulations, Section 740.13) for both object code and source code.

chat-e2ee's People

Contributors

aditya-13 avatar alirezariahi avatar allcontributors[bot] avatar amreekminocha avatar audreykj avatar codebysid avatar darksoul11 avatar dependabot[bot] avatar encrypted-soul avatar estefysc avatar fabisdr avatar firtysh avatar j-16 avatar jonatan5524 avatar joydeep2683 avatar jradha11 avatar lonewarrior581 avatar manny525 avatar ming-tsai avatar muke1908 avatar nafees87n avatar narasimha1997 avatar nexus-uw avatar ranjithrosan17 avatar ryuuko avatar salonigoyal2309 avatar suman313 avatar tomyotwongjai avatar trikcode avatar tskull01 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

chat-e2ee's Issues

Link generation UI

The home route where users can generate a unique chat link.

  • Basic instruction about the link and how it works.
  • "Generate link" button. ref #20
  • Loader while generating the link.
  • Show link.
  • The link should pre-selected for copying.

Location: ./client/src/pages/chatlink
Please refer to the UI below:

Link generation

Related issue #1

Create a reusable button component

Please take design reference from #2
Create a react component for a button that should take the following as props.

  • label
  • type <primary|secondary> default: primary
  • state <active|disabled> default: active
  • onClick
  • width

Add additional attributes while saving chat link in db.

Add the following properties while inserting link data:

await insertInDb(link, LINK_COLLECTION);

expired: false
deleted: false

Address the required changes in validateChannel function i.e. it should also check the link is not expired and deleted -

const channelValid = async (channel) => {

expired will be used if links are left unused for certain period of time.
deleted will be used if user explicitly deletes the link.

Verify if the channel is valid - exits in db

Write a controller validateLink in /backend/api/index.js - GET

It should take string from the query param and check whether it exists in the db.
If it exists it should return 200 else 404 with some message.

Use the function channelValid at backend/api/messaging/validateChannel.js

const isChannelValid = await channelValid(channel);
if (!isChannelValid) {
    // send 404
}
// send 200

Messaging: component to display list of messages

Create a component that accepts an array of objects as a prop where the objects represent one message block, and it should render the messages in a list view (Ref: attached image).
Example prop:

cosnt data = [
    {
       self: true,
       body: "Hey Alice"
    }, {
       self: false,
       body: "Hi Bob"
    }
]

<MessageList data={data} />

chat (1)

Note: The message block should align accordingly. If it's sent by you (i.e. self: true) it should appear on the right side of you.

Display chat session statuses in UI

Once clicked the chat link, following things happen.

  1. It checks for the participant's public key. getSetUsers
  2. It generates its key pair and shares the public key. exchangePublicKey
  3. In case public key not found in step 1, it waits for the other user to join and request public key once other user joins the chat.

Users can start chatting only once above steps are finished. Display the above statuses in the UI so that users are aware of stuff that are happening behind the scene.

Statuses need to displayed on UI:

  1. Checking for user.
  2. Sharing public key.
  3. Waiting for user.
  4. Online.

Update the readme.md with the instructions for captcha configuration

The home route contains a captcha that needs to configured while setting up the development environment. Update the readme summarizing the below steps.

  • Obtain key from the google captcha site.
  • Create the .env files in the root and client directory.
  • Use the relevant keys in both the .env files.

Messaging: Scroll down to bottom when there is a new message

When the list of messages exceeds the height of the container, the new messages are not visible until scrolled. The container needs to scroll down for the following cases:

  • When there is a new incoming message.
  • When a new message is sent.

FIX: rest api url structure

REST api endpoint should only point a resource. In url verb should be avoided and should be used appropriate method instead.
ref: https://restfulapi.net/resource-naming/

example:

Bad:
POST -> /chat-link/generate
GET -> /chat-link/validate/:channel
POST -> /chat/send
DELETE -> /chat-link/delete/:channel

Good:
CREATE-> /chat-link/
GET -> /chat-link/status/:channel
POST -> /chat/message
DELETE -> /chat-link/:channel

Improve auto scroll experience for chat messages

Auto scroll to new message should happen in the following scenarios

  • Whenever user sends a message
  • Whenever user receives a message and he is currently at the bottom of the message list

Auto scroll to new message should not happen in the following scenarios

  • User is reading old messages(i.e, is not scrolled to the bottom of chat window). In this case we can show an indicator which says X New messages which when clicked can scroll to the first unread message.

Setup be+fe project

Create and configure a project that will spin up a server.

  • in dev mode both fe and be should run on watch mode.
  • in prod env, the express server should serve the static fe.

Validate link before sending message.

When the client make POST request to /api/chat/send, server publishes the message to the channel which is given in request body. The channel should be validated before publishing the message i.e check if the value (channel) exists in db.
Controller: ./backend/api/messaging/index.js

Here the channel is the unique string that is generated at the starting of the chat session by requesting from the server(/api/getLink). The value is persisted in db - #1

Create component for chat link display

Create a react component that will take content as a prop.

Functionalities:

  1. It'll have a copy button
  2. Clicking on the copy button, the content will be copied to the clipboard.
  3. If someone clicks on the text it should get selected.

Example:

2020-07-22 18 27 06

Messaging: Create a layout for messaging page

When someone visits the generated link (#2), this page will open up.
Dir: client/src/pages/messaging/index

Check the attached image for reference.


This is just for the information not in the scope of this issue :
In this page following things will be handled:

  • Public key exchange
  • Storing public key in localStorage
  • Chatting interface

chat

Create an image component.

Create a react component that should take the following as props

  • src (source of the image)
  • maxHeight
  • maxWidth

It should maintain the aspect ratio of the image while not exceeding max height and max width.

desktop: Add basic emoji support

For non-mobile devices, add support for emoji.

  • Create a util function that detects whether it's a mobile device or not.
  • If not a mobile device, add a row of basic emojis right above the text area. (Chat page)

Button to retry fetching public key

Show a button:
-When a user joins the session, we try to get its public key on join

-In case, there is no key available at that moment or the request fails, show a button at the top that will allow the user to fetch the key again. Ref attached image.

-When someone clicks the button, call getSetUsers(channelID);.

While loading:

  • spin the button for better UX.
  • should not be clickable.

const getSetUsers = async (channelID) => {

-Once the key is received, make sure the button is not visible anymore.

Ref design:
Untitled

Configure mongodb

Create a mongo instance and configure/establish a connection with the server.

Audio component

Create a react component that plays a sound based on the props.

<Notification play={true} audio={audioFile} />

This should play the audio file when play is true.
It should play again when the props change from false to true

Write an endpoint(DELETE) that mark the chat link as deleted

Write a controller at https://github.com/muke1908/chat-e2ee/blob/master/backend/api/chatLink/index.js
DELETE - /chat-link/delete/<hash> - this will select the resource by hash and patch as deleted: true.

Example resource structure is:

{
   "hash": "a2ceea03-7f1e-4393-ba9c-a6ff477eb701",
   "link": "/chat/a2ceea03-7f1e-4393-ba9c-a6ff477eb701",
   "absoluteLink": "https://chat-e2ee.azurewebsites.net/chat/a2ceea03-7f1e-4393-ba9c-a6ff477eb701",
   "expired": false,
   "deleted": false
}

Refer: #95

Basic image sharing support

1 - Write a handler at,

<input className={styles.inputImagePicker} type="file" onChange={imagePicker} />

2 - and use imagePicker to get base64 string of the image and pass it to parent and store it in state (similar to text message).
https://github.com/muke1908/chat-e2ee/blob/master/client/src/utils/imagePicker.js

3- Modify the handleSubmit to send images.

const handleSubmit = (e) => {

Note: in the scope of this issue, we'll not handle encryption/decryption

Chat unique link

Write a controller: /backend/api/index.js - POST endpoint

  • use a hash/uuid to create a unique link
  • create db entry (dependent on #6 )
  • format and return link.

Suggested response:

{
   hash: <generated unique string>,
   formattedLink: <somedomain.com>/chat/<hash>
}

Validate a channel before adding client to list

When someone opens the chat link, we make a WebSocket connection and maintain a list of connected clients. We should only care about clients on a valid chat link.

socket.on('chat-join', (data) => {

It shouldn't add user to list if the channel is invalid. Validate using channelValid function

const channelValid = async (channel) => {

Add websocket to the project

Add socket.io to both client and server.
In the scope of this issue, just create utilities that establish a connection between client and server.

Prevent the user from sending empty messages

Currently, a user can send empty messages to the person he/she is chatting with. This might include an empty string(which is a message) or a message containing only 'n' number of spaces.

Disable the send button as long as the person(the one sending the message) enters a non-empty message.

Prevent submit for the empty message - let's just do alert('Please enter your message')

const handleSubmit = (e) => {

Websocket : establish connection

  • Find the right library/service that should be used for the web-socket connection.
  • Write utils in FE and BE to establish a connection between two clients based on the shared unique link.
  • A message sent by a client should be delivered to the other client live on the link.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.