basic peer and block sync finished, torcheck added
This commit is contained in:
parent
329d296df3
commit
c185b0b02a
BIN
hacker.png
BIN
hacker.png
Binary file not shown.
Before Width: | Height: | Size: 399 B |
66
hush-hush.js
66
hush-hush.js
@ -17,10 +17,36 @@
|
|||||||
*/
|
*/
|
||||||
var findMessageIntervalTime = 5000
|
var findMessageIntervalTime = 5000
|
||||||
var publicNodes = [
|
var publicNodes = [
|
||||||
"4gh2dwbmlrombeoyco55un7kbej7trsuebxfzvo53h6uj5adseceduyd"
|
"yre3tmbu25lcogl42xlh73wfchgbx3unz2zz3ttyiylj6gaq5mzhevid"
|
||||||
]
|
]
|
||||||
var messageHashes = []
|
var messageHashes = []
|
||||||
var blocks = {}
|
var blocks = []
|
||||||
|
var basicTextEncoder = new TextEncoder()
|
||||||
|
var difficulty = "0000"
|
||||||
|
var maxBlockAge = 2678400
|
||||||
|
|
||||||
|
|
||||||
|
function shuffleArray(array) {
|
||||||
|
if (document.hidden){return}
|
||||||
|
for (let i = array.length - 1; i > 0; i--) {
|
||||||
|
const j = Math.floor(Math.random() * (i + 1));
|
||||||
|
[array[i], array[j]] = [array[j], array[i]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//https://stackoverflow.com/q/10420352
|
||||||
|
function getReadableFileSizeString(fileSizeInBytes) {
|
||||||
|
var i = -1;
|
||||||
|
var byteUnits = [' kB', ' MB', ' GB', ' TB', 'PB', 'EB', 'ZB', 'YB'];
|
||||||
|
do {
|
||||||
|
fileSizeInBytes = fileSizeInBytes / 1024;
|
||||||
|
i++;
|
||||||
|
} while (fileSizeInBytes > 1024);
|
||||||
|
|
||||||
|
return Math.max(fileSizeInBytes, 0.1).toFixed(1) + byteUnits[i];
|
||||||
|
};
|
||||||
|
|
||||||
|
setInterval(function(){shuffleArray(publicNodes)}, 5000)
|
||||||
|
|
||||||
|
|
||||||
// Make Tor connect to each node to reduce future connection time
|
// Make Tor connect to each node to reduce future connection time
|
||||||
publicNodes.forEach(element => {
|
publicNodes.forEach(element => {
|
||||||
@ -40,7 +66,7 @@ function addMessage(message, timestamp){
|
|||||||
|
|
||||||
let newEl = tmpl.content.cloneNode(true)
|
let newEl = tmpl.content.cloneNode(true)
|
||||||
newEl.children[0].children[0].children[0].innerText = message
|
newEl.children[0].children[0].children[0].innerText = message
|
||||||
newEl.children[0].children[0].children[1].innerText = timestamp
|
newEl.children[0].children[0].children[2].innerText = timestamp
|
||||||
document.getElementsByClassName("messageFeed")[0].append(newEl)
|
document.getElementsByClassName("messageFeed")[0].append(newEl)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,16 +85,40 @@ async function apiGET(path, queryString, raw=false){
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function findMessages(){
|
async function findMessages(){
|
||||||
|
if (document.hidden){
|
||||||
|
setTimeout(function(){findMessages()}, 1000)
|
||||||
|
return
|
||||||
|
}
|
||||||
let messages = (await apiGET("getblocklist", "?type=brd")).split('\n')
|
let messages = (await apiGET("getblocklist", "?type=brd")).split('\n')
|
||||||
messages.forEach(block => {
|
messages.forEach(block => {
|
||||||
if (! block){return}
|
block = reconstructHash(block)
|
||||||
if (block in blocks){return}
|
if (!block.startsWith(difficulty)){console.debug("not difficulty reached:" + block); return}
|
||||||
|
|
||||||
|
if (blocks.includes(block)){return}
|
||||||
apiGET("getdata", "/" + block, raw=false).then(function(d){
|
apiGET("getdata", "/" + block, raw=false).then(function(d){
|
||||||
let metadata = d.split("\n")[0]
|
let updateMemoryUsage = function(data, block){
|
||||||
|
let current = parseInt(document.getElementById('memUsage').innerText)
|
||||||
|
// Size is size of data (not metadata) and block hash
|
||||||
|
document.getElementById('memUsage').innerText = getReadableFileSizeString(current + ((basicTextEncoder.encode(data)).length + block.length))
|
||||||
|
}
|
||||||
|
|
||||||
|
try{
|
||||||
|
verifyBlock(d, block)
|
||||||
|
verifyTime()
|
||||||
|
}
|
||||||
|
catch(e){
|
||||||
|
console.debug(block + ":" + e)
|
||||||
|
}
|
||||||
|
|
||||||
|
let metadata = JSON.parse(d.split("\n")[0])
|
||||||
|
console.debug(metadata)
|
||||||
let data = d.split('\n')[1]
|
let data = d.split('\n')[1]
|
||||||
blocks[block] = data
|
blocks.push(block)
|
||||||
|
addMessage(data, new Date(metadata['time']))
|
||||||
|
updateMemoryUsage(data, block)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
setTimeout(function(){findMessages()}, findMessageIntervalTime)
|
||||||
}
|
}
|
||||||
|
|
||||||
setInterval(function(){findMessages()}, findMessageIntervalTime)
|
setTimeout(function(){findMessages()}, findMessageIntervalTime)
|
47
index.html
47
index.html
@ -3,7 +3,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
|
|
||||||
<title>hush-hush</title>
|
<title>kiccan</title>
|
||||||
|
|
||||||
<meta name="description" content="Generate Onionr block">
|
<meta name="description" content="Generate Onionr block">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
|
||||||
@ -11,32 +11,52 @@
|
|||||||
|
|
||||||
<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>👁️</text></svg>">
|
<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>👁️</text></svg>">
|
||||||
<link rel="stylesheet" href="css/bulma-dark.min.css">
|
<link rel="stylesheet" href="css/bulma-dark.min.css">
|
||||||
|
<link rel="stylesheet" href="style.css">
|
||||||
|
<script src="tordetect.js" async></script>
|
||||||
|
<script src="marked.min.js" defer></script>
|
||||||
<script src="sha3.js" defer></script>
|
<script src="sha3.js" defer></script>
|
||||||
<script src="onionr-jspow/index.js" defer></script>
|
<script src="onionr-jspow/index.js" defer></script>
|
||||||
<script src="hush-hush.js" defer></script>
|
|
||||||
<script src="onionr-blocks.js" defer></script>
|
<script src="onionr-blocks.js" defer></script>
|
||||||
|
<script src="hush-hush.js" defer></script>
|
||||||
<script src="worker-handler.js" defer></script>
|
<script src="worker-handler.js" defer></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<section class="section">
|
<section class="section">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<h1 class="title">
|
<h1 class="title">
|
||||||
hush-hush
|
kiccan
|
||||||
</h1>
|
</h1>
|
||||||
<p class="subtitle">
|
<p class="subtitle">
|
||||||
Anonymous decentralized message board 🤫
|
anonymous decentralized message board 🌐
|
||||||
|
<img src="vanilla.png" alt="this website uses vanilla JS" aria-hidden="true" loading="lazy" class="is-pulled-right">
|
||||||
|
<img src="copyleft.png" alt="GNU" aria-hidden="true" loading="lazy" class="is-pulled-right">
|
||||||
</p>
|
</p>
|
||||||
<noscript><p>JavaScript is required for this app.</p></noscript>
|
<noscript><p class="has-text-warning">
|
||||||
<p>ℹ️ hush-hush is a message board program that utilizes the Onionr network.</p>
|
JavaScript is required for this app. The server has no knowledge of posts, so content must be served by P2P nodes.
|
||||||
<p>⚠️ Posts are rate-limited using a partial hash collision proof of work function.</p>
|
</p></noscript>
|
||||||
<p>⏲️ The host of this web page has no control over posts. Browse and post at your own risk.</p>
|
<p>kiccan is a message board program that utilizes the <a href="https://onionr.net/">Onionr</a> network.</p>
|
||||||
<img src="vanilla.png" alt="this website uses vanilla JS" aria-hidden="true" loading="lazy">
|
<p>⏲️posts are rate-limited using a partial hash collision proof of work function.</p>
|
||||||
<img src="hacker.png" alt="hacker" aria-hidden="true" loading="lazy">
|
<p>⚠️ the host of this web page has no control over posts. Browse and post at your own risk.</p>
|
||||||
<img src="copyleft.png" alt="GNU" aria-hidden="true" loading="lazy">
|
<p class="is-pulled-right">post memory usage: <span id="memUsage">0kb</span></p>
|
||||||
|
<p class="is-hidden has-text-warning noTor">You do not seem to be able to reach .onion services. Please use Tor Browser or Brave Browser's private tabs.</p>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
<div class="container messageCreator">
|
||||||
|
<div class="columns">
|
||||||
|
<div class="column is-two-fifths">
|
||||||
|
<div class="postForm">
|
||||||
|
<div class="control">
|
||||||
|
<textarea class="textarea" placeholder="Normal textarea"></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="column">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="control">
|
||||||
|
<a class="button is-primary">Create Post</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="container messageFeed">
|
<div class="container messageFeed">
|
||||||
</div>
|
</div>
|
||||||
<template id="cMsgTemplate">
|
<template id="cMsgTemplate">
|
||||||
@ -46,7 +66,6 @@
|
|||||||
Message
|
Message
|
||||||
</div>
|
</div>
|
||||||
<div class="column cAuthor is-narrow"></div>
|
<div class="column cAuthor is-narrow"></div>
|
||||||
<!--<img class="identicon image is-48x48" alt="user icon" src="/shared/images/anon.svg">-->
|
|
||||||
<div class="column is-narrow cMsgDate">
|
<div class="column is-narrow cMsgDate">
|
||||||
Date
|
Date
|
||||||
</div>
|
</div>
|
||||||
|
6
marked.min.js
vendored
Normal file
6
marked.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -17,14 +17,22 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
self.addEventListener('message', function(e) {
|
self.addEventListener('message', async function(e) {
|
||||||
let lookupPeer = async function(peer){
|
let lookupPeer = async function(peer){
|
||||||
let newList = await fetch('http://')
|
let newList = await (await fetch('http://' + peer + '.onion/pex')).text()
|
||||||
|
|
||||||
|
newList = newList.replace('.onion', '')
|
||||||
|
return newList.split(',')
|
||||||
}
|
}
|
||||||
var data = JSON.parse(e.data)
|
var data = JSON.parse(e.data)
|
||||||
|
|
||||||
let peers = data['nodeList']
|
let peer = data['node']
|
||||||
lookupPeer(peers)
|
let peerList = await lookupPeer(peer)
|
||||||
|
peerList.forEach(node => {
|
||||||
|
if (node){
|
||||||
|
postMessage(node)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
)
|
)
|
7
style.css
Normal file
7
style.css
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
.subtitle img{
|
||||||
|
padding-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.messageCreator{
|
||||||
|
margin-bottom: 1em;
|
||||||
|
}
|
8
tordetect.js
Normal file
8
tordetect.js
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
let torDetect = function(){
|
||||||
|
let el = document.createElement('img')
|
||||||
|
el.onerror = function(){
|
||||||
|
document.getElementsByClassName('noTor')[0].classList.remove('is-hidden')
|
||||||
|
}
|
||||||
|
el.src = "https://3g2upl4pq6kufc4m.onion/favicon.ico"
|
||||||
|
}
|
||||||
|
setTimeout(torDetect, 1000)
|
@ -2,6 +2,12 @@ var lookupWorker = new Worker('peer-lookup.js');
|
|||||||
|
|
||||||
|
|
||||||
lookupWorker.addEventListener('message', function(e) {
|
lookupWorker.addEventListener('message', function(e) {
|
||||||
console.log('Worker said: ', e.data);
|
publicNodes.push(e.data)
|
||||||
}, false);
|
}, false);
|
||||||
lookupWorker.postMessage(JSON.stringify({"nodeList": publicNodes}))
|
|
||||||
|
|
||||||
|
|
||||||
|
setInterval(function(){
|
||||||
|
lookupWorker.postMessage(JSON.stringify({"node": getCurrentNode()}))
|
||||||
|
}, 60000)
|
||||||
|
lookupWorker.postMessage(JSON.stringify({"node": getCurrentNode()}))
|
||||||
|
Loading…
Reference in New Issue
Block a user