Moved plugin web files to be in the plugin folder to reduce staticfiles blueprint coupling

This commit is contained in:
Kevin Froman 2020-09-01 22:41:59 +00:00
parent 14f2d03ebf
commit 37e5dbab4b
23 changed files with 37 additions and 40 deletions

View file

@ -0,0 +1,28 @@
/*
Onionr - Private P2P Communication
Settings modal closing
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/>.
*/
document.getElementById('closeSettingsModalButton').onclick = function(){
document.getElementById('settingsModal').classList.remove('is-active')
setActiveTab('inbox')
}
document.querySelector("#settingsModal .modal-background").onclick = function(){
document.getElementById('settingsModal').classList.remove('is-active')
setActiveTab('inbox')
}

View file

@ -0,0 +1,261 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>
Onionr Mail
</title>
<link rel="shortcut icon" type="image/ico" href="/shared/images/favicon.ico">
<link rel="stylesheet" href="/shared/fontawesome-free-5.10.2/css/all.min.css">
<link rel="stylesheet" href="/shared/main/PNotifyBrightTheme.css">
<link rel="stylesheet" href="/gettheme">
<link rel="stylesheet" href="/shared/node_modules/bulma-switch/dist/css/bulma-switch.min.css">
<link rel="stylesheet" href="/mail/mail.css">
<script defer src="/shared/node_modules/pnotify/dist/iife/PNotify.js"></script>
<script defer src="/shared/node_modules/pnotify/dist/iife/PNotifyButtons.js"></script>
<script defer src="/shared/main/apicheck.js"></script>
<script defer src="/shared/misc.js"></script>
<script defer src="/mail/sethumanreadable.js"></script>
<script defer src="/mail/loadsettings.js"></script>
<script defer src="/mail/mail.js"></script>
<script defer src="/mail/sendmail.js"></script>
<script defer src="/mail/closesettings.js"></script>
<script defer src="/mail/settings.js"></script>
<script defer src="/shared/navbar.js"></script>
</head>
<body>
<nav class="navbar is-dark" role="navigation" aria-label="main navigation">
<div class="navbar-brand">
<a class="navbar-item idLink" href="/">
<img src="/shared/images/favicon.ico" class="navbarLogo">
</a>
<a role="button" class="navbar-burger burger" aria-label="menu" aria-expanded="false"
data-target="navbarBasic">
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
</a>
</div>
<div id="navbarBasic" class="navbar-menu">
<div class="navbar-start">
<a class="navbar-item idLink" href="/mail/">Mail</a>
<a class="navbar-item idLink" href="/friends/">Friends</a>
<a class="navbar-item idLink" href="/board/">Circles</a>
</div>
</div>
</nav>
<!--Hero (Dark Section)-->
<section class="hero is-small is-dark">
<div class="hero-body">
<div class="container">
<div class="columns">
<div class="column">
<h1 class="title">
Mail
</h1>
<h2 class="subtitle">
Private and safe messages
</h2>
</div>
<div class="column is-7">
<div class="field">
<div class="field has-addons">
<p class="control">
<a class="button is-static">
<i class="fas fa-fingerprint"></i>
</a>
</p>
<p class="control is-expanded">
<input id="myPub" class="input myPub" type="text" readonly>
</p>
<p class="control">
<a id="myPubCopy" class="button is-primary"><i class="fas fa-copy"></i></a>
</p>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
<br>
<div id="messageDisplay" class="overlay">
<div class="overlayContent">
<span class="closeOverlay" overlay="messageDisplay"></span>
<div>
From: <input type="text" id="fromUser" readonly> Signature: <span id="sigValid"></span> <span
id="addUnknownContact"><button class="button is-primary">Add to Contacts</button></span>
</div>
<div class="break-up">
Subject: <span id="subjectView"></span>
</div>
<div>
<button id="replyBtn" class="button is-primary break-up">Reply</button>
</div>
<div id="signatureValidity"></div>
<div id="threadDisplay" class="pre messageContent">
</div>
</div>
</div>
<div id="sentboxDisplay" class="overlay">
<div class="overlayContent">
<span class="closeOverlay" overlay="sentboxDisplay"></span>
To: <input id="toID" readonly type="text">
<div id="sentboxDisplayText" class="pre messageContent">
</div>
</div>
</div>
<div id="settingsModal" class="modal">
<div class="modal-background"></div>
<div class="modal-card">
<header class="modal-card-head">
<button id="closeSettingsModalButton" class="closeSettingsModal delete" aria-label="close"></button>
</header>
<section class="modal-card-body">
<div class="columns">
<div class="column">
<div>Ask senders to use forward-secrecy</div>
<small>Turn off if using 1 ID on more than 1 device, or have Onionr data erasure on exit enabled.</small>
</div>
<div class="column is-2">
<div class="field">
<input id="forwardSecrecySetting" type="checkbox"
class="switch is-rounded is-danger" checked>
<label for="forwardSecrecySetting"></label>
</div>
</div>
</div>
<div class="columns">
<div class="column">
<div>Message padding</div>
<small>Improves privacy slightly for a small performance hit.</small>
</div>
<div class="column is-2">
<div class="field">
<input id="messagePaddingSetting" type="checkbox"
class="switch is-rounded is-warning">
<label for="messagePaddingSetting"></label>
</div>
</div>
</div>
<div class="columns">
<div class="column">
Inbox notifications
</div>
<div class="column is-2">
<div class="field">
<input id="notificationSetting" type="checkbox"
class="switch is-rounded" checked>
<label for="notificationSetting"></label>
</div>
</div>
</div>
<div class="columns notificationSetting">
<div class="column">
Notifications for stranger's messages
</div>
<div class="column is-2">
<div class="field">
<input id="strangersNotification" type="checkbox"
class="switch is-rounded" checked>
<label for="strangersNotification"></label>
</div>
</div>
</div>
<div class="columns notificationSetting">
<div class="column">
Notification sound
</div>
<div class="column is-2">
<div class="field">
<input id="notificationSound" type="checkbox"
class="switch is-rounded" checked>
<label for="notificationSound"></label>
</div>
</div>
</div>
Signature
<textarea id="mailSignatureSetting" class="textarea" placeholder="Signature to add to every message" rows="5"></textarea>
</section>
</div>
</div>
<!--Start of content-->
<div class="container">
<div class="tabs" id="tabBtns">
<ul>
<li class="is-active">
<a>
<span class="icon">
<i class="fa fa-envelope"></i>
</span>
<span id="inboxTab">Inbox</span>
</a>
</li>
<li>
<a>
<span class="icon">
<i class="fa fa-paper-plane"></i>
</span>
<span>Sent</span>
</a>
</li>
<li>
<a>
<span class="icon">
<i class="fa fa-pen"></i>
</span>
<span>Compose</span>
</a>
</li>
<li>
<a>
<span class="icon">
<i class="fa fa-cog"></i>
</span>
<span>Settings</span>
</a>
</li>
</ul>
</div>
<div class="content" id="noInbox">No messages to show ¯\_(ツ)_/¯</div>
<div class="content">
<div class="mailPing">
API server either shutdown, has disabled mail, or has experienced a bug.
</div>
<div id="threads" class="threads">
<div id="threadPlaceholder">Nothing here yet 😞</div>
</div>
</div>
</div>
<div id="sendMessage">
<div class="container">
<div class="field">
<label><i class="fas fa-user"></i> Select friend: <select id="friendSelect"></select></label>
</div>
<form method="post" action="" id="sendForm" enctype="application/x-www-form-urlencoded">
<div class="field">
To: <input id="draftID" type="text" name="to" placeholder="pubkey or select above" required>
</div>
Subject: <input name="subject" id="draftSubject" maxlength="25" type="text"
placeholder="message subject">
<div class="field">
<textarea name="message" class="textarea" placeholder="type your message..." id="draftText" required></textarea>
</div>
<input type="submit" value="Send" class="button is-primary successBtn">
</form>
</div>
</div>
<div id="infoOverlay" class="overlay">
</div>
</body>
</html>

View file

@ -0,0 +1,29 @@
mailSettings = {}
fetch('/config/get/mail', {
headers: {
"content-type": "application/json",
"token": webpass
}})
.then((resp) => resp.json())
.then(function(settings) {
mailSettings = settings || {}
if (mailSettings.default_forward_secrecy === false){
document.getElementById('forwardSecrecySetting').checked = false
}
if (mailSettings.use_padding === false){
document.getElementById('messagePaddingSetting').checked = false
}
if (mailSettings.notificationSetting === false){
document.getElementById('notificationSetting').checked = false
}
if (mailSettings.notificationSound === false){
document.getElementById('notificationSound').checked = false
}
if (typeof mailSettings.signature != undefined && mailSettings.signature != null && mailSettings.signature != ""){
document.getElementById('mailSignatureSetting').value = mailSettings.signature
}
if (mailSettings.strangersNotification == false){
document.getElementById('strangersNotification').checked = false
}
})

View file

@ -0,0 +1,60 @@
.threadEntry button{
margin-right: 1%;
}
.threadEntry span, .sentboxList span{
padding-left: 1%;
}
.threadEntry, .sentboxList{
cursor: pointer;
}
.overlayContent{
background-color: lightgray;
border: 3px solid black;
border-radius: 3px;
color: black;
font-family: Verdana, Geneva, Tahoma, sans-serif;
min-height: 100%;
padding: 1em;
margin: 1em;
}
#draftText{
margin-top: 1em;
margin-bottom: 1em;
display: block;
width: 50%;
height: 75%;
min-width: 2%;
min-height: 5%;
background: white;
color: black;
}
.sentboxList{
padding-top: 1em;
}
.messageContent{
padding-top: 1em;
}
#tabBtns ul .icon {
pointer-events: none;
}
#settingsModal .modal-card-body{
font-size: 150%;
min-height: 300px;
}
#settingsModal textarea{
resize: none;
margin-top: 1em;
}
#settingsModal small{
font-size: 0.5em;
}

View file

@ -0,0 +1,450 @@
/*
Onionr - Private P2P Communication
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 = ''
sentbox = ''
threadPart = document.getElementById('threads')
threadPlaceholder = document.getElementById('threadPlaceholder')
tabBtns = document.getElementById('tabBtns')
threadContent = {}
replyBtn = document.getElementById('replyBtn')
addUnknownContact = document.getElementById('addUnknownContact')
noInbox = document.getElementById('noInbox')
humanReadableCache = {}
function stripEndZeroes(str){
str = str.split("")
let zeroCount = 0
for (x = str.length - 1; x != 0; x--){
if (str[x] == "0"){
zeroCount += 1
}
else{
break
}
}
str.splice(str.length - zeroCount, zeroCount)
str = str.join("")
return str
}
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})
}
})
}
function openReply(bHash, quote, subject){
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
}
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]
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')
}
function openThread(bHash, sender, date, sigBool, pubkey, subjectLine){
addUnknownContact.style.display = 'none'
var messageDisplay = document.getElementById('threadDisplay')
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 || ''
document.getElementById('subjectView').innerText = subjectLine
resp = stripEndZeroes(resp)
messageDisplay.innerText = resp
var sigEl = document.getElementById('sigValid')
var sigMsg = 'signature'
// show add unknown contact button if peer is unknown
if (sender !== myPub && sigBool){
addUnknownContact.style.display = 'inline'
}
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(){
document.getElementById('messageDisplay').style.visibility = 'hidden'
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)
}
})
}
function setActiveTab(tabName){
threadPart.innerHTML = ""
noInbox.style.display = 'none'
window.inboxActive = false
document.getElementById('sendMessage').classList.add('is-hidden')
switch(tabName){
case 'inbox':
window.inboxActive = true
refreshPms()
getInbox()
break
case 'sent':
getSentbox()
break
case 'compose':
document.getElementById('sendMessage').classList.remove('is-hidden')
break
case 'settings':
document.getElementById('settingsModal').classList.add('is-active')
break
}
}
function deleteMessage(bHash){
fetch('/mail/deletemsg/' + bHash, {
"method": "post",
headers: {
"token": webpass
}})
}
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';
}
}
})
}
function loadInboxEntries(bHash){
fetch('/getblockheader/' + bHash, {
headers: {
"token": webpass
}})
.then((resp) => resp.json()) // Transform the data into json
.then(function(resp) {
//console.log(resp)
var entry = document.createElement('div')
var bHashDisplay = document.createElement('span')
//var senderInput = document.createElement('input')
var senderInput = document.createElement('span')
var subjectLine = document.createElement('span')
var dateStr = document.createElement('span')
var validSig = document.createElement('span')
var deleteBtn = document.createElement('button')
var humanDate = new Date(0)
var metadata = resp['metadata']
humanDate.setUTCSeconds(resp['meta']['time'])
humanDate = humanDate.toString()
validSig.style.display = 'none'
if (typeof resp['meta']['signer'] != 'undefined' && resp['meta']['signer'] != ''){
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{
resp2.text().then(function(resp2){
loadHumanReadableToCache(resp['meta']['signer'])
senderInput.innerText = resp2
entry.setAttribute('data-nameSet', true)
})
}
})
}
else{
senderInput.innerText = 'Anonymous'
entry.setAttribute('data-nameSet', false)
}
if (! resp['meta']['validSig']){
validSig.style.display = 'inline'
validSig.innerText = 'Signature Validity: Bad'
validSig.style.color = 'red'
}
//bHashDisplay.innerText = bHash.substring(0, 10)
entry.setAttribute('data-hash', bHash)
entry.setAttribute('data-pubkey', resp['meta']['signer'])
senderInput.readOnly = true
dateStr.innerText = humanDate.substring(0, humanDate.indexOf('('))
deleteBtn.classList.add('delete', 'deleteBtn')
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)
entry.appendChild(deleteBtn)
entry.appendChild(bHashDisplay)
entry.appendChild(senderInput)
entry.appendChild(subjectLine)
entry.appendChild(dateStr)
entry.appendChild(validSig)
entry.classList.add('threadEntry')
entry.onclick = function(event){
if (event.target.classList.contains('deleteBtn')){
return
}
openThread(entry.getAttribute('data-hash'), senderInput.innerText, dateStr.innerText, resp['meta']['validSig'], entry.getAttribute('data-pubkey'), subjectLine.innerText)
}
deleteBtn.onclick = function(){
entry.parentNode.removeChild(entry);
deleteMessage(entry.getAttribute('data-hash'))
}
}.bind(bHash))
}
function getInbox(){
if (! window.inboxActive){
return
}
var els = document.getElementsByClassName('threadEntry')
var showed = false
for(var i = 0; i < pms.length; i++) {
var add = true
if (pms[i].trim().length == 0){
noInbox.style.display = 'block'
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])
}
}
if (! showed){
threadPlaceholder.style.display = 'block'
}
}
function getSentbox(){
fetch('/mail/getsentbox', {
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);
if (keys.length == 0){
threadPart.innerHTML = "nothing to show here yet."
}
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: '
var toEl = document.createElement('span')
toEl.classList.add('toElement')
var sentDate = document.createElement('span')
var humanDate = new Date(0)
humanDate.setUTCSeconds(resp[i]['date'])
humanDate = humanDate.toString()
var preview = document.createElement('span')
var deleteBtn = document.createElement('button')
var message = resp[i]['message']
deleteBtn.classList.add('deleteBtn', 'delete')
sentDate.innerText = humanDate.substring(0, humanDate.indexOf('('))
if (resp[i]['name'] == null || resp[i]['name'].toLowerCase() == 'anonymous'){
toEl.innerText = resp[i]['peer']
setHumanReadableValue(toEl, resp[i]['peer'])
}
else{
toEl.innerText = resp[i]['name']
}
preview.innerText = '(' + resp[i]['subject'] + ')'
entry.classList.add('sentboxList')
entry.setAttribute('data-hash', resp[i]['hash'])
entry.appendChild(deleteBtn)
entry.appendChild(toLabel)
entry.appendChild(toEl)
entry.appendChild(preview)
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
}
showSentboxWindow(toEl.innerText, message)
}
})(i, resp)
threadPart.appendChild(entry)
}.bind(threadPart))
}
function showSentboxWindow(to, content){
content = stripEndZeroes(content)
document.getElementById('toID').value = to
document.getElementById('sentboxDisplayText').innerText = content
overlay('sentboxDisplay')
}
function refreshPms(callNext){
if (! window.inboxActive){
return
}
fetch('/mail/getinbox', {
headers: {
"token": webpass
}})
.then((resp) => resp.text())
.then(function(data) {
pms = data.split(',')
if (pms.length > 0){
noInbox.style.display = 'none'
}
if (callNext){
getInbox()
}
})
}
tabBtns.onclick = function(event){
var children = tabBtns.children[0].children
for (var i = 0; i < children.length; i++) {
var btn = children[i]
btn.classList.remove('is-active')
}
event.target.parentElement.parentElement.classList.add('is-active')
setActiveTab(event.target.innerText.toLowerCase())
}
for (var i = 0; i < document.getElementsByClassName('refresh').length; i++){
document.getElementsByClassName('refresh')[i].style.float = 'right'
}
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 = [];
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)
}
})
setActiveTab('inbox')
setInterval(function(){mailPing()}, 10000)
mailPing()
window.inboxInterval = setInterval(function(){refreshPms(true)}, 3000)
refreshPms(true)
document.addEventListener("visibilitychange", function() {
if (document.visibilityState === 'visible') {
refreshPms()
}
})

View file

@ -0,0 +1,95 @@
/*
Onionr - Private P2P Communication
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/>.
*/
var sendbutton = document.getElementById('sendMail')
messageContent = document.getElementById('draftText')
to = document.getElementById('draftID')
subject = document.getElementById('draftSubject')
friendPicker = document.getElementById('friendSelect')
function utf8Length(s) {
var size = encodeURIComponent(s).match(/%[89ABab]/g);
return s.length + (size ? size.length : 0);
}
function padString(string_data, round_nearest_byte_exponent = 3){
if (utf8Length(string_data) === 0){
string_data += '0'
}
let round_size = 10 ** round_nearest_byte_exponent
while (utf8Length(string_data) % round_size > 0){
string_data += '0'
}
return string_data
}
function sendMail(toData, message, subject){
let meta = {'subject': subject}
if (document.getElementById('messagePaddingSetting').checked){
message = padString(message)
}
if (document.getElementById('mailSignatureSetting').value !== false){
message += "\n"
message += document.getElementById('mailSignatureSetting').value
}
postData = {'message': message, 'to': toData, 'type': 'pm', 'encrypt': true, 'meta': JSON.stringify(meta)}
postData.forward = document.getElementById('forwardSecrecySetting').checked
postData = JSON.stringify(postData)
sendForm.style.display = 'none'
fetch('/insertblock', {
method: 'POST',
body: postData,
headers: {
"content-type": "application/json",
"token": webpass
}})
.then((resp) => resp.text()) // Transform the data into text
.then(function(data) {
sendForm.style.display = 'block'
PNotify.success({
text: 'Queued for sending!',
delay: 3500,
mouseReset: false
})
to.value = subject.value = messageContent.value = ""
friendPicker.value = ""
subject.value = ""
})
}
var friendPicker = document.getElementById('friendSelect')
friendPicker.onchange = function(){
to.value = friendPicker.value
}
sendForm.onsubmit = function(){
if (! to.value.includes("-") && to.value.length !== 56 && to.value.length !== 52){
PNotify.error({
text: 'User ID is not valid'
})
}
else{
sendMail(to.value, messageContent.value, subject.value)
}
return false
}

View file

@ -0,0 +1,40 @@
/*
Onionr - Private P2P Communication
Load human readable public keys into a cache
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/>.
*/
function loadHumanReadableToCache(key){
fetch('/getHumanReadable/' + key, {
headers: {
"token": webpass
}})
.then((resp) => resp.text())
.then(function(resp) {
humanReadableCache[key] = resp
})
}
function setHumanReadableValue(el, key){
if (typeof humanReadableCache[key] != 'undefined'){
el.innerText = humanReadableCache[key].split('-').slice(0,3).join('-')
return
}
else{
loadHumanReadableToCache(key)
setTimeout(function(){setHumanReadableValue(el, key)}, 100)
return
}
}

View file

@ -0,0 +1,120 @@
/*
Onionr - Private P2P Communication
Handle mail settings
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/>.
*/
var notificationSetting = document.getElementById('notificationSetting')
var friendOnlyNotification = document.getElementById('strangersNotification')
var notificationSound = document.getElementById('notificationSound')
var sigSetting = document.getElementById('mailSignatureSetting')
document.getElementById('forwardSecrecySetting').onchange = function(e){
postData = JSON.stringify({"default_forward_secrecy": e.target.checked})
fetch('/config/set/mail', {
method: 'POST',
body: postData,
headers: {
"content-type": "application/json",
"token": webpass
}})
.then((resp) => resp.text())
.then(function(data) {
mailSettings['forwardSecrecy'] = document.getElementById('forwardSecrecySetting').checked
PNotify.success({
text: 'Successfully toggled default forward secrecy'
})
})
}
notificationSound.onchange = function(e){
var postData = JSON.stringify({"notificationSound": e.target.checked})
fetch('/config/set/mail', {
method: 'POST',
body: postData,
headers: {
"content-type": "application/json",
"token": webpass
}})
.then(function(data) {
mailSettings['notificationSound'] = notificationSound.checked
PNotify.success({
text: 'Successfully notification sound'
})
})
}
friendOnlyNotification.onchange = function(e){
var postData = JSON.stringify({"strangersNotification": e.target.checked})
fetch('/config/set/mail', {
method: 'POST',
body: postData,
headers: {
"content-type": "application/json",
"token": webpass
}})
.then(function(data) {
mailSettings['strangersNotification'] = friendOnlyNotification.checked
PNotify.success({
text: 'Successfully toggled notifications from strangers'
})
})
}
notificationSetting.onchange = function(e){
var notificationSettings = document.getElementsByClassName('notificationSetting')
if (e.target.checked){
for (i = 0; i < notificationSettings.length; i++){
notificationSettings[i].style.display = "flex"
}
}
else{
for (i = 0; i < notificationSettings.length; i++){
notificationSettings[i].style.display = "none"
}
}
var postData = JSON.stringify({"notificationSetting": e.target.checked})
fetch('/config/set/mail', {
method: 'POST',
body: postData,
headers: {
"content-type": "application/json",
"token": webpass
}})
.then(function(data) {
mailSettings['notificationSetting'] = notificationSetting.checked
PNotify.success({
text: 'Successfully toggled default mail notifications'
})
})
}
sigSetting.onchange = function(){
var postData = JSON.stringify({"signature": sigSetting.value})
fetch('/config/set/mail', {
method: 'POST',
body: postData,
headers: {
"content-type": "application/json",
"token": webpass
}})
.then(function(data) {
mailSettings['signature'] = sigSetting.value
PNotify.success({
text: 'Set mail signature'
})
})
}