onionr/static-data/www/mail/mail.js

422 lines
14 KiB
JavaScript
Raw Normal View History

2019-02-04 00:31:03 +00:00
/*
Onionr - Private P2P Communication
2019-02-04 00:31:03 +00:00
This file handles the mail interface
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
pms = ''
2019-02-08 18:53:28 +00:00
sentbox = ''
threadPart = document.getElementById('threads')
2019-02-03 18:19:50 +00:00
threadPlaceholder = document.getElementById('threadPlaceholder')
2019-02-04 00:31:03 +00:00
tabBtns = document.getElementById('tabBtns')
2019-02-04 23:48:21 +00:00
threadContent = {}
2019-02-28 03:02:44 +00:00
replyBtn = document.getElementById('replyBtn')
addUnknownContact = document.getElementById('addUnknownContact')
noInbox = document.getElementById('noInbox')
humanReadableCache = {}
2019-09-10 18:43:40 +00:00
async function addContact(pubkey, friendName){
fetch('/friends/add/' + pubkey, {
method: 'POST',
headers: {
"token": webpass
}}).then(function(data) {
if (friendName.trim().length > 0){
post_to_url('/friends/setinfo/' + pubkey + '/name', {'data': friendName, 'token': webpass})
}
})
}
2019-02-28 03:02:44 +00:00
function openReply(bHash, quote, subject){
2019-02-28 03:02:44 +00:00
var inbox = document.getElementsByClassName('threadEntry')
var entry = ''
var friendName = ''
var key = ''
for(var i = 0; i < inbox.length; i++) {
if (inbox[i].getAttribute('data-hash') === bHash){
entry = inbox[i]
}
}
if (entry.getAttribute('data-nameset') == 'true'){
document.getElementById('friendSelect').value = document.getElementById('fromUser').value
2019-02-28 03:02:44 +00:00
}
key = entry.getAttribute('data-pubkey')
document.getElementById('draftID').value = key
document.getElementById('draftSubject').value = 'RE: ' + subject
// Add quoted reply
var splitQuotes = quote.split('\n')
for (var x = 0; x < splitQuotes.length; x++){
splitQuotes[x] = '> ' + splitQuotes[x]
}
if (typeof humanReadableCache[key] != 'undefined'){
document.getElementById('draftID').value = humanReadableCache[key]
2019-09-29 21:32:46 +00:00
quote = '\n' + humanReadableCache[key].split('-').slice(0,3).join('-') + ' wrote:\n' + splitQuotes.join('\n')
}
else{
quote = '\n' + key.substring(0, 12) + ' wrote:' + '\n' + splitQuotes.join('\n')
}
document.getElementById('draftText').value = quote
setActiveTab('compose')
2019-02-28 03:02:44 +00:00
}
2019-02-04 00:31:03 +00:00
function openThread(bHash, sender, date, sigBool, pubkey, subjectLine){
addUnknownContact.style.display = 'none'
2019-02-04 23:48:21 +00:00
var messageDisplay = document.getElementById('threadDisplay')
2019-09-10 16:55:44 +00:00
fetch('/getblockbody/' + bHash, {
"method": "get",
headers: {
"token": webpass
}})
.then((resp) => resp.text())
.then(function(resp) {
document.getElementById('fromUser').value = sender || 'Anonymous'
document.getElementById('fromUser').value = pubkey || ''
2019-09-10 16:55:44 +00:00
document.getElementById('subjectView').innerText = subjectLine
messageDisplay.innerText = resp
var sigEl = document.getElementById('sigValid')
var sigMsg = 'signature'
// show add unknown contact button if peer is unknown
if (sender !== myPub && sigBool){
2019-09-10 16:55:44 +00:00
addUnknownContact.style.display = 'inline'
}
2019-09-10 16:55:44 +00:00
if (sigBool){
sigMsg = 'Good ' + sigMsg
sigEl.classList.remove('danger')
}
else{
sigMsg = 'Bad/no ' + sigMsg + ' (message could be impersonating someone)'
sigEl.classList.add('danger')
replyBtn.style.display = 'none'
}
sigEl.innerText = sigMsg
overlay('messageDisplay')
replyBtn.onclick = function(){
openReply(bHash, messageDisplay.innerText, subjectLine)
}
addUnknownContact.onclick = function(){
var friendName = prompt("Enter an alias for this contact:")
if (friendName === null || friendName.length == 0){
return
}
addContact(pubkey, friendName)
}
})
2019-02-04 23:48:21 +00:00
}
2019-02-04 00:31:03 +00:00
function setActiveTab(tabName){
threadPart.innerHTML = ""
noInbox.style.display = 'none'
window.inboxActive = false
2019-02-04 00:31:03 +00:00
switch(tabName){
case 'inbox':
window.inboxActive = true
2019-03-03 06:26:55 +00:00
refreshPms()
getInbox()
2019-02-04 00:31:03 +00:00
break
case 'sent':
2019-02-08 18:53:28 +00:00
getSentbox()
2019-02-04 00:31:03 +00:00
break
case 'compose':
overlay('sendMessage')
document.getElementById('inboxTab').click()
2019-02-04 00:31:03 +00:00
break
}
}
2019-03-03 06:26:55 +00:00
function deleteMessage(bHash){
fetch('/mail/deletemsg/' + bHash, {
"method": "post",
headers: {
"token": webpass
}})
}
2019-03-11 05:10:37 +00:00
function mailPing(){
fetch('/mail/ping', {
"method": "get",
headers: {
"token": webpass
}})
.then(function(resp) {
var pings = document.getElementsByClassName('mailPing')
if (resp.ok){
for (var i=0; i < pings.length; i++){
pings[i].style.display = 'none';
}
}
else{
for (var i=0; i < pings.length; i++){
pings[i].style.display = 'block';
}
}
})
}
2019-02-28 03:02:44 +00:00
function loadInboxEntries(bHash){
2019-02-04 23:48:21 +00:00
fetch('/getblockheader/' + bHash, {
headers: {
"token": webpass
}})
.then((resp) => resp.json()) // Transform the data into json
.then(function(resp) {
//console.log(resp)
2019-02-04 23:48:21 +00:00
var entry = document.createElement('div')
var bHashDisplay = document.createElement('span')
2019-10-14 11:02:51 +00:00
//var senderInput = document.createElement('input')
var senderInput = document.createElement('span')
2019-02-04 23:48:21 +00:00
var subjectLine = document.createElement('span')
var dateStr = document.createElement('span')
var validSig = document.createElement('span')
2019-03-03 06:26:55 +00:00
var deleteBtn = document.createElement('button')
2019-02-04 23:48:21 +00:00
var humanDate = new Date(0)
var metadata = resp['metadata']
humanDate.setUTCSeconds(resp['meta']['time'])
humanDate = humanDate.toString()
2019-03-04 19:03:35 +00:00
validSig.style.display = 'none'
2019-09-10 16:55:44 +00:00
2019-09-09 08:23:09 +00:00
if (typeof resp['meta']['signer'] != 'undefined' && resp['meta']['signer'] != ''){
2019-09-10 16:55:44 +00:00
fetch('/friends/getinfo/' + resp['meta']['signer'] + '/name', {
headers: {
"token": webpass
}})
.then(function(resp2){
if (!resp2.ok){
setHumanReadableValue(senderInput, resp['meta']['signer'])
entry.setAttribute('data-nameSet', false)
}
else{
2019-09-22 19:22:35 +00:00
resp2.text().then(function(resp2){
2019-09-10 16:55:44 +00:00
loadHumanReadableToCache(resp['meta']['signer'])
2019-10-14 11:02:51 +00:00
senderInput.innerText = resp2
2019-09-10 16:55:44 +00:00
entry.setAttribute('data-nameSet', true)
2019-09-22 19:22:35 +00:00
})
2019-09-10 16:55:44 +00:00
}
})
2019-09-09 08:23:09 +00:00
}
else{
2019-10-14 11:02:51 +00:00
senderInput.innerText = 'Anonymous'
2019-09-09 08:23:09 +00:00
entry.setAttribute('data-nameSet', false)
}
2019-03-04 19:03:35 +00:00
if (! resp['meta']['validSig']){
validSig.style.display = 'inline'
validSig.innerText = 'Signature Validity: Bad'
validSig.style.color = 'red'
}
//bHashDisplay.innerText = bHash.substring(0, 10)
2019-02-28 03:02:44 +00:00
entry.setAttribute('data-hash', bHash)
entry.setAttribute('data-pubkey', resp['meta']['signer'])
2019-02-04 23:48:21 +00:00
senderInput.readOnly = true
dateStr.innerText = humanDate.substring(0, humanDate.indexOf('('))
2019-07-10 03:17:56 +00:00
deleteBtn.classList.add('delete', 'deleteBtn')
2019-02-04 23:48:21 +00:00
if (metadata['subject'] === undefined || metadata['subject'] === null) {
subjectLine.innerText = '()'
}
else{
subjectLine.innerText = '(' + metadata['subject'] + ')'
}
//entry.innerHTML = 'sender ' + resp['meta']['signer'] + ' - ' + resp['meta']['time']
threadPart.appendChild(entry)
2019-03-03 06:26:55 +00:00
entry.appendChild(deleteBtn)
2019-02-04 23:48:21 +00:00
entry.appendChild(bHashDisplay)
entry.appendChild(senderInput)
entry.appendChild(subjectLine)
entry.appendChild(dateStr)
2019-03-04 19:03:35 +00:00
entry.appendChild(validSig)
2019-02-04 23:48:21 +00:00
entry.classList.add('threadEntry')
2019-03-03 06:26:55 +00:00
entry.onclick = function(event){
if (event.target.classList.contains('deleteBtn')){
return
}
2019-10-14 11:02:51 +00:00
openThread(entry.getAttribute('data-hash'), senderInput.innerText, dateStr.innerText, resp['meta']['validSig'], entry.getAttribute('data-pubkey'), subjectLine.innerText)
2019-02-04 23:48:21 +00:00
}
2019-03-03 06:26:55 +00:00
deleteBtn.onclick = function(){
entry.parentNode.removeChild(entry);
deleteMessage(entry.getAttribute('data-hash'))
}
2019-02-04 23:48:21 +00:00
}.bind(bHash))
}
function getInbox(){
if (! window.inboxActive){
return
}
var els = document.getElementsByClassName('threadEntry')
2019-02-03 18:19:50 +00:00
var showed = false
2019-02-04 23:48:21 +00:00
var requested = ''
for(var i = 0; i < pms.length; i++) {
var add = true
2019-02-03 18:19:50 +00:00
if (pms[i].trim().length == 0){
noInbox.style.display = 'block'
2019-02-03 18:19:50 +00:00
continue
}
else{
threadPlaceholder.style.display = 'none'
showed = true
}
for (var x = 0; x < els.length; x++){
if (pms[i] === els[x].getAttribute('data-hash')){
add = false
}
}
if (add && window.inboxActive) {
loadInboxEntries(pms[i])
}
}
2019-02-03 18:19:50 +00:00
if (! showed){
threadPlaceholder.style.display = 'block'
}
2019-02-08 18:53:28 +00:00
}
2019-02-08 18:53:28 +00:00
function getSentbox(){
2019-03-03 06:26:55 +00:00
fetch('/mail/getsentbox', {
2019-02-08 18:53:28 +00:00
headers: {
"token": webpass
}})
.then((resp) => resp.json()) // Transform the data into json
.then(function(resp) {
var keys = [];
var entry = document.createElement('div')
for(var k in resp) keys.push(k);
2019-02-28 03:02:44 +00:00
if (keys.length == 0){
threadPart.innerHTML = "nothing to show here yet."
}
2019-09-09 23:21:05 +00:00
for (var i = keys.length - 1; i > -1; i--) (function(i, resp){
var entry = document.createElement('div')
var toLabel = document.createElement('span')
toLabel.innerText = 'To: '
2019-10-14 11:02:51 +00:00
var toEl = document.createElement('span')
toEl.classList.add('toElement')
2019-03-11 05:10:37 +00:00
var sentDate = document.createElement('span')
var humanDate = new Date(0)
humanDate.setUTCSeconds(resp[i]['date'])
humanDate = humanDate.toString()
var preview = document.createElement('span')
2019-03-03 06:26:55 +00:00
var deleteBtn = document.createElement('button')
2019-03-05 03:16:33 +00:00
var message = resp[i]['message']
2019-07-10 03:17:56 +00:00
deleteBtn.classList.add('deleteBtn', 'delete')
2019-10-14 11:02:51 +00:00
sentDate.innerText = humanDate.substring(0, humanDate.indexOf('('))
if (resp[i]['name'] == null || resp[i]['name'].toLowerCase() == 'anonymous'){
2019-10-14 11:02:51 +00:00
toEl.innerText = resp[i]['peer']
setHumanReadableValue(toEl, resp[i]['peer'])
2019-03-05 03:16:33 +00:00
}
else{
2019-10-14 11:02:51 +00:00
toEl.innerText = resp[i]['name']
2019-03-05 03:16:33 +00:00
}
2019-03-03 06:26:55 +00:00
preview.innerText = '(' + resp[i]['subject'] + ')'
2019-07-10 03:17:56 +00:00
entry.classList.add('sentboxList')
2019-03-03 06:26:55 +00:00
entry.setAttribute('data-hash', resp[i]['hash'])
entry.appendChild(deleteBtn)
entry.appendChild(toLabel)
entry.appendChild(toEl)
entry.appendChild(preview)
2019-03-11 05:10:37 +00:00
entry.appendChild(sentDate)
threadPart.appendChild(entry)
entry.onclick = function(e){
if (e.target.classList.contains('deleteBtn')){
deleteMessage(e.target.parentNode.getAttribute('data-hash'))
e.target.parentNode.parentNode.removeChild(e.target.parentNode)
return
2019-03-03 06:26:55 +00:00
}
2019-10-14 11:02:51 +00:00
showSentboxWindow(toEl.innerText, message)
}
})(i, resp)
threadPart.appendChild(entry)
}.bind(threadPart))
}
function showSentboxWindow(to, content){
document.getElementById('toID').value = to
document.getElementById('sentboxDisplayText').innerText = content
overlay('sentboxDisplay')
}
function refreshPms(callNext){
if (! window.inboxActive){
return
}
2019-03-02 19:17:18 +00:00
fetch('/mail/getinbox', {
headers: {
"token": webpass
}})
2019-09-10 16:55:44 +00:00
.then((resp) => resp.text())
.then(function(data) {
2019-08-29 06:49:41 +00:00
pms = data.split(',').reverse()
if (pms.length > 0){
noInbox.style.display = 'none'
}
if (callNext){
getInbox()
}
})
2019-03-03 06:26:55 +00:00
}
2019-02-04 00:31:03 +00:00
tabBtns.onclick = function(event){
var children = tabBtns.children[0].children
2019-02-04 00:31:03 +00:00
for (var i = 0; i < children.length; i++) {
var btn = children[i]
btn.classList.remove('is-active')
2019-02-04 00:31:03 +00:00
}
event.target.parentElement.parentElement.classList.add('is-active')
2019-02-04 00:31:03 +00:00
setActiveTab(event.target.innerText.toLowerCase())
}
for (var i = 0; i < document.getElementsByClassName('refresh').length; i++){
document.getElementsByClassName('refresh')[i].style.float = 'right'
2019-02-05 06:29:06 +00:00
}
fetch('/friends/list', {
headers: {
"token": webpass
}})
.then((resp) => resp.json()) // Transform the data into json
.then(function(resp) {
var friendSelectParent = document.getElementById('friendSelect')
var keys = [];
var friend
for(var k in resp) keys.push(k);
friendSelectParent.appendChild(document.createElement('option'))
for (var i = 0; i < keys.length; i++) {
var option = document.createElement("option")
var name = resp[keys[i]]['name'] || ""
option.value = keys[i]
if (name.length == 0){
option.text = keys[i]
}
else{
option.text = name
}
friendSelectParent.appendChild(option)
}
2019-03-03 06:26:55 +00:00
})
2019-03-11 05:10:37 +00:00
setActiveTab('inbox')
setInterval(function(){mailPing()}, 10000)
mailPing()
window.inboxInterval = setInterval(function(){refreshPms(true)}, 3000)
refreshPms(true)