fixes for mail, work on specs, and added files for profile viewer
This commit is contained in:
parent
ad94c8a4ef
commit
45ddbe5e69
@ -27,6 +27,8 @@ Users are identified by ed25519 public keys, which can be used to sign blocks or
|
||||
|
||||
Onionr can be used for mail, as a social network, instant messenger, file sharing software, or for encrypted group discussion.
|
||||
|
||||
The whitepaper (subject to change prior to first alpha release) is available [here](docs/whitepaper.md).
|
||||
|
||||
![Tor stinks slide image](docs/tor-stinks-02.png)
|
||||
|
||||
## Main Features
|
||||
|
@ -6,8 +6,7 @@ Onionr 'Blocks' are the primary means of sharing information in Onionr. Blocks a
|
||||
|
||||
They contain a JSON metadata section followed by a line break, with the main data following.
|
||||
|
||||
In the future, the spec will be updated to use flags and MessagePack instead of JSON with english keys.
|
||||
|
||||
In the future, the specification will likely be updated to use flags and MessagePack instead of JSON with english keys.
|
||||
|
||||
# Encryption and Signatures
|
||||
|
@ -26,7 +26,7 @@ import core
|
||||
from onionrblockapi import Block
|
||||
import onionrutils, onionrexceptions, onionrcrypto, blockimporter, onionrevents as events, logger, config
|
||||
import httpapi
|
||||
from httpapi import friendsapi, simplecache
|
||||
from httpapi import friendsapi, simplecache, profilesapi
|
||||
from onionrservices import httpheaders
|
||||
import onionr
|
||||
|
||||
@ -256,7 +256,8 @@ class API:
|
||||
self.bindPort = bindPort
|
||||
|
||||
# Be extremely mindful of this. These are endpoints available without a password
|
||||
self.whitelistEndpoints = ('site', 'www', 'onionrhome', 'board', 'boardContent', 'sharedContent', 'mail', 'mailindex', 'friends', 'friendsindex')
|
||||
self.whitelistEndpoints = ('site', 'www', 'onionrhome', 'board', 'profiles', 'profilesindex',
|
||||
'boardContent', 'sharedContent', 'mail', 'mailindex', 'friends', 'friendsindex')
|
||||
|
||||
self.clientToken = config.get('client.webpassword')
|
||||
self.timeBypassToken = base64.b16encode(os.urandom(32)).decode()
|
||||
@ -272,6 +273,7 @@ class API:
|
||||
onionrInst.setClientAPIInst(self)
|
||||
app.register_blueprint(friendsapi.friends)
|
||||
app.register_blueprint(simplecache.simplecache)
|
||||
app.register_blueprint(profilesapi.profile_BP)
|
||||
httpapi.load_plugin_blueprints(app)
|
||||
|
||||
@app.before_request
|
||||
@ -319,6 +321,14 @@ class API:
|
||||
def loadContacts():
|
||||
return send_from_directory('static-data/www/friends/', 'index.html')
|
||||
|
||||
@app.route('/profiles/<path:path>', endpoint='profiles')
|
||||
def loadContacts(path):
|
||||
return send_from_directory('static-data/www/profiles/', path)
|
||||
|
||||
@app.route('/profiles/', endpoint='profilesindex')
|
||||
def loadContacts():
|
||||
return send_from_directory('static-data/www/profiles/', 'index.html')
|
||||
|
||||
@app.route('/serviceactive/<pubkey>')
|
||||
def serviceActive(pubkey):
|
||||
try:
|
||||
|
28
onionr/httpapi/profilesapi/__init__.py
Normal file
28
onionr/httpapi/profilesapi/__init__.py
Normal file
@ -0,0 +1,28 @@
|
||||
'''
|
||||
Onionr - P2P Anonymous Storage Network
|
||||
|
||||
This file creates http endpoints for user profile pages
|
||||
'''
|
||||
'''
|
||||
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/>.
|
||||
'''
|
||||
import core
|
||||
from flask import Blueprint, Response, request, abort
|
||||
from . import profiles
|
||||
|
||||
profile_BP = Blueprint('profile_BP', __name__)
|
||||
|
||||
@profile_BP.route('/profile/get/<pubkey>', endpoint='profiles')
|
||||
def get_profile_page(pubkey):
|
||||
return Response(pubkey)
|
2
onionr/httpapi/profilesapi/profiles.py
Normal file
2
onionr/httpapi/profilesapi/profiles.py
Normal file
@ -0,0 +1,2 @@
|
||||
def get_latest_user_profile(pubkey):
|
||||
return ''
|
@ -1 +1 @@
|
||||
huei7fugyuesltkf3yzj27an36skz2f2u55g7ganyaq6yjhauwicwfyd.onion
|
||||
ecaufnpxx67xmvzwcriohapmmnqbj665h3ynemvwrr2juxl5oa5g7cad.onion
|
||||
|
@ -42,6 +42,7 @@ def mail_delete(block):
|
||||
if block not in existing:
|
||||
existing.append(block)
|
||||
kv.put('deleted_mail', existing)
|
||||
kv.flush()
|
||||
return 'success'
|
||||
|
||||
@flask_blueprint.route('/mail/getinbox')
|
||||
@ -50,16 +51,30 @@ def list_inbox():
|
||||
|
||||
@flask_blueprint.route('/mail/getsentbox')
|
||||
def list_sentbox():
|
||||
kv.refresh()
|
||||
sentbox_list = sentboxdb.SentBox(c).listSent()
|
||||
sentbox_list_copy = list(sentbox_list)
|
||||
list_copy = list(sentbox_list)
|
||||
deleted = kv.get('deleted_mail')
|
||||
if deleted is None:
|
||||
deleted = []
|
||||
for x in range(len(sentbox_list_copy) - 1):
|
||||
for x in list_copy:
|
||||
if x['hash'] in deleted:
|
||||
sentbox_list.remove(x)
|
||||
return json.dumps(sentbox_list)
|
||||
'''
|
||||
@flask_blueprint.route('/mail/getsentbox')
|
||||
def list_sentbox():
|
||||
sentbox_list = sentboxdb.SentBox(c).listSent()
|
||||
sentbox_list_copy = list(sentbox_list)
|
||||
kv.refresh()
|
||||
deleted = kv.get('deleted_mail')
|
||||
if deleted is None:
|
||||
deleted = []
|
||||
for x in range(len(sentbox_list_copy)):
|
||||
if sentbox_list_copy[x]['hash'] in deleted:
|
||||
x -= 1
|
||||
sentbox_list.pop(x)
|
||||
sentbox_list.remove(sentbox_list_copy[x]['hash'])
|
||||
else:
|
||||
sentbox_list[x]['name'] = contactmanager.ContactManager(c, sentbox_list_copy[x]['peer'], saveUser=False).get_info('name')
|
||||
|
||||
return json.dumps(sentbox_list)
|
||||
'''
|
@ -4,12 +4,12 @@
|
||||
"display_header" : false,
|
||||
"minimum_block_pow": 4,
|
||||
"minimum_send_pow": 4,
|
||||
"socket_servers": true,
|
||||
"socket_servers": false,
|
||||
"security_level": 0,
|
||||
"max_block_age": 2678400,
|
||||
"bypass_tor_check": false,
|
||||
"public_key": "",
|
||||
"random_bind_ip": true
|
||||
"random_bind_ip": false
|
||||
},
|
||||
|
||||
"www" : {
|
||||
|
@ -36,8 +36,11 @@
|
||||
<div>
|
||||
From: <input type='text' id='fromUser' readonly> Signature: <span id='sigValid'></span>
|
||||
</div>
|
||||
<div class='break-up'>
|
||||
Subject: <span id='subjectView'></span>
|
||||
</div>
|
||||
<div>
|
||||
<button id='replyBtn' class='primaryBtn'>Reply</button>
|
||||
<button id='replyBtn' class='primaryBtn break-up'>Reply</button>
|
||||
</div>
|
||||
<div id='signatureValidity'></div>
|
||||
<div id='threadDisplay' class='pre messageContent'>
|
||||
|
@ -92,7 +92,7 @@ input{
|
||||
color: black;
|
||||
}
|
||||
|
||||
#replyBtn{
|
||||
.break-up{
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,7 @@ threadContent = {}
|
||||
myPub = httpGet('/getActivePubkey')
|
||||
replyBtn = document.getElementById('replyBtn')
|
||||
|
||||
function openReply(bHash){
|
||||
function openReply(bHash, quote, subject){
|
||||
var inbox = document.getElementsByClassName('threadEntry')
|
||||
var entry = ''
|
||||
var friendName = ''
|
||||
@ -41,13 +41,23 @@ function openReply(bHash){
|
||||
}
|
||||
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]
|
||||
}
|
||||
quote = splitQuotes.join('\n')
|
||||
document.getElementById('draftText').value = quote
|
||||
setActiveTab('send message')
|
||||
}
|
||||
|
||||
function openThread(bHash, sender, date, sigBool, pubkey){
|
||||
function openThread(bHash, sender, date, sigBool, pubkey, subjectLine){
|
||||
var messageDisplay = document.getElementById('threadDisplay')
|
||||
var blockContent = httpGet('/getblockbody/' + bHash)
|
||||
document.getElementById('fromUser').value = sender
|
||||
document.getElementById('subjectView').innerText = subjectLine
|
||||
messageDisplay.innerText = blockContent
|
||||
var sigEl = document.getElementById('sigValid')
|
||||
var sigMsg = 'signature'
|
||||
@ -64,7 +74,7 @@ function openThread(bHash, sender, date, sigBool, pubkey){
|
||||
sigEl.innerText = sigMsg
|
||||
overlay('messageDisplay')
|
||||
replyBtn.onclick = function(){
|
||||
openReply(bHash)
|
||||
openReply(bHash, messageDisplay.innerText, subjectLine)
|
||||
}
|
||||
}
|
||||
|
||||
@ -174,7 +184,7 @@ function loadInboxEntries(bHash){
|
||||
if (event.target.classList.contains('deleteBtn')){
|
||||
return
|
||||
}
|
||||
openThread(entry.getAttribute('data-hash'), senderInput.value, dateStr.innerText, resp['meta']['validSig'], entry.getAttribute('data-pubkey'))
|
||||
openThread(entry.getAttribute('data-hash'), senderInput.value, dateStr.innerText, resp['meta']['validSig'], entry.getAttribute('data-pubkey'), subjectLine.innerText)
|
||||
}
|
||||
|
||||
deleteBtn.onclick = function(){
|
||||
@ -216,7 +226,7 @@ function getSentbox(){
|
||||
if (keys.length == 0){
|
||||
threadPart.innerHTML = "nothing to show here yet."
|
||||
}
|
||||
for (var i = 0; i < keys.length; i++){
|
||||
for (var i = 0; i < keys.length; i++) (function(i, resp){
|
||||
var entry = document.createElement('div')
|
||||
var obj = resp[i]
|
||||
var toLabel = document.createElement('span')
|
||||
@ -245,19 +255,18 @@ function getSentbox(){
|
||||
entry.appendChild(toEl)
|
||||
entry.appendChild(preview)
|
||||
entry.appendChild(sentDate)
|
||||
entry.onclick = (function(tree, el, msg) {return function() {
|
||||
console.log(resp)
|
||||
if (! entry.classList.contains('deleteBtn')){
|
||||
showSentboxWindow(el.value, msg)
|
||||
}
|
||||
};})(entry, toEl, message);
|
||||
|
||||
deleteBtn.onclick = function(){
|
||||
entry.parentNode.removeChild(entry);
|
||||
deleteMessage(entry.getAttribute('data-hash'))
|
||||
}
|
||||
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()
|
||||
}
|
||||
})(i, resp)
|
||||
threadPart.appendChild(entry)
|
||||
}.bind(threadPart))
|
||||
}
|
||||
@ -304,7 +313,6 @@ for (var i = 0; i < document.getElementsByClassName('refresh').length; i++){
|
||||
document.getElementsByClassName('refresh')[i].style.float = 'right'
|
||||
}
|
||||
|
||||
|
||||
fetch('/friends/list', {
|
||||
headers: {
|
||||
"token": webpass
|
||||
|
20
onionr/static-data/www/profiles/index.html
Normal file
20
onionr/static-data/www/profiles/index.html
Normal file
File diff suppressed because one or more lines are too long
0
onionr/static-data/www/profiles/profiles.js
Normal file
0
onionr/static-data/www/profiles/profiles.js
Normal file
Loading…
Reference in New Issue
Block a user