Server for the be8 messenger.
const body = {
nickname: 'picked name or randomly generated name',
password: 'randomly generated',
};
fetch('/newacc', {
method: 'POST',
body,
});
{
nickname: 'picked name or randomly generated name',
password: 'randomly generated pw',
type: 'user',
expire: 'Date object', // acc expires after 30 days
id: 'generated acc id'
}
Returns the acc (without password) of the actual session.
fetch('/me', {
method: 'GET',
});
User can change his nick every time and as often as he wants to.
const body = {
newNickname: 'picked new name',
oldNickname: 'former name',
};
fetch('/changenickname', {
method: 'POST',
body,
});
Deletes the acc of the actual session and all conversations of the acc. If the user is a group admin, the group will be deleted too.
fetch('/destroyacc', {
method: 'GET',
});
Handles threads and messages.
Fetches all threads for the acc of the actual session. A threadID is always a compound of the two conversation partners, e.g. 10281:10317, 10281:g123 (for groups).
fetch('/getthreads', {
method: 'GET',
});
[{
expire: 'some date',
nickname: 'nice nick',
sender: '10281', // system acc
status: 'read', // unread
text: 'wkdjf48isjfdskjf92834ied', // text of last message encrypted
threadID: '10281:10326',
ts: 'time of last message',
type: 'user' // system
}, {
...
}]
Fetches all messages of a conversation but returns only the last 100. A messageID is always an iterating number in the thread. For storing it into the db the threadID is compound with the messageID, e.g. 10281:10317:7.
const body = {
threadID: 'some thread id',
};
fetch('/getmessages', {
method: 'POST',
body,
});
[{
messageID: '4',
nickname: 'fancy name',
receiver: '10317',
sender: '10281',
status: ['10317'], // ids of accs that already have seen the messages
text: 'OrIXGw8CR6TYin5f2XNTuFpurMoPo7SgVtL3AKx', // text is always encrypted
threadID: '10281:10317',
ts: 'Wed Jun 22 2022 11:08:35 GMT+0000 (Coordinated Universal Time)',
type: 'textMessage', // system, imageMessage
}, {
...
}]
When starting a conversation the threadID and a system message for both conversation partner in the thread is getting generated.
const body = {
receiverID: 'some id',
};
fetch('/startconversation', {
method: 'POST',
body,
});
When writing a message your conversation partner, or everyone in a group you are writing to, is getting a pushnotification.
const body = {
nickname: 'fancy dude'
receiver: '10317'
sender: '10281'
text: 'lbpyj3HzcX4v3WbNMka90X7XJRCmrw=='
threadID: '10281:10317'
type: 'textMessage'
};
fetch('/writemessage', {
method: 'POST',
body
});
Handles all group activities incl. encrypted group keys. //TODO: private public groups
The groupID is always a generated number with a leading 'g'. The creator is automatically the admin and gets a system message for creating the group. There are private and public groups.
const body = {
groupType: 'public', // private
nickname: 'fancy groupname',
maxMembers: 100, // optional, default is set to 20
};
fetch('/groupcreate', {
method: 'POST',
body,
});
{
groupID: 'g1234',
nickname: 'fancy groupname',
type: 'group',
groupType: 'public',
admin: '10317', // creator
maxMembers: 100,
}
In a public group everyone can add another member unless the maxMembers are not reached. In a private group only the admin can add new members.
const body = {
groupID: 'g1234',
memberID: '10281'
};
fetch('/groupaddmember', {
method: 'POST',
body,
});
Acc of actual session got added to a public group by clicking the invite link. If no acc was created before one get's automatically created and added to the group.
const body = {
groupID: 'g1234'
};
fetch('/groupjoinmember', {
method: 'POST',
body,
});
Returns all members and the admin always on first position.
const body = {
groupID: 'g1234'
};
fetch('/groupgetmembers', {
method: 'POST',
body,
});
If someone leaves the group a new groupkey is getting generated. If he rejoins the group he can see the old messages he saw before leaving but not the ones after leaving.
const body = {
accID: '10281',
groupID: 'g1234'
};
fetch('/groupleavemember', {
method: 'POST',
body,
});
Only the admin is able to kick a member of a group. The admin cannot kick himself.
const body = {
accID: '10281',
groupID: 'g1234'
};
fetch('/groupkickmember', {
method: 'POST',
body,
});
When a group get's destroyed it's removed from every member's thread, so no one can read the messages anymore. Only the admin can destroy the group.
const body = {
groupID: 'g1234'
};
fetch('/groupdestroygroup', {
method: 'POST',
body,
});
Everytime a member leaves the group or is added, a new group key is getting generated and stored encrypted for every member of the group. Also the groupVersion is increased and stored for every member that is still in the group.
const body = {
groupID: 'g1234',
groupKey: 'encrypted group key',
accID: '10281',
keyholder: '10281'
};
fetch('/groupstorekey', {
method: 'POST',
body,
});
Only groupKeys are returned for the groupVersion that are stored for the particular acc. Only when the user is part of the group.
const body = {
groupID: 'g1234',
accID: '10281'
};
fetch('/groupgetkeys', {
method: 'POST',
body,
});
When sending a message in a group the current group version is getting fetched for encrypting the message with the dedicated group key.
const body = {
groupID: 'g1234'
};
fetch('/groupgetcurrentversion', {
method: 'POST',
body,
});
Trigger server sent events for different types.
const body = {
groupID: 'g1234',
type: 'joinmember' // 'leavegroup'
};
fetch('/grouptriggersseupdate', {
method: 'POST',
body,
});
Handles the counting of the generated and used invite links for users and groups.
const body = {
sentInviteLink: true, // could also be usedInviteLink: true
type: 'join' // group
};
fetch('/invitelink', {
method: 'POST',
body
});
Handling of the public keys.
Sets the frontend generated public key for the acc of the actual session.
const body = {
publicKey: {
crv: 'P-384',
ext: 'true',
key_ops: [],
kty: 'EC',
x: 'some part of key',
y: 'other part of key'
}
};
fetch('/setkey', {
method: 'POST',
body
});
Returns the public key for a given acc.
const body = {
accID: '10281'
};
fetch('/getkey', {
method: 'POST',
body
});
Returns the public keys for several given accs.
const body = {
accIDs: ['10281', '10326']
};
fetch('/getkeys', {
method: 'POST',
body
});
Writes the encrypted base64 file to a .bin file on the server storage. The name of the file is a mix of sender nickname and contentID.
const body = {
content: 'some encrypted base64 string',
contentID: 'random String',
contentType: 'image',
nickname: 'name of the sender',
receiver: '10326',
sender: '10281',
threadID: '10281:10326',
type: 'imageMessage'
};
fetch('/imageupload', {
method: 'POST',
body
});
Returns the encrypted file with sender contentID and type of the content.
const body = {
sender: '10281',
contentID: 'generated id at upload'
};
fetch('/imageget', {
method: 'POST',
body
});
Returns some stats of the messenger.
fetch('/insights', {
method: 'GET'
});
Returns an array with numbers. Handled in frontend.
[
'10327', // accs generated. Starts at 10000
'10023', // groups generated. Starts at 10000
'352', // threads
'4010', // messages
'160', // generated invite links
'53', // joined invite links
'38', // generated group invite links
'83', // used group invite links
]
Adds the device keys for pushnotifications to the db.
const body = {
// the device keys
};
fetch('/subscribe', {
method: 'POST',
body
});