Update messenger.js

- merge conflicts
This commit is contained in:
sairajzero 2022-08-10 03:01:50 +05:30
parent 392f3a112b
commit 285136b1e9

View File

@ -1,6 +1,15 @@
(function () { (function() {
const messenger = window.messenger = {}; const messenger = window.messenger = {};
const user = {
get id() {
return floDapps.user.id
},
get public() {
return floDapps.user.public
}
}
const expiredKeys = {}; const expiredKeys = {};
const UI = { const UI = {
@ -121,7 +130,7 @@
floCloudAPI.closeRequest(groupConnID[groupID]); floCloudAPI.closeRequest(groupConnID[groupID]);
delete groupConnID[groupID]; delete groupConnID[groupID];
} }
let callbackFn = function (dataSet, error) { let callbackFn = function(dataSet, error) {
if (error) if (error)
return console.error(error) return console.error(error)
console.info(dataSet) console.info(dataSet)
@ -162,7 +171,7 @@
data.rmMembers = dataSet[vc].message.split("|") data.rmMembers = dataSet[vc].message.split("|")
data.note = dataSet[vc].comment data.note = dataSet[vc].comment
groupInfo.members = groupInfo.members.filter(m => !data.rmMembers.includes(m)) groupInfo.members = groupInfo.members.filter(m => !data.rmMembers.includes(m))
if (data.rmMembers.includes(myFloID)) { if (data.rmMembers.includes(user.id)) {
disableGroup(groupID); disableGroup(groupID);
return; return;
} }
@ -181,7 +190,7 @@
if (data.message) if (data.message)
data.message = decrypt(data.message); data.message = decrypt(data.message);
newInbox.messages[vc] = data; newInbox.messages[vc] = data;
if (data.sender !== myFloID) if (data.sender !== user.id)
addMark(data.groupID, "unread") addMark(data.groupID, "unread")
if (!_loaded.appendix[`lastReceived_${groupID}`] || if (!_loaded.appendix[`lastReceived_${groupID}`] ||
_loaded.appendix[`lastReceived_${groupID}`] < vc) _loaded.appendix[`lastReceived_${groupID}`] < vc)
@ -211,7 +220,7 @@
} }
const initUserDB = function () { const initUserDB = function() {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
var obj = { var obj = {
messages: {}, messages: {},
@ -221,18 +230,20 @@
groups: {}, groups: {},
gkeys: {}, gkeys: {},
blocked: {}, blocked: {},
flodata: {},
appendix: {}, appendix: {},
userSettings: {} userSettings: {}
} }
compactIDB.initDB(`${floGlobals.application}_${myFloID}`, obj).then(result => { let user_db = `${floGlobals.application}_${user.id}`;
compactIDB.initDB(user_db, obj).then(result => {
console.info(result) console.info(result)
compactIDB.setDefaultDB(`${floGlobals.application}_${myFloID}`); compactIDB.setDefaultDB(user_db);
resolve("Messenger UserDB Initated Successfully") resolve("Messenger UserDB Initated Successfully")
}).catch(error => reject(error)); }).catch(error => reject(error));
}) })
} }
messenger.blockUser = function (floID) { messenger.blockUser = function(floID) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if (_loaded.blocked.has(floID)) if (_loaded.blocked.has(floID))
return resolve("User is already blocked"); return resolve("User is already blocked");
@ -243,7 +254,7 @@
}) })
} }
messenger.unblockUser = function (floID) { messenger.unblockUser = function(floID) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if (!_loaded.blocked.has(floID)) if (!_loaded.blocked.has(floID))
return resolve("User is not blocked"); return resolve("User is not blocked");
@ -254,7 +265,7 @@
}) })
} }
messenger.sendMessage = function (message, receiver) { messenger.sendMessage = function(message, receiver) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
sendRaw(message, receiver, "MESSAGE").then(result => { sendRaw(message, receiver, "MESSAGE").then(result => {
let vc = result.vectorClock; let vc = result.vectorClock;
@ -277,7 +288,7 @@
}) })
} }
messenger.sendMail = function (subject, content, recipients, prev = null) { messenger.sendMail = function(subject, content, recipients, prev = null) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if (!Array.isArray(recipients)) if (!Array.isArray(recipients))
recipients = [recipients] recipients = [recipients]
@ -290,7 +301,7 @@
let promises = recipients.map(r => sendRaw(JSON.stringify(mail), r, "MAIL")) let promises = recipients.map(r => sendRaw(JSON.stringify(mail), r, "MAIL"))
Promise.allSettled(promises).then(results => { Promise.allSettled(promises).then(results => {
mail.time = Date.now(); mail.time = Date.now();
mail.from = myFloID mail.from = user.id
mail.to = [] mail.to = []
results.forEach(r => { results.forEach(r => {
if (r.status === "fulfilled") if (r.status === "fulfilled")
@ -310,12 +321,12 @@
}) })
} }
const requestDirectInbox = function () { const requestDirectInbox = function() {
if (directConnID) { //close existing request connection (if any) if (directConnID) { //close existing request connection (if any)
floCloudAPI.closeRequest(directConnID); floCloudAPI.closeRequest(directConnID);
directConnID = undefined; directConnID = undefined;
} }
let callbackFn = function (dataSet, error) { let callbackFn = function(dataSet, error) {
if (error) if (error)
return console.error(error) return console.error(error)
let newInbox = { let newInbox = {
@ -331,7 +342,7 @@
if (_loaded.blocked.has(dataSet[vc].senderID) && dataSet[vc].type !== "REVOKE_KEY") if (_loaded.blocked.has(dataSet[vc].senderID) && dataSet[vc].type !== "REVOKE_KEY")
throw "blocked-user"; throw "blocked-user";
if (dataSet[vc].message instanceof Object && "secret" in dataSet[vc].message) if (dataSet[vc].message instanceof Object && "secret" in dataSet[vc].message)
dataSet[vc].message = floCrypto.decryptData(dataSet[vc].message, myPrivKey) dataSet[vc].message = floDapps.user.decrypt(dataSet[vc].message);
if (dataSet[vc].type === "MESSAGE") { if (dataSet[vc].type === "MESSAGE") {
//process as message //process as message
let dm = { let dm = {
@ -354,7 +365,7 @@
let mail = { let mail = {
time: dataSet[vc].time, time: dataSet[vc].time,
from: dataSet[vc].senderID, from: dataSet[vc].senderID,
to: [myFloID], to: [user.id],
subject: data.subject, subject: data.subject,
content: encrypt(data.content), content: encrypt(data.content),
ref: data.ref, ref: data.ref,
@ -412,14 +423,14 @@
UI.direct(newInbox) UI.direct(newInbox)
} }
floCloudAPI.requestApplicationData(null, { floCloudAPI.requestApplicationData(null, {
receiverID: myFloID, receiverID: user.id,
lowerVectorClock: _loaded.appendix.lastReceived + 1, lowerVectorClock: _loaded.appendix.lastReceived + 1,
callback: callbackFn callback: callbackFn
}).then(conn_id => directConnID = conn_id) }).then(conn_id => directConnID = conn_id)
.catch(error => console.error("request-direct:", error)); .catch(error => console.error("request-direct:", error));
} }
messenger.getMail = function (mailRef) { messenger.getMail = function(mailRef) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
compactIDB.readData("mails", mailRef).then(mail => { compactIDB.readData("mails", mailRef).then(mail => {
mail.content = decrypt(mail.content) mail.content = decrypt(mail.content)
@ -428,7 +439,7 @@
}); });
} }
const getChatOrder = messenger.getChatOrder = function (separate = false) { const getChatOrder = messenger.getChatOrder = function(separate = false) {
let result; let result;
if (separate) { if (separate) {
result = {}; result = {};
@ -444,11 +455,11 @@
return result; return result;
} }
messenger.storeContact = function (floID, name) { messenger.storeContact = function(floID, name) {
return floDapps.storeContact(floID, name) return floDapps.storeContact(floID, name)
} }
const loadDataFromIDB = function (defaultList = true) { const loadDataFromIDB = function(defaultList = true) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if (defaultList) if (defaultList)
dataList = ["mails", "marked", "groups", "chats", "blocked", "appendix"] dataList = ["mails", "marked", "groups", "chats", "blocked", "appendix"]
@ -464,7 +475,7 @@
data.appendix.lastReceived = data.appendix.lastReceived || '0'; data.appendix.lastReceived = data.appendix.lastReceived || '0';
if (data.appendix.AESKey) { if (data.appendix.AESKey) {
try { try {
let AESKey = floCrypto.decryptData(data.appendix.AESKey, myPrivKey); let AESKey = floDapps.user.decrypt(data.appendix.AESKey);
data.appendix.AESKey = AESKey; data.appendix.AESKey = AESKey;
if (dataList.includes("messages")) if (dataList.includes("messages"))
for (let m in data.messages) for (let m in data.messages)
@ -481,13 +492,14 @@
data.gkeys[k] = decrypt(data.gkeys[k], AESKey); data.gkeys[k] = decrypt(data.gkeys[k], AESKey);
resolve(data) resolve(data)
} catch (error) { } catch (error) {
console.error(error)
reject("Corrupted AES Key"); reject("Corrupted AES Key");
} }
} else { } else {
if (Object.keys(data.mails).length) if (Object.keys(data.mails).length)
return reject("AES Key not Found") return reject("AES Key not Found")
let AESKey = floCrypto.randString(32, false); let AESKey = floCrypto.randString(32, false);
let encryptedKey = floCrypto.encryptData(AESKey, myPubKey); let encryptedKey = floCrypto.encryptData(AESKey, user.public);
compactIDB.addData("appendix", encryptedKey, "AESKey").then(result => { compactIDB.addData("appendix", encryptedKey, "AESKey").then(result => {
data.appendix.AESKey = AESKey; data.appendix.AESKey = AESKey;
resolve(data); resolve(data);
@ -497,19 +509,19 @@
}) })
} }
messenger.addMark = function (key, mark) { messenger.addMark = function(key, mark) {
if (_loaded.marked.hasOwnProperty(key) && !_loaded.marked[key].includes(mark)) if (_loaded.marked.hasOwnProperty(key) && !_loaded.marked[key].includes(mark))
_loaded.marked[key].push(mark) _loaded.marked[key].push(mark)
return addMark(key, mark) return addMark(key, mark)
} }
messenger.removeMark = function (key, mark) { messenger.removeMark = function(key, mark) {
if (_loaded.marked.hasOwnProperty(key)) if (_loaded.marked.hasOwnProperty(key))
_loaded.marked[key] = _loaded.marked[key].filter(v => v !== mark) _loaded.marked[key] = _loaded.marked[key].filter(v => v !== mark)
return removeMark(key, mark) return removeMark(key, mark)
} }
messenger.addChat = function (chatID) { messenger.addChat = function(chatID) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
compactIDB.addData("chats", 0, chatID) compactIDB.addData("chats", 0, chatID)
.then(result => resolve("Added chat")) .then(result => resolve("Added chat"))
@ -517,7 +529,7 @@
}) })
} }
messenger.rmChat = function (chatID) { messenger.rmChat = function(chatID) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
compactIDB.removeData("chats", chatID) compactIDB.removeData("chats", chatID)
.then(result => resolve("Chat removed")) .then(result => resolve("Chat removed"))
@ -525,7 +537,7 @@
}) })
} }
messenger.clearChat = function (chatID) { messenger.clearChat = function(chatID) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
let options = { let options = {
lowerKey: `${chatID}|`, lowerKey: `${chatID}|`,
@ -542,7 +554,7 @@
}) })
} }
messenger.getChat = function (chatID) { messenger.getChat = function(chatID) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
let options = { let options = {
lowerKey: `${chatID}|`, lowerKey: `${chatID}|`,
@ -557,7 +569,7 @@
}) })
} }
messenger.backupData = function () { messenger.backupData = function() {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
loadDataFromIDB(false).then(data => { loadDataFromIDB(false).then(data => {
delete data.appendix.AESKey; delete data.appendix.AESKey;
@ -565,11 +577,11 @@
data.pubKeys = floGlobals.pubKeys; data.pubKeys = floGlobals.pubKeys;
data = btoa(unescape(encodeURIComponent(JSON.stringify(data)))) data = btoa(unescape(encodeURIComponent(JSON.stringify(data))))
let blobData = { let blobData = {
floID: myFloID, floID: user.id,
pubKey: myPubKey, pubKey: user.public,
data: encrypt(data, myPrivKey), data: floDapps.user.encipher(data),
} }
blobData.sign = floCrypto.signData(blobData.data, myPrivKey); blobData.sign = floDapps.sign(blobData.data);
resolve(new Blob([JSON.stringify(blobData)], { resolve(new Blob([JSON.stringify(blobData)], {
type: 'application/json' type: 'application/json'
})); }));
@ -577,7 +589,7 @@
}) })
} }
const parseBackup = messenger.parseBackup = function (blob) { const parseBackup = messenger.parseBackup = function(blob) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if (blob instanceof Blob || blob instanceof File) { if (blob instanceof Blob || blob instanceof File) {
let reader = new FileReader(); let reader = new FileReader();
@ -585,11 +597,11 @@
var blobData = JSON.parse(evt.target.result); var blobData = JSON.parse(evt.target.result);
if (!floCrypto.verifySign(blobData.data, blobData.sign, blobData.pubKey)) if (!floCrypto.verifySign(blobData.data, blobData.sign, blobData.pubKey))
reject("Corrupted Backup file: Signature verification failed"); reject("Corrupted Backup file: Signature verification failed");
else if (myFloID !== blobData.floID || myPubKey !== blobData.pubKey) else if (user.id !== blobData.floID || user.public !== blobData.pubKey)
reject("Invalid Backup file: Incorrect floID"); reject("Invalid Backup file: Incorrect floID");
else { else {
try { try {
let data = decrypt(blobData.data, myPrivKey) let data = floDapps.user.decipher(blobData.data);
try { try {
data = JSON.parse(decodeURIComponent(escape(atob(data)))); data = JSON.parse(decodeURIComponent(escape(atob(data))));
resolve(data) resolve(data)
@ -607,7 +619,7 @@
}) })
} }
messenger.restoreData = function (arg) { messenger.restoreData = function(arg) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if (arg instanceof Blob || arg instanceof File) if (arg instanceof Blob || arg instanceof File)
var parseData = parseBackup var parseData = parseBackup
@ -660,7 +672,7 @@
}) })
} }
messenger.clearUserData = function () { messenger.clearUserData = function() {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
let promises = [ let promises = [
compactIDB.deleteDB(), compactIDB.deleteDB(),
@ -674,18 +686,18 @@
//group feature //group feature
messenger.createGroup = function (groupname, description = '') { messenger.createGroup = function(groupname, description = '') {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if (!groupname) return reject("Invalid Group Name") if (!groupname) return reject("Invalid Group Name")
let id = floCrypto.generateNewID(); let id = floCrypto.generateNewID();
let groupInfo = { let groupInfo = {
groupID: id.floID, groupID: id.floID,
pubKey: id.pubKey, pubKey: id.pubKey,
admin: myFloID, admin: user.id,
name: groupname, name: groupname,
description: description, description: description,
created: Date.now(), created: Date.now(),
members: [myFloID] members: [user.id]
} }
let h = ["groupID", "created", "admin"].map(x => groupInfo[x]).join('|') let h = ["groupID", "created", "admin"].map(x => groupInfo[x]).join('|')
groupInfo.hash = floCrypto.signData(h, id.privKey) groupInfo.hash = floCrypto.signData(h, id.privKey)
@ -702,10 +714,10 @@
}) })
} }
messenger.changeGroupName = function (groupID, name) { messenger.changeGroupName = function(groupID, name) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
let groupInfo = _loaded.groups[groupID] let groupInfo = _loaded.groups[groupID]
if (myFloID !== groupInfo.admin) if (user.id !== groupInfo.admin)
return reject("Access denied: Admin only!") return reject("Access denied: Admin only!")
let message = encrypt(name, groupInfo.eKey) let message = encrypt(name, groupInfo.eKey)
sendRaw(message, groupID, "UP_NAME", false) sendRaw(message, groupID, "UP_NAME", false)
@ -714,10 +726,10 @@
}) })
} }
messenger.changeGroupDescription = function (groupID, description) { messenger.changeGroupDescription = function(groupID, description) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
let groupInfo = _loaded.groups[groupID] let groupInfo = _loaded.groups[groupID]
if (myFloID !== groupInfo.admin) if (user.id !== groupInfo.admin)
return reject("Access denied: Admin only!") return reject("Access denied: Admin only!")
let message = encrypt(description, groupInfo.eKey) let message = encrypt(description, groupInfo.eKey)
sendRaw(message, groupID, "UP_DESCRIPTION", false) sendRaw(message, groupID, "UP_DESCRIPTION", false)
@ -726,7 +738,7 @@
}) })
} }
messenger.addGroupMembers = function (groupID, newMem, note = undefined) { messenger.addGroupMembers = function(groupID, newMem, note = undefined) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if (!Array.isArray(newMem) && typeof newMem === "string") if (!Array.isArray(newMem) && typeof newMem === "string")
newMem = [newMem] newMem = [newMem]
@ -743,7 +755,7 @@
return reject(`Invalid Members (pubKey not available): ${imem2}`) return reject(`Invalid Members (pubKey not available): ${imem2}`)
//send new newMem list to existing members //send new newMem list to existing members
let groupInfo = _loaded.groups[groupID] let groupInfo = _loaded.groups[groupID]
if (myFloID !== groupInfo.admin) if (user.id !== groupInfo.admin)
return reject("Access denied: Admin only!") return reject("Access denied: Admin only!")
let k = groupInfo.eKey; let k = groupInfo.eKey;
//send groupInfo to new newMem //send groupInfo to new newMem
@ -765,7 +777,7 @@
}) })
} }
messenger.rmGroupMembers = function (groupID, rmMem, note = undefined) { messenger.rmGroupMembers = function(groupID, rmMem, note = undefined) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if (!Array.isArray(rmMem) && typeof rmMem === "string") if (!Array.isArray(rmMem) && typeof rmMem === "string")
rmMem = [rmMem] rmMem = [rmMem]
@ -773,7 +785,7 @@
let imem = rmMem.filter(m => !groupInfo.members.includes(m)) let imem = rmMem.filter(m => !groupInfo.members.includes(m))
if (imem.length) if (imem.length)
return reject(`Invalid members: ${imem}`) return reject(`Invalid members: ${imem}`)
if (myFloID !== groupInfo.admin) if (user.id !== groupInfo.admin)
return reject("Access denied: Admin only!") return reject("Access denied: Admin only!")
let message = encrypt(rmMem.join("|"), groupInfo.eKey) let message = encrypt(rmMem.join("|"), groupInfo.eKey)
let p1 = sendRaw(message, groupID, "RM_MEMBERS", false, note) let p1 = sendRaw(message, groupID, "RM_MEMBERS", false, note)
@ -785,10 +797,10 @@
}) })
} }
const revokeKey = messenger.revokeKey = function (groupID) { const revokeKey = messenger.revokeKey = function(groupID) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
let groupInfo = _loaded.groups[groupID] let groupInfo = _loaded.groups[groupID]
if (myFloID !== groupInfo.admin) if (user.id !== groupInfo.admin)
return reject("Access denied: Admin only!") return reject("Access denied: Admin only!")
let newKey = floCrypto.randString(16, false); let newKey = floCrypto.randString(16, false);
Promise.all(groupInfo.members.map(m => sendRaw(JSON.stringify({ Promise.all(groupInfo.members.map(m => sendRaw(JSON.stringify({
@ -800,7 +812,7 @@
}) })
} }
messenger.sendGroupMessage = function (message, groupID) { messenger.sendGroupMessage = function(message, groupID) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
let k = _loaded.groups[groupID].eKey let k = _loaded.groups[groupID].eKey
message = encrypt(message, k) message = encrypt(message, k)
@ -810,7 +822,7 @@
}) })
} }
const disableGroup = messenger.disableGroup = function (groupID) { const disableGroup = messenger.disableGroup = function(groupID) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if (!_loaded.groups[groupID]) if (!_loaded.groups[groupID])
return reject("Group not found"); return reject("Group not found");
@ -829,7 +841,7 @@
}) })
} }
messenger.init = function () { messenger.init = function() {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
initUserDB().then(result => { initUserDB().then(result => {
console.debug(result); console.debug(result);