A silly backend which saves and delivers messages
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.
 
 
Jonas Lochmann e9b91f6c35
Update dependencies
3 years ago
src Fix keeping status items 3 years ago
.gitignore Initial commit 3 years ago
Dockerfile Initial commit 3 years ago
Readme.md Fix link to socket.io 3 years ago
package-lock.json Update dependencies 3 years ago
package.json Update dependencies 3 years ago
tsconfig.json Initial commit 3 years ago
tslint.json Initial commit 3 years ago

Readme.md

Communication Server

A silly backend which saves and delivers messages

Device IDs

Every device can generate a id by itself and use it. A device id must match the pattern ^[a-zA-Z0-9+/=]{24}$.

Device authentication

Every device can chose an authentication token by itself and use it. The token is a string which muste have at least 32 chars.

The authentication token is set when a device connects the first time. Due to the automated deletion of old data, a new device can take an existing device id and set a new token when the old device has not connected for 4 weeks.

Messages

A message is a piece of data which can be sent from one device to an other device. It has the following fields at the database:

  • senderDeviceId
  • messageId
  • receiverDeviceId
  • sequenceId
  • content
  • time

As soon as the receiver confirms the delivery by adding the message id to receivedMessageIds in a sync request, the message is removed from the server.

Message Content

The message content must match the pattern /^[a-zA-Z0-9+/=]*$/.

Sequence IDs

To prevent duplicate messages, every message gets a number. The sequence id can be any number starting 0.

If a device sends a message whose sequence id is smaller or equal to a previous message sent by this device, than the new message will be ignored.

The sender device can see which messages are not yet delivered in the pendingSentMessageSequenceIds response field. Messages are deleted if they were not delivered within one week. The deletion without delivery removes the sequence id from the pendingSentMessageSequenceIds response field too.

Statuses

A status is a piece of data which can be sent from one device. One status can be sent to multiple devices. A status must be sent to at least one device.

A status has got the following fields at the database:

  • senderDeviceId
  • statusId
  • content
  • time
  • receiverDeviceIds

Status ID

The status id must match the pattern /^[a-zA-Z0-9]{10}$/.

Status Content

The status content must match the pattern /^[a-zA-Z0-9+/=]*$/.

Sending

To send/ keep a status, it must be added to the putStatus request field.

If a status is not in the putStatus anymore, then it's considered old and is deleted.

If newContent is not set for a status, then it's assumed that the content is equal to the previous content of this status. If newContent is not set and there is no previous content, then the status id is added to missingStatusContent .

Receiving

Status changes are reported using the response field statusUpdates.

For caching, the client can set the receivedStatus field to specify the statuses he received. Then only updates are reported using the response field statusUpdates. if the content of a status update is not set, then the status which is contained in receivedStatus does not exist anymore.

Privacy

  • anyone can take any unused device id
  • the sender of a message knows when the message was delivered
  • anyone can send messages to anyone
  • messages and status updates contain timestamps

Resulting recommendations:

  • input validation
  • input validation
  • input validation
  • encrypting and signing the data
  • generating device ids randomly
  • keeping device ids private

Scaling

Using multiple instances of this server application with the same database breaks the change notifications.

API

There is exactly one endpoint: /sync. The requests and responses use JSON. They are described here and here.

Notifications/ Push

To allow a fast message delivery, it's possible to suscribe for changes using socket.io. To use that:

  • connect to the server with a socket.io client
  • after connecting, emit ('subscribe', deviceId, authToken, confirmationListener) where confirmationListener is a function
  • wait for the event 'changes'
  • the change event has got one parameter of the type object with these properties:
    • messages (boolean, true if and only if there is a new message for this device)
    • status (boolean, true if and only if the status messages sent to this device were changed)
    • deliveredMessages (boolean, true if and only if messages sent from this device were delivered)

The notifications are not triggered when deleting old data.

Deletion of old data

  • device registrations (last activity timestamp, auth token) are deleted after 4 weeks without activity
  • messages are deleted after 1 week if they were not delivered
  • statuses are deleted if the sender didn't do any sync for 1 week

Usage

  • install the dependencies with npm install
  • build it with npm run build
  • eventually set environment variables
    • PORT (the listening port for the http server)
    • DATABASE_URL (the url of the database which should be used)
  • start it with npm start

License

Copyright (C) 2019 Jonas Lochmann

This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, version 3 of the License.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License along with this program. If not, see https://www.gnu.org/licenses/.