diff --git a/index.html b/index.html
index 8d36bbb..46b3e34 100644
--- a/index.html
+++ b/index.html
@@ -1569,10 +1569,10 @@
let subject = subjectOfReplyMail.value;
let content = replyMailContent.value;
let prevRef = replyMailPopup.dataset.prevRef;
- messenger.replyMail(prevRef, subject, content, recipient).then(data => {
+ messenger.sendMail(subject, content, recipient, prevRef).then(data => {
notify(`Mail replied!`);
replyMailPopup.hide()
- let {ref, subject, time, category, floID, content} = data
+ let {ref, subject, time, from, to, prev, content} = data
sentMailContainer.prepend(render.mailCard(ref, subject, time, category, floID, content));
}).catch(error => notify("Failed to send mail!", "error", error))
}
@@ -10926,7 +10926,6 @@ Bitcoin.Util = {
var obj = {
messages: {},
mails: {},
- mailRef: {},
marked: {},
groupInfo: {},
groupMsg: {},
@@ -10961,72 +10960,38 @@ Bitcoin.Util = {
})
},
- sendMail(subject, content, recipients) {
+ sendMail(subject, content, recipients, prev = null) {
return new Promise(async (resolve, reject) => {
- let result = {
- success: {},
- error: {}
- }
+ if (!Array.isArray(recipients))
+ recipients = [recipients]
let mail = {
subject: subject,
content: content,
- ref: floCrypto.randString(32, true)
- }
- for (let i = 0; i < recipients.length; i++) {
- try {
- if (recipients[i] in floGlobals.pubKeys)
- result.success[recipients[i]] = await this.util.sendEncrypted(mail,
- recipients[i]);
- else
- result.success[recipients[i]] = await this.util.sendEncoded(mail,
- recipients[i]);
- } catch (error) {
- result.error[recipients[i]] = error;
- }
- }
- let data = {
- time: Date.now(),
- floID: Object.keys(result.success),
- category: "sentTo",
- subject: subject,
- ref: mail.ref
- }
- compactIDB.addData("mails", data, `${data.time}`)
- compactIDB.addData("mailContent", this.util.encrypt(content), `${data.time}`)
- compactIDB.addData("mailRef", `${data.time}`, mail.ref)
- result.data = data
- resolve(result)
- })
- },
-
- replyMail(prevRef, subject, content, recipient) {
- return new Promise(async (resolve, reject) => {
- let mail = {
- prevRef: prevRef,
- subject: subject,
- content: content,
- ref: floCrypto.randString(32, true)
- }
- try {
- if (recipient in floGlobals.pubKeys)
- await this.util.sendEncrypted(mail, recipient);
- else
- await this.util.sendEncoded(mail, recipient);
- let data = {
- time: Date.now(),
- floID: recipient,
- category: "replyTo",
- prevRef: prevRef,
- subject: subject,
- ref: mail.ref
- }
- compactIDB.addData("mails", data, `${data.time}`)
- compactIDB.addData("mailContent", this.util.encrypt(content), `${data.time}`)
- compactIDB.addData("mailRef", `${data.time}`, mail.ref)
- resolve(data)
- } catch (error) {
- reject(error)
+ ref: Date.now() + floCrypto.randString(8, true),
+ prev: prev
}
+ let promises = recipients.map(r => this.util.sendRaw(JSON.stringify(mail), r, "MAIL"))
+ Promise.allSettled(promises).then(results => {
+ mail.time = Date.now();
+ mail.from = myFloID
+ mail.to = []
+ results.forEach(r => {
+ if (r.status === "fulfilled") {
+ let vc = Object.keys(r.value).pop()
+ mail.to.push(r.value[vc].receiverID)
+ }
+ })
+ if (mail.to.length === 0)
+ return reject(results)
+ mail.content = this.util.encrypt(content)
+ compactIDB.addData("mails", {
+ ...mail
+ }, mail.ref)
+ mail.content = content
+ resolve({
+ [mail.ref]: mail
+ });
+ })
})
},
@@ -11046,41 +11011,42 @@ Bitcoin.Util = {
try {
//store the pubKey if not stored already
floDapps.storePubKey(dataSet[vc].senderID, dataSet[vc].pubKey)
- let data = {
- time: dataSet[vc].time,
- floID: dataSet[vc].senderID,
- }
if (dataSet[vc].message instanceof Object && "secret" in dataSet[vc]
.message)
dataSet[vc].message = floCrypto.decryptData(dataSet[vc].message,
myPrivKey)
if (dataSet[vc].type === "MESSAGE") {
//process as message
- data.category = "received"
- data.message = messenger.util.encrypt(dataSet[vc].message);
+ let dm = {
+ time: dataSet[vc].time,
+ floID: dataSet[vc].senderID,
+ category: "received",
+ message: messenger.util.encrypt(dataSet[vc].message)
+ }
compactIDB.addData("messages", {
- ...data
+ ...dm
}, vc)
- data.message = dataSet[vc].message;
- newInbox.messages[vc] = data;
- messenger.addMark(data.floID, "unread")
+ dm.message = dataSet[vc].message;
+ newInbox.messages[vc] = dm;
+ messenger.addMark(dm.floID, "unread")
} else if (dataSet[vc].type === "MAIL") {
//process as mail
- data.subject = dataSet[vc].message.subject;
- data.ref = dataSet[vc].message.ref;
- if (dataSet[vc].message.prevRef) {
- data.prevRef = dataSet[vc].message.prevRef;
- data.category = "replyFrom";
- } else
- data.category = "receivedFrom"
- data.content = messenger.util.encrypt(dataSet[vc].message.content)
+ let data = JSON.parse(dataSet[vc].message);
+ let mail = {
+ time: dataSet[vc].time,
+ from: dataSet[vc].senderID,
+ to: [myFloID],
+ subject: data.subject,
+ content: messenger.util.encrypt(data.content),
+ ref: data.ref,
+ prev: data.prev
+ }
compactIDB.addData("mails", {
- ...data
- }, vc);
- compactIDB.addData("mailRef", vc, data.ref)
- data.content = dataSet[vc].message.content;
- newInbox.mails[vc] = data;
- messenger.addMark(data.ref, "unread")
+ ...mail
+ }, mail.ref);
+ mail.content = dataSet[vc].message.content;
+ newInbox.mails[mail.ref] = mail;
+ messenger.addMark(mail.ref, "unread")
} else if (dataSet[vc].type === "CREATE_GROUP") {
//process create group
let groupInfo = JSON.parse(dataSet[vc].message);
@@ -11129,13 +11095,9 @@ Bitcoin.Util = {
getMail(mailRef) {
return new Promise((resolve, reject) => {
- compactIDB.readData("mailRef", mailRef).then(result => {
- let promises = [compactIDB.readData("mails", result), compactIDB.readData(
- "mailContent", result)]
- Promise.all(promises).then(results => {
- results[0].content = Crypto.AES.decrypt(results[1]);
- resolve(results[0]);
- }).catch(error => reject(error))
+ compactIDB.readData("mails", mailRef).then(mail => {
+ mail.content = this.util.decrypt(mail.content)
+ resolve(mail)
}).catch(error => reject(error))
});
},
@@ -11176,32 +11138,48 @@ Bitcoin.Util = {
return floDapps.storeContact(floID, name)
},
- loadDataFromIDB() {
+ loadDataFromIDB(dataList = 'default') {
return new Promise((resolve, reject) => {
- let loadData = ["messages", "mails", "marked", "groupMsg", "groupInfo", "appendix"]
+ if (dataList === 'default')
+ dataList = ["messages", "mails", "marked", "groupMsg", "groupInfo", "appendix"]
+ else if (dataList === 'all')
+ dataList = ["messages", "mails", "marked", "groupMsg", "groupInfo", "groupKey",
+ "appendix"
+ ]
let promises = []
- for (var i = 0; i < loadData.length; i++)
- promises[i] = compactIDB.readAllData(loadData[i])
+ for (var i = 0; i < dataList.length; i++)
+ promises[i] = compactIDB.readAllData(dataList[i])
Promise.all(promises).then(results => {
let data = {}
- for (var i = 0; i < loadData.length; i++)
- data[loadData[i]] = results[i]
+ for (var i = 0; i < dataList.length; i++)
+ data[dataList[i]] = results[i]
data.appendix.lastReceived = data.appendix.lastReceived || '0'
if (data.appendix.AESKey) {
try {
let AESKey = floCrypto.decryptData(data.appendix.AESKey, myPrivKey);
data.appendix.AESKey = AESKey;
- for (let m in data.messages) {
- let decrypted = Crypto.AES.decrypt(data.messages[m].message,
- AESKey)
- data.messages[m].message = decrypted;
- }
+ if ("messages" in dataList)
+ for (let m in data.messages)
+ data.messages[m].message = this.util.decrypt(data.messages[m]
+ .message, AESKey)
+ if ("mails" in dataList)
+ for (let m in data.mails)
+ data.mails[m].content = this.util.decrypt(data.mails[m].content,
+ AESKey)
+ if ("groupKey" in dataList)
+ for (let k in data.groupKeys)
+ data.groupKeys[k] = this.util.decrypt(data.groupKeys[k], AESKey)
+ if ("groupMsg" in dataList)
+ for (let m in data.groupMsg)
+ if (datdata.groupMsg[m].message)
+ data.groupMsg[m].message = this.util.decrypt(data.groupMsg[
+ m].message, AESKey)
resolve(data)
} catch (error) {
reject("Corrupted AES Key");
}
} else {
- if (Object.keys(data.messages).length)
+ if (Object.keys(data.messages).length || Object.keys(data.mails).length)
return reject("AES Key not Found")
let AESKey = floCrypto.randString(32);
let encryptedKey = floCrypto.encryptData(AESKey, myPubKey);
@@ -11216,24 +11194,16 @@ Bitcoin.Util = {
backupData() {
return new Promise((resolve, reject) => {
- let obs = ["contacts", "pubKeys", "messages", "mails", "mailContent", "mailRef", "marked",
- "appendix"
- ]
- let promises = [];
- obs.forEach(o => promises.push(compactIDB.readAllData(o)))
- Promise.all(promises).then(results => {
- let data = {}
- for (let i = 0; i < obs.length; i++)
- data[obs[i]] = results[i]
- results = undefined;
+ this.loadDataFromIDB("all").then(data => {
+ delete data.appendix.AESKey;
data = btoa(unescape(encodeURIComponent(JSON.stringify(data))))
- data = {
+ let blobData = {
floID: myFloID,
pubKey: myPubKey,
- data: floCrypto.encryptData(data, myPubKey),
+ data: this.util.encrypt(data, myPrivKey),
}
- data.sign = floCrypto.signData(JSON.stringify(data.data), myPrivKey);
- resolve(new Blob([JSON.stringify(data)], {
+ blobData.sign = floCrypto.signData(blobData.data, myPrivKey);
+ resolve(new Blob([JSON.stringify(blobData)], {
type: 'application/json'
}));
}).catch(error => reject(error))
@@ -11245,14 +11215,14 @@ Bitcoin.Util = {
if (blob instanceof Blob || blob instanceof File) {
let reader = new FileReader();
reader.onload = evt => {
- var data = JSON.parse(evt.target.result);
- if (!floCrypto.verifySign(JSON.stringify(data.data), data.sign, data.pubKey))
+ var blobData = JSON.parse(evt.target.result);
+ if (!floCrypto.verifySign(blobData.data, blobData.sign, blobData.pubKey))
reject("Corrupted Backup file: Signature verification failed");
- else if (myFloID !== data.floID || myPubKey !== data.pubKey)
+ else if (myFloID !== blobData.floID || myPubKey !== blobData.pubKey)
reject("Invalid Backup file: Incorrect floID");
else {
try {
- data = floCrypto.decryptData(data.data, myPrivKey);
+ let data = this.util.decrypt(blobData.data, myPrivKey)
try {
data = JSON.parse(decodeURIComponent(escape(atob(data))));
resolve(data)
@@ -11272,32 +11242,28 @@ Bitcoin.Util = {
restoreData(arg) {
return new Promise((resolve, reject) => {
- let parseData;
if (arg instanceof Blob || arg instanceof File)
- parseData = this.parseBackup
+ var parseData = this.parseBackup
else
- parseData = data => new Promise((res, rej) => res(data))
+ var parseData = data => new Promise((res, rej) => res(data))
parseData(arg).then(data => {
- if (data.appendix.lastReceived < floGlobals.appendix.lastReceived)
- data.appendix.lastReceived = floGlobals.appendix.lastReceived;
- let AESKey = floCrypto.decryptData(data.appendix.AESKey, myPrivKey);
- if (AESKey !== floGlobals.appendix.AESKey) {
- for (let m in data.messages) {
- let decrypted = this.util.decrypt(data.messages[m].message, AESKey)
- let encrypted = this.util.encrypt(decrypted)
- data.messages[m].message = encrypted;
- }
- for (let m in data.mailContent) {
- let decrypted = this.util.decrypt(data.mailContent[m], AESKey)
- let encrypted = this.util.encrypt(decrypted)
- data.mailContent[m] = encrypted;
- }
- }
- delete data.appendix.AESKey;
+ for (let m in data.messages)
+ data.messages[m].message = this.util.encrypt(data.messages[m].message)
+ for (let m in data.mail)
+ data.mails[m].content = this.util.encrypt(data.mails[m].content)
+ for (let k in data.groupKeys)
+ data.groupKeys[k] = this.util.encrypt(data.groupKeys[k])
+ for (let m in data.groupMsg)
+ if (datdata.groupMsg[m].message)
+ data.groupMsg[m].message = this.util.encrypt(data.groupMsg[m].message)
+ for (let l in data.appendix)
+ if (l.startsWith('lastReceived') && data.appendix[l] < floGlobals.appendix[
+ l])
+ data.appendix[l] = floGlobals.appendix[l]
let promises = [];
- for (obs in data)
- for (value in data[obs])
- promises.push(compactIDB.writeData(obs, data[obs][value], value));
+ for (let obs in data)
+ for (let k in data[obs])
+ promises.push(compactIDB.writeData(obs, data[obs][k], k));
Promise.all(promises)
.then(results => resolve("Restore Successful"))
.catch(error => reject("Restore Failed: Unable to write to IDB"))