1 Commits

Author SHA1 Message Date
jeff
dbaef40178 fix build docs 2015-08-05 11:54:45 -04:00
17 changed files with 140 additions and 546 deletions

30
LICENSE
View File

@@ -1,21 +1,17 @@
The MIT License (MIT)
Copyright (c) 2015 Jeff Becker
NOT FOR RECTAL USE PUBLIC LICENSE
Version 1.1, Febuary 2015
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
Copyright (C) 2015 Jeff Becker <ampernand@gmail.com>
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
NOT FOR RECTAL USE PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. NOT for rectal use.
1. Don't sue me, it's your fault.
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@@ -1,18 +1,16 @@
# NNTPChan #
NNTPChan (previously known as overchan) is a decentralized imageboard that uses nntp to synchronize content between many different servers. It utilizes cryptograpghicly signed posts to perform optional/opt-in decentralized moderation.
This repository contains resources used by the core daemon which is located [here](https://github.com/majestrate/srndv2) along with general documentation, [here](doc/)
NNTPChan (previously known as overchan) is a decentralized imageboard that uses nntp to synchronize content between many different servers. It utilizes cryptograpghicly signed posts to perform optional/opt-in decentralized moderation (currently work-in-progress)
## getting started ##
After you [built and installed the daemon](doc/build.md) and [set up your database](doc/database.md), clone this repository and start up the daemon
If you don't want to compile from source, you can download a precompiled binary [here](https://github.com/majestrate/srndv2/releases) when they are released.
After you [built and installed the daemon](build-daemon.md) and [set up your database](database-setup.md), clone this repository and start up the daemon
# clone it
git clone https://github.com/majestrate/nntpchan ~/nntpchan
# get the latest stable release
cd ~/nntpchan/
git checkout tags/0.2.1
git clone https://github.com/majestrate/nntpchan
cd nntpchan
# set up the workspace
srndv2 setup
@@ -20,12 +18,11 @@ After you [built and installed the daemon](doc/build.md) and [set up your databa
# run the daemon
srndv2 run
Then open http://127.0.0.1:18000/ukko.html in your browser.
*PLEASE* report any bugs you find while setting up or building [(here)](https://github.com/majestrate/nntpchan/issues) so that the problems get fixed (^:
For peering requests, questions or support find me on [rizon](https://qchat.rizon.net/?channels=#nntpchan) as \__uguu\__
For peering requests, questions or support find me on [rizon](https://qchat.rizon.net/?channels=#8chan-dev) as \__uguu\__
Like this project? Fund it:

View File

@@ -7,7 +7,6 @@
* go 1.4 or higher
* libsodium 1.0 or higher
* imagemagick
* RabbitMQ
## debian ##
@@ -23,7 +22,7 @@ Debian Jessie has go 1.3, we need 1.4 or higher to build the nntpchan daemon so
# set up a directory for our go distribution
mkdir -p $HOME/local
cd $HOME/local
cd $$HOME/local
# obtain and unpack go binary distribution
wget https://storage.googleapis.com/golang/go1.4.2.linux-amd64.tar.gz -O go-stable.tar.gz
@@ -44,10 +43,12 @@ We'll also need to install some dependancies that come with debian:
# as root
apt update
apt install imagemagick libsodium-dev
apt-get update
apt-get install libmagickwand-dev libsodium-dev
Now you can build the daemon:
Now build the daemon:
go get github.com/majestrate/srndv2
go install github.com/majestrate/srndv2

View File

@@ -1,47 +0,0 @@
<html>
<head>
<link rel="stylesheet" href="site.css"></link>
<title> NNTPChan Frequently Asked Questions</title>
</head>
<body>
<h2>NNTPChan faq </h2>
<br/>
<hr />
<div id="faq">
<p>
<div>Question: What is nntpchan?</div>
<div>NNTPCchan is a federated imageboard that spans across several networks including tor, i2p and anonet. There are no central servers so that as long as 1 server is left the forum will continue to function.</div>
</p>
<hr />
<p>
<div>Question: How is this different from *chan? </div>
<div>NNTPChan is by design invulnerable to global censorship. All moderation is local to each server.</div>
</p>
<hr />
<p>
<div>Question: How does moderation work then? </div>
<div>Moderation is done with our special tripcodes (ed25519-sha512 signed posts). Anyone can give moderation suggestions, but that doesn't mean anyone will accept them. Those who trust the actions of a moderator can have their frontend whitelist the moderation actions and have them performed without oversight by another moderator.</div>
</p>
<hr />
<p>
<div>Question: How can I remove content from nntpchan completely? </div>
<div>‾\(._.)/‾ I don't know. You probably can't unless every server agrees to remove the content, even then, nothing prevents someone from reposting it. You can't delete what you post on the internet.</div>
</p>
<hr />
<p>
<div>Question: Do you allow XYZ content? </div>
<div>If it violates USA Law or causes problems with my host, no. Otherwise, yes. <b>All posts on this site are the responsibility of the individual poster and not the administration of this server</b>.</div>
</p>
<hr />
<p>
<div>Question: I found a bug or I have a feature request where do I go? </div>
<div><a href="https://github.com/majestrate/nntpchan/issues">github</a></div>
</p>
<hr />
<p>
<div>Please send any questions to ampernand [|at\] gmail {dot} com with subject starting with "nntpchan question" </div>
</p>
<hr />
</div>
</body>
</html>

View File

@@ -18,77 +18,20 @@ function get_longhash(str) {
return str;
}
// handle ban command
function nntpchan_ban() {
nntpchan_mod({
parser: get_longhash,
name: "ban",
handle: function(j) {
if (j.banned) {
return document.createTextNode(j.banned);
}
}
});
}
function nntpchan_unban() {
nntpchan_mod({
name: "unban",
handle: function(j) {
if (j.result) {
return document.createTextNode(j.result);
}
}
})
}
// handle delete command
function nntpchan_delete() {
nntpchan_mod({
parser: get_longhash,
name: "del",
handle: function(j) {
var elem = document.createElement("div");
if (j.deleted) {
for ( var idx = 0 ; idx < j.deleted.length ; idx ++ ) {
var msg = "deleted: " + j.deleted[idx];
var e = document.createTextNode(msg);
var el = document.createElement("div");
el.appendChild(e);
elem.appendChild(el);
}
}
if (j.notdeleted) {
for ( var idx = 0 ; idx < j.notdeleted.length ; idx ++ ) {
var msg = "not deleted: " + j.notdeleted[idx];
var e = document.createTextNode(msg);
var el = document.createElement("div");
el.appendChild(e);
elem.appendChild(el);
}
}
return elem;
}
});
}
function nntpchan_mod(mod_action) {
// get the element
var input = document.getElementById("nntpchan_mod_target");
var target = input.value;
if (mod_action.parser) {
target = mod_action.parser(target);
}
var input = document.getElementById("nntpchan_mod_delete");
// get the long hash
var longhash = get_longhash(input.value);
// TODO: check long hash
var elem = document.getElementById("nntpchan_mod_result");
// clear old results
while( elem.firstChild ) {
elem.removeChild(elem.firstChild);
}
// fire off ajax
var ajax = new XMLHttpRequest();
ajax.onreadystatechange = function() {
@@ -103,33 +46,29 @@ function nntpchan_mod(mod_action) {
var e = document.createTextNode(j.error);
elem.appendChild(e);
} else {
if (mod_action.handle) {
var result = mod_action.handle(j);
if (result) {
elem.appendChild(result);
} else {
// fail
alert("mod action failed, handler returned nothing");
if ( j.deleted ) {
for ( var idx = 0 ; idx < j.deleted.length ; idx ++ ) {
var deltxt = "deleted " + j.deleted[idx];
var e = document.createTextNode(deltxt);
elem.appendChild(e);
}
}
if ( j.notdeleted ) {
for ( var idx = 0 ; idx < j.notdeleted.length ; idx ++ ) {
var deltxt = "failed to delete " + j.notdeleted[idx];
var e = document.createTextNode(deltxt);
elem.appendChild(e);
}
} else {
// fail
alert("mod action has no handler");
}
}
} else if (status) {
} else {
// nah
// http error
elem.innerHTML = "error: HTTP "+status;
}
// clear input
input.value = "";
}
}
if (mod_action.name) {
var url = mod_action.name + "/" + target;
ajax.open("GET", url);
ajax.send();
} else {
alert("mod action has no name");
}
ajax.open("GET", "del/"+longhash);
ajax.send();
}

View File

@@ -1,9 +1,6 @@
.thread {
margin-right: 20px;
margin-bottom: 1em;
display: inline-block;
word-wrap: break-word;
width: 100%;
margin_right: 20px;
margin_bottom: 5px;
}
.frontend , .subject {
@@ -19,101 +16,18 @@
font-weight: bold;
}
#postform-outer {
text-align: center;
}
input {
width: 70%;
}
input.button {
width: 25%;
}
textarea {
width: 350px;
}
#postform-inner {
display: inline-block;
}
.post {
padding: 10px 10px;
}
.reply, th, .ukko_thread_header {
background: #d6daf0;
}
hr {
height: 0px;
border-width: 1px medium medium;
border-color: #b7c5d9;
border-style: solid none none;
}
a:hover , a:visited:hover {
color: #f13333;
}
a {
color: blue;
}
a:visited {
color: #414383;
}
.navbar {
position: fixed;
top: 0px;
left: 0px;
right: 0px;
margin-top: 0px;
z-index: 20;
box-shadow: 0px 1px 20px rgba(0, 0, 0, 0.15);
background: #CFD8EF;
color: #616383;
}
.navbar-sep {
color: black;
}
#postform_container {
margin-top: 5em;
}
.ukko_thread_header {
padding: 5px 5px;
margin: 5px 5px;
display: inline-block;
}
th {
font-size: 10pt;
padding-left: 10px;
padding-right: 15px;
padding: 10px;
}
body {
background: linear-gradient(to top, #eef2ff, #eaf1ff) repeat scroll;
font-family: arial,helvetica,sans-serif;
font-size: 10pt;
margin: 0 4px;
padding-left: 4px;
padding-right: 4px;
background: #eef2ff;
}
.reply {
margin-left: 1.8em;
display: inline-block;
border-radius: 3px;
}
.frontend {
@@ -123,17 +37,20 @@ body {
}
.op {
background: #eef2ff;
margin-right: 20px;
margin-bottom: 10px;
}
.post, .post_body {
margin-top: 5px;
margin-bottom: 5px;
padding-right: 3em;
padding-bottom: 0.3em;
}
.post_body > p {
margin: 2px;
word-wrap: break-word;
}
.tripcode {
@@ -142,41 +59,4 @@ body {
.memearrows {
color: green;
}
.intro {
margin-bottom: 0.75em;
}
.file:not(.multiple) .file-thumbnail {
float: left;
}
.file-thumbnail {
display: block;
margin: 5px 20px 10px;
border: medium none;
max-width: 300px;
max-height: 200px;
}
pre > p {
margin: 0px 0px;
}
.reply , .post_body > pre , .ukko_thread_header {
padding: 7px 7px;
border-radius: 5px;
box-shadow: 1px 1px 3px black;
}
.post_body > pre {
background: #3f3f3f;
color: #d17600;
}
#faq > div {
margin-left: 20%;
width: 50%;
padding: 10px;
}

View File

@@ -14,6 +14,7 @@
<html>
<head>
<meta charset="utf-8" />
<script type="text/javascript" src="{{board.Prefix}}static/captcha.js"></script>
<link rel="stylesheet" href="{{board.Prefix}}static/site.css"></link>
<title>{{board.Board}}</title>
</head>
@@ -32,11 +33,11 @@
<div class="thread" id="thread_{{OP.PostHash}}">
<div clsss="thread_header">
</div>
{{{OP.Truncate.RenderPost}}}
{{#Truncate.Replies}}
{{{Truncate.RenderPost}}}
{{{OP.RenderPost}}}
{{#Replies}}
{{{RenderPost}}}
<br />
{{/Truncate.Replies}}
{{/Replies}}
</div>
<br/>
<hr/>

View File

@@ -1,57 +0,0 @@
{{!
frontpage.mustache -- template for index.html
template parameters:
- graph ( a list of 4 string tuples: (board, posts_per_hour, posts_per_day, total_posts) )
- totalposts ( the number of total posts we have ever seen )
- frontend ( the name of the frontend )
- prefix ( the site's prefix )
}}
<html>
<head>
<link rel="stylesheet" href="{{prefix}}static/site.css"></link>
<title> {{frontend}} on nntpchan </title>
</head>
<body>
<center>
<div class="index-outer">
<div class="index-inner">
<h1> {{frontend}} on nntpchan </h1>
<h2>View the <a href="ukko.html">overboard</a></h2>
<h3>Read the <a href="{{prefix}}static/faq.html">FAQ</a></h3>
<h3>Join the <a href="https://i2p.rocks/irc/?channels=overchan&nick=nameless">IRC</a></h3>
<h3>Fork on github: <a href="https://github.com/majestrate/nntpchan/">frontend</a> and <a href="https://github.com/majestrate/srndv2/">core</a></h3>
<h4>We've Had {{totalposts}} Posts Since August 01 2015 </h4>
</div>
<div class="index-inner">
<table id="board_graph">
<tbody>
<tr>
<th> Board </th>
<th> Post per Hour </th>
<th> Post per Day </th>
<th> Total </th>
</tr>
{{# graph}}
<tr>
<td>
<a href="{{prefix}}{{Board}}-0.html">{{Board}}</a>
</td>
<td>
{{Hour}}
</td>
<td>
{{Day}}
</td>
<td>
{{All}}
</td>
</tr>
{{/ graph}}
</tbody>
</table>
</div>
</div>
</center>
</body>
</html>

View File

@@ -16,16 +16,12 @@
<div> post actions </div>
<hr />
<div>
<label for="nntpchan_mod_target">target</label>
<input id="nntpchan_mod_target" type="text" />
</div>
<div>
<button onclick="nntpchan_ban()">ban (url)</button>
<button onclick="nntpchan_delete()">delete (url)</button>
<button onclick="nntpchan_unban()">unban (ip)</button>
<label for="nntpchan_mod_delete">delete by url</label>
<input id="nntpchan_mod_delete" type="text" />
</div>
<button id="nntpchan_mod" onclick="nntpchan_delete()">go</button>
<span id="nntpchan_mod_result"></span>
</div>
<div id="nntpchan_mod_result"></div>
<noscript>
<b>enable js to use the mod panel kthx</b>
</noscript>

View File

@@ -7,40 +7,16 @@
- name ( the name of whatever resource we are on, board/thread )
- frontend ( the name of the frontend we are on )
- links ( a list of Link Models to display )
- prefix ( site prefix )
}}
<div class="navbar">
<span class="navbar-name">
<span class="board_title">{{name}}</span>
on
<span class="frontend_title">{{frontend}}</span>
</span>
<span class="navbar-sep">
|
</span>
<span class="navbar-links">
<span class="navbar-links-title">
Pages:
</span>
{{# links }}
<span class="navbar-link"><a href="{{LinkURL}}">{{Text}}</a></span>
{{/ links }}
</span>
<span class="navbar-sep">
|
</span>
<span class="navbar-links">
<span class="navbar-link"><a href="{{prefix}}">front page</a></span>
</span>
<span class="navbar-sep">
|
</span>
<span class="navbar-links">
<span class="navbar-link"><a href="{{prefix}}ukko.html">overboard</a></span>
</span>
<span class="navbar-sep">
|
</span>
</div>
<hr />
}}
<div>
<span class="board_title">{{name}}</span>
on
<span class="frontend_title">{{frontend}}</span>
</div>
<div class="links">
{{# links }}
<span class="link"><a href="{{LinkURL}}">{{Text}}</a></span>
{{/ links }}
</div>
<hr />

View File

@@ -1,9 +1,6 @@
<div class="{{{CSSClass}}}" id="post_{{PostHash}}">
<p class="intro">
<label for="delete_{{PostHash}}">
<span class="frontend">
[[ {{Frontend}} ]]
</span>
<span class="subject">
{{Subject}}
</span>
@@ -25,18 +22,15 @@
{{#OP}}
<a href="{{PostURL}}">[reply]</a>
{{/OP}}
<span class="tripcode">{{{Pubkey}}}</span>
</p>
<p class="frontend">
[[ {{Frontend}} ]]
</p>
<div class="files">
{{#Attachments}}
<div class="file">
<p class="file_info">
<span>File: {{Filename}}</span>
</p>
<a target="_blank" class="file-link" href="{{Source}}" title="{{Filename}}">
<img class="file-thumbnail" src="{{Thumbnail}}" alt="{{Filename}}" />
</a>
</div>
<a class="file" href="{{Source}}" title="{{Filename}}">
<img class="file-thumbnail" src="{{Thumbnail}}" alt="{{Filename}}" />
</a>
{{/Attachments}}
</div>
<div class="post_body">{{{RenderBody}}}</div>

View File

@@ -8,62 +8,57 @@
}}
<form action="{{post_url}}" enctype="multipart/form-data" name="post" method="post">
<input type="hidden" name="reference" value="{{reference}}" />
<div id="postform-outer">
<div id="postform-inner">
<table class="postform">
<tbody>
<tr>
<th>
Name
</th>
<td>
<input type="text" name="name" value="" />
</td>
</tr>
<tr>
<th>
Subject
</th>
<td>
<input type="text" name="subject" value="" />
<input type="submit" value="{{button}}" class="button" />
</td>
</tr>
<tr>
<th>
Comment
</th>
<td>
<textarea type="text" name="message" cols=40 rows=5></textarea>
</td>
</tr>
<tr>
<th>
File
</th>
<td>
<input type="file" name="attachment" />
</td>
</tr>
<tr>
<th>
Captcha
</th>
<td>
<img id="captcha_img" src="{{prefix}}captcha/img" alt="captcha" />
</td>
</tr>
<tr>
<th>
Solution
</th>
<td>
<input type="text" name="captcha" />
</td>
</tr>
</tbody>
</table>
</div>
</div>
<input type="hidden" name="captcha" value="" id="captcha_input" />
<table class="postform">
<tbody>
<tr>
<th>
Name
</th>
<td>
<input type="text" name="name" value="" />
</td>
</tr>
<tr>
<th>
Subject
</th>
<td>
<input type="text" name="subject" value="" />
<input type="submit" value="{{button}}" />
</td>
</tr>
<tr>
<th>
Comment
</th>
<td>
<textarea type="text" name="message" cols=35 rows=5></textarea>
</td>
</tr>
<tr>
<th>
File
</th>
<td>
<input type="file" name="attachment" />
</td>
</tr>
<tr>
<th>
Captcha
</th>
<td>
<img id="captcha_img" src="" alt="captcha" />
</td>
</tr>
<tr>
<th>
</th>
<td>
<input type="text" name="captcha_solution" />
</td>
</tr>
</tbody>
</table>
</form>

View File

@@ -14,6 +14,7 @@
<html>
<head>
<meta charset="utf-8" />
<script type="text/javascript" src="{{thread.Prefix}}static/captcha.js"></script>
<link rel="stylesheet" href="{{thread.Prefix}}static/site.css"></link>
<title> {{thread.OP.Subject}} </title>
</head>

View File

@@ -11,9 +11,6 @@
<link rel="stylesheet" href="{{prefix}}static/site.css"></link>
</head>
<body>
<div id="ukko-topbar">
<a href="{{prefix}}">Front Page</a>
</div>
<div id="ukko_threads" class="threads_container">
{{#threads}}
<div class="ukko_thread_header">
@@ -23,10 +20,10 @@
<div clsss="thread_header">
</div>
{{{OP.RenderPost}}}
{{#Truncate.Replies}}
{{{Truncate.RenderPost}}}
{{#Replies}}
{{{RenderPost}}}
<br />
{{/Truncate.Replies}}
{{/Replies}}
</div>
<hr/>
{{/threads}}

View File

@@ -1,23 +0,0 @@
#!/usr/bin/env bash
#
# shell script for regenerating thumbnails
#
if [ "$1" == "" ] ; then
echo "usage: $0 webroot_dir"
else
cd $1
echo "regenerate missing thumbs in $(pwd)"
find img/ \
-type f \
-regextype posix-extended \
-iregex '.*\.(png|jpg|gif)$' \
-not -execdir test -f '../thm/{}' \; \
-exec echo 'generating missing thumb for {}' \; \
-exec mogrify \
-define jpeg:size=500x500 \
-thumbnail '250>x250>' \
-path thm/ \
-strip \
'{}' \;
fi

View File

@@ -1,52 +0,0 @@
## peering with other nodes ##
In order to actually be distributed, you need another person to sync posts with, otherwise what's the point right?
Right now peering information is private, there is no link level authenticatio (yet) so everything is done via either a vpn tunnel or a tor hidden service.
### Peering via cjdns vpn tunnel ###
Set up cjdns, read more [here](https://github.com/cjdelisle/cjdns/blob/master/doc/configure.md#connection-interfaces)
git clone https://github.com/cjdelisle/cjdns
cd cjdns && ./do
./cjdroute --genconf >> cjdroute.conf
./cjdroute < cjdroute.conf
Get your ipv6 address for cjdns
ip addr show tun0
Edit srnd.ini to bind nntp on that ipv6 address, make sure to use the square brances `[` and `]`
[nntp]
...
bind=[xxxx:xxxx:xxxx:xxx:xx....]:1199
say you have 2 friends at fc33:3:3::aadd and fc03:9f:123::a3df. right now feeds.ini can't take raw ipv6 addresses so add them to `/etc/hosts`
# add these lines to /etc/hosts
fc33:3:3::aadd bob
fc03:9f:123::a3df charlie
then add to feeds.ini the following:
[feed-bob]
proxy-type=none
[bob]
overchan.*=1
ctl=1
[feed-charlie]
proxy-type=none
[charlie]
overchan.*=1
ctl=1
then restart srndv2
**TODO:** firewalling