make it work, and also make it embeddable in Go applications

This commit is contained in:
idk
2020-09-09 11:08:16 -04:00
parent 64d325476b
commit 2ba3977385
17 changed files with 968 additions and 469 deletions

View File

@ -1,9 +1,15 @@
run:
run: fmt gen
go run ./
fmt:
gofmt -w -s *.go */*.go
clean:
rm i2pcontrol.js
i2pcontrol.js:
wget "https://raw.githubusercontent.com/eyedeekay/I2P-in-Private-Browsing-Mode-Firefox/i2pcontrol/i2pcontrol/i2pcontrol.js"
wget "https://raw.githubusercontent.com/eyedeekay/I2P-in-Private-Browsing-Mode-Firefox/i2pcontrol/i2pcontrol/i2pcontrol.js"
gen:
go run --tags=generate gen.go

View File

@ -1,5 +1,3 @@
# toopie.html
I2P Router monitoring in HTML and Javascript. Only like, 10% a joke, I actually
think it could be useful. Doesn't work yet due to a CORS issue but once that's
resolved I'll explain what it's actually for. Also it already works in the
i2pcontrol branch of the I2P In Private Browsing Webextension.
Still real crude, but it works now.

11
gen.go Normal file
View File

@ -0,0 +1,11 @@
//+build generate
package main
import "github.com/zserge/lorca"
func main() {
// You can also run "npm build" or webpack here, or compress assets, or
// generate manifests, or do other preparations for your assets.
lorca.Embed("toopie", "lib/assets.go", "www")
}

View File

@ -1,277 +0,0 @@
var password = "itoopie";
var hello = "hello i2pcontrol";
function makeid(length) {
var result = "";
var characters =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
var charactersLength = characters.length;
for (var i = 0; i < length; i++) {
result += characters.charAt(Math.floor(Math.random() * charactersLength));
}
return result;
}
function send(message) {
async function postData(url = "", data = {}) {
// Default options are marked with *
console.log("(i2pcontrol)");
let requestBody = JSON.stringify(data);
let opts = {
method: "POST", // *GET, POST, PUT, DELETE, etc.
mode: "cors", // no-cors, *cors, same-origin
cache: "no-cache", // *default, no-cache, reload, force-cache, only-if-cached
credentials: "same-origin", // include, *same-origin, omit
headers: {
"Content-Type": "application/json"
},
redirect: "follow", // manual, *follow, error
referrerPolicy: "no-referrer", // no-referrer, *client
body: requestBody // body data type must match "Content-Type" header
};
const response = await fetch(url, opts);
return await response.json(); // parses JSON response into native JavaScript objects
}
return postData("http://127.0.0.1:7657/jsonrpc/", message);
}
function authenticate(password) {
var json = {
id: makeid(6),
jsonrpc: "2.0",
method: "Authenticate",
params: {
API: 1,
Password: password
}
};
return send(json);
}
async function GetToken(password) {
let me = authenticate(password);
return await me.then(gettoken);
}
function gettoken(authtoken) {
return authtoken.result.Token;
}
function Done(output) {
console.log("(i2pcontrol) I2PControl connection tested,", output);
return output;
}
function Echo(message) {
function echo(token) {
let json = {
id: makeid(6),
jsonrpc: "2.0",
method: "Echo",
params: {
Token: token,
Echo: message
}
};
return send(json);
}
let token = GetToken(password);
let done = token.then(echo);
return done;
}
function UpdateEchoElementByID(Query, ID) {
function updateelement(update) {
console.log("(i2pcontrol)", update);
document.getElementById(ID).innerText = update;
}
let net = Echo(Query);
net.then(updateleement);
}
function GetRate(Query) {
function getrate(token) {
var json = new Object();
json["id"] = makeid(6);
json["jsonrpc"] = "2.0";
json["method"] = "I2PControl";
json["params"] = new Object();
json["params"]["Token"] = token;
json["params"]["Stat"] = Query;
json["params"]["Period"] = 2000;
return send(json);
}
let token = GetToken(password);
let done = token.then(getrate);
return done;
}
function UpdateGetRateElementByID(Query, ID) {
function updateelement(update) {
console.log("(i2pcontrol)", update);
document.getElementById(ID).innerText = update;
}
let net = GetRate(Query);
net.then(updateleement);
}
function I2PControl(Query) {
function i2pcontrol(token) {
var json = new Object();
json["id"] = makeid(6);
json["jsonrpc"] = "2.0";
json["method"] = "I2PControl";
json["params"] = new Object();
json["params"]["Token"] = token;
json["params"][Query] = null;
return send(json);
}
let token = GetToken(password);
let done = token.then(i2pcontrol);
return done;
}
function UpdateI2PControlElementByID(Query, ID) {
function updateelement(update) {
console.log("(i2pcontrol)", update);
document.getElementById(ID).innerText = update;
}
let net = I2PControl(Query);
net.then(updateleement);
}
function RouterInfo(Query) {
function routerinfo(token) {
var json = new Object();
json["id"] = makeid(6);
json["jsonrpc"] = "2.0";
json["method"] = "RouterInfo";
json["params"] = new Object();
json["params"]["Token"] = token;
json["params"][Query] = null;
return send(json);
}
let token = GetToken(password);
let done = token.then(routerinfo);
return done;
}
function UpdateRouterInfoElementByID(Query, ID) {
function updateelement(update) {
console.log(
"(i2pcontrol)",
update.result[Query],
ID,
document.getElementById(ID)
);
document.getElementById(ID).innerText = update.result[Query];
}
let net = RouterInfo(Query);
net.then(updateelement);
}
function RouterManager(Query) {
function routermanager(token) {
var json = new Object();
json["id"] = makeid(6);
json["jsonrpc"] = "2.0";
json["method"] = "RouterManager";
json["params"] = new Object();
json["params"]["Token"] = token;
json["params"][Query] = null;
return send(json);
}
let token = GetToken(password);
let done = token.then(routermanager);
return done;
}
function UpdateRouterManagerElementByID(Query, ID) {
function updateelement(update) {
console.log("(i2pcontrol)", update);
document.getElementById(ID).innerText = update;
}
let net = RouterManage(Query);
net.then(updateleement);
}
function NetworkSetting(Query) {
function networksetting(token) {
var json = new Object();
json["id"] = makeid(6);
json["jsonrpc"] = "2.0";
json["method"] = "NetworkSetting";
json["params"] = new Object();
json["params"]["Token"] = token;
json["params"][Query] = null;
return send(json);
}
let token = GetToken(password);
let done = token.then(networksetting);
return done;
}
function UpdateNetworkSettingElementByID(Query, ID) {
function updateelement(update) {
console.log("(i2pcontrol)", update);
document.getElementById(ID).innerText = update;
}
let net = NetworkSetting(Query);
net.then(updateleement);
}
function UpdateContents() {
UpdateRouterInfoElementByID("i2p.router.status", "router-status");
UpdateRouterInfoElementByID("i2p.router.uptime", "router-uptime");
UpdateRouterInfoElementByID("i2p.router.version", "router-version");
UpdateRouterInfoElementByID(
"i2p.router.net.bw.inbound.1s",
"router-net-bw-inbound-1s"
);
UpdateRouterInfoElementByID(
"i2p.router.net.bw.inbound.15s",
"router-net-bw-inbound-15s"
);
UpdateRouterInfoElementByID(
"i2p.router.net.bw.outbound.1s",
"router-net-bw-outbound-1s"
);
UpdateRouterInfoElementByID(
"i2p.router.net.bw.outbound.15s",
"router-net-bw-outbound-15s"
);
UpdateRouterInfoElementByID("i2p.router.net.status", "router-net-status");
UpdateRouterInfoElementByID(
"i2p.router.net.tunnels.participating",
"router-net-tunnels-participating"
);
UpdateRouterInfoElementByID(
"i2p.router.netdb.activepeers",
"router-netdb-activepeers"
);
UpdateRouterInfoElementByID(
"i2p.router.netdb.fastpeers",
"router-netdb-fastpeers"
);
UpdateRouterInfoElementByID(
"i2p.router.netdb.highcapacitypeers",
"router-netdb-highcapacitypeers"
);
UpdateRouterInfoElementByID(
"i2p.router.netdb.isreseeding",
"router-netdb-isreseeding"
);
UpdateRouterInfoElementByID(
"i2p.router.netdb.knownpeers",
"router-netdb-knownpeers"
);
}
UpdateContents();
/*setInterval(function() {
UpdateContents();
}, 750);*/
//var done = Echo(hello);
//done.then(Done);

View File

@ -1,155 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>I2P Router Information</title>
<link href="home.css" rel="stylesheet" type="text/css">
</head>
<body>
<h1>I2P Router Information</h1>
<ul>
<li>
<div id="label-router-status">
Router Status:
</div>
<div id="router-status">
Replace with Router Status
</div>
</li>
<li>
<div id="label-router-uptime">
Router Uptime(Ms):
</div>
<div id="router-uptime">
Replace with Router Uptime
</div>
</li>
<li>
<div id="label-router-version">
Router Version:
</div>
<div id="router-version">
Replace with Router Version
</div>
</li>
<li>
<ul>
<li>
<div id="label-router-bw-outbound-1s">
Outbound bw 1s:
</div>
<div id="router-net-bw-outbound-1s">
Replace with Router Bandwidth Outbound 1s
</div>
</li>
<li>
<div id="label-router-bw-outbound-15s">
Outbound bw 15s:
</div>
<div id="router-net-bw-outbound-15s">
Replace with Router Bandwidth Outbound 15s
</div>
</li>
<li>
<div id="label-router-bw-inbound-1s">
Inbound bw 1s:
</div>
<div id="router-net-bw-inbound-1s">
Replace with Router Bandwidth Inbound 1s
</div>
</li>
<li>
<div id="label-router-bw-inbound-15s">
Inbound bw 15s:
</div>
<div id="router-net-bw-inbound-15s">
Replace with Router Bandwidth Outbound 15s
</div>
</li>
</ul>
</li>
<!--<li>
<div id="label-router-net-status">Network Status:</div>
<div id="router-net-status">Replace with Router Network Status</div>
</li>-->
<li>
<ul>
<li>
<div id="label-router-net-tunnels-participating">
Participating Tunnels:
</div>
<div id="router-net-tunnels-participating">
Replace with Router Participating Tunnel Count
</div>
</li>
<li>
<div id="label-router-activepeers">
Active Peers:
</div>
<div id="router-netdb-activepeers">
Replace with Router Active Peers
</div>
</li>
<li>
<div id="label-router-netdb-fastpeers">
Fast Peers:
</div>
<div id="router-netdb-fastpeers">
Replace with Router Fast Peers
</div>
</li>
<li>
<div id="label-router-netdb-highcapacitypeers">
High Capacity Peers:
</div>
<div id="router-netdb-highcapacitypeers">
Replace with High Capacity Peers
</div>
</li>
<li>
<div id="label-router-netdb-isreseeding">
Reseed status:
</div>
<div id="router-netdb-isreseeding">
Replace with Router netDB Reseeding Status
</div>
</li>
<li>
<div id="label-router-netdb-knownpeers">
Known Peers:
</div>
<div id="router-netdb-knownpeers">
Replace with Router Known Peers
</div>
</li>
</ul>
</li>
</ul>
<script src="i2pcontrol.js"></script>
</body>
</html>

70
lib/assets.go Normal file

File diff suppressed because one or more lines are too long

201
lib/cors.go Normal file
View File

@ -0,0 +1,201 @@
package toopie
import (
"bufio"
"bytes"
"flag"
"fmt"
"github.com/aybabtme/iocontrol"
"github.com/dustin/go-humanize"
"golang.org/x/net/context"
"io"
"log"
"net"
"net/http"
"runtime"
"strings"
"time"
)
const timeout = time.Second * 5
var (
connIDs = make(chan uint64)
connDone = make(chan uint64)
)
func Listen() net.Listener {
ln, err := net.Listen("tcp", "127.0.0.1:0")
if err != nil {
log.Fatal(err)
}
log.Println(fmt.Sprintf("http://%s", ln.Addr()))
go http.Serve(ln, http.FileServer(FS))
go proxy(fmt.Sprintf("http://%s", ln.Addr()), fmt.Sprintf("localhost:7657"))
return ln
}
func proxy(localAddr, remoteAddr string) string {
var (
lPort = flag.Int("port", 7677, "local port on which the proxy will listen")
)
flag.Parse()
log.SetFlags(0)
log.SetPrefix("portproxy: ")
if remoteAddr == "" {
log.Fatal("need to define a remote address")
}
l, err := net.Listen("tcp", fmt.Sprintf(":%d", *lPort))
if err != nil {
log.Fatalf("couldn't setup listener for proxy: %v", err)
}
defer l.Close()
runtime.GOMAXPROCS(runtime.NumCPU())
ctx, cancel := context.WithCancel(context.Background())
log.Printf("now proxying port %d to %q", *lPort, remoteAddr)
go func() {
i := uint64(1)
var inflight int
for {
select {
case <-ctx.Done():
return
case connIDs <- i:
i++
inflight++
log.SetPrefix(fmt.Sprintf("portproxy: %d conns ", inflight))
log.Printf("[%d] new connection", i)
case id := <-connDone:
inflight--
log.SetPrefix(fmt.Sprintf("portproxy: %d conns ", inflight))
log.Printf("[%d] connection done", id)
}
}
}()
for {
conn, err := l.Accept()
if err != nil {
cancel()
log.Fatalf("failed to accept: %v", err)
}
go func(conn net.Conn) {
buf := bytes.NewBuffer(nil)
brd := bufio.NewReader(io.TeeReader(conn, buf))
if req, err := http.ReadRequest(brd); err == nil {
req.RemoteAddr = remoteAddr
proxyHTTP(ctx, conn, req, localAddr)
} else {
// proxyConn(ctx, conn, buf, remoteAddr)
}
}(conn)
}
}
func proxyHTTP(parent context.Context, lconn net.Conn, req *http.Request, localaddr string) {
defer lconn.Close()
start := time.Now()
id := <-connIDs
defer func() { connDone <- id }()
log.Printf("[%d] highjacking HTTP request!", id)
rconn, err := net.DialTimeout("tcp", req.RemoteAddr, timeout)
if err != nil {
log.Printf("[%d] couldn't dial remote address: %v", id, err)
return
}
defer rconn.Close()
mrd := iocontrol.NewMeasuredReader(rconn)
mwr := iocontrol.NewMeasuredWriter(rconn)
ctx, cancel := context.WithCancel(parent)
defer cancel()
go func() {
tick := time.NewTicker(time.Second)
for {
select {
case <-ctx.Done():
dur := time.Since(start)
log.Printf("[%d] %s\tHTTP\ttx:%s @ %sps\t\trx:%s @ %sps",
id,
dur,
humanize.IBytes(uint64(mwr.Total())),
humanize.IBytes(uint64(mwr.BytesPerSec())),
humanize.IBytes(uint64(mrd.Total())),
humanize.IBytes(uint64(mrd.BytesPerSec())),
)
return
case <-tick.C:
}
dur := time.Since(start)
log.Printf("[%d] %s\tHTTP\ttx:%s @ %sps\t\trx:%s @ %sps",
id,
dur,
humanize.IBytes(uint64(mwr.Total())),
humanize.IBytes(uint64(mwr.BytesPerSec())),
humanize.IBytes(uint64(mrd.Total())),
humanize.IBytes(uint64(mrd.BytesPerSec())),
)
}
}()
if err := req.Write(mwr); err != nil {
log.Printf("[%d] couldn't write HTTP request: %v", id, err)
return
}
resp, err := http.ReadResponse(bufio.NewReader(mrd), req)
if err != nil {
log.Printf("[%d] couldn't read HTTP response: %v", id, err)
return
}
if _, ok := req.Header["Origin"]; ok {
// resp.Header.Set("Access-Control-Allow-Origin", "*")
resp.Header.Set("Access-Control-Allow-Origin", localaddr)
}
if _, ok := req.Header["Origin"]; ok {
resp.Header.Set("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept")
}
if err := resp.Write(lconn); err != nil {
log.Printf("[%d] couldn't write HTTP response back to client: %v", id, err)
return
}
}
func isNormalTerminationError(err error) bool {
if err == nil {
return false
}
if err == io.EOF {
return true
}
e, ok := err.(*net.OpError)
if ok && e.Timeout() {
return true
}
for _, cause := range []string{
"use of closed network connection",
"broken pipe",
"connection reset by peer",
} {
if strings.Contains(err.Error(), cause) {
return true
}
}
return false
}

20
lib/launch.go Normal file
View File

@ -0,0 +1,20 @@
//go:generate go run -tags generate gen.go
package toopie
import (
"fmt"
"github.com/webview/webview"
)
func Launch() {
ln := Listen()
defer ln.Close()
debug := true
w := webview.New(debug)
defer w.Destroy()
w.SetTitle("toopie.html")
w.SetSize(500, 800, webview.HintFixed)
w.Navigate(fmt.Sprintf("http://%s", ln.Addr()))
w.Run()
}

11
main.go Normal file
View File

@ -0,0 +1,11 @@
//go:generate go run -tags generate gen.go
package main
import (
"github.com/eyedeekay/toopie.html/lib"
)
func main() {
toopie.Launch()
}

14
run.go
View File

@ -1,14 +0,0 @@
package main
import (
"log"
"net/http"
)
func main() {
fs := http.FileServer(http.Dir("./"))
http.Handle("/", fs)
log.Println("Listening...")
http.ListenAndServe(":3000", nil)
}

BIN
toopie.html Executable file

Binary file not shown.

55
www/content.js Normal file
View File

@ -0,0 +1,55 @@
function contentUpdateById(id, message) {
let infoTitle = document.getElementById(id);
let messageContent = chrome.i18n.getMessage(message);
if (infoTitle === null) {
console.log('content error', id, messageContent);
return;
}
infoTitle.textContent = messageContent;
}
// Information Section
contentUpdateById('text-section-header', 'extensionName');
contentUpdateById('description', 'extensionDescription');
contentUpdateById('i2pbrowser-version', 'extensionVersion');
contentUpdateById('beta', 'extensionStatus');
contentUpdateById('proxy-check', 'proxyFailedStatus');
// Control Section
contentUpdateById('controlHeader', 'controlHeader');
contentUpdateById('controlExplain', 'controlExplain');
contentUpdateById('clear-browser-data', 'clearData');
contentUpdateById('clear-desc', 'clearDesc');
contentUpdateById('enable-web-rtc', 'enableWebRTC');
contentUpdateById('rtcDesc', 'rtcDesc');
contentUpdateById('disable-history', 'disableHistory');
contentUpdateById('histDesc', 'histDesc');
// Application Section
contentUpdateById('applicationHeader', 'applicationHeader');
contentUpdateById('applicationExplain', 'applicationExplain');
contentUpdateById('window-visit-index', 'windowVisitHelppage');
contentUpdateById('help', 'help');
contentUpdateById('window-visit-router', 'windowVisitConsole');
contentUpdateById('routerConsole', 'routerConsole');
contentUpdateById('window-visit-homepage', 'windowVisitHomepage');
contentUpdateById('abouthome', 'abouthome');
contentUpdateById('window-visit-i2ptunnel', 'windowVisitI2ptunnel');
contentUpdateById('i2ptunnel', 'i2ptunnel');
contentUpdateById('window-visit-susimail', 'windowVisitSusiMail');
contentUpdateById('susimail', 'susimail');
contentUpdateById('window-visit-snark', 'windowVisitSnark');
contentUpdateById('snark', 'snark');
// Homepage Section
contentUpdateById('window-visit-webpage', 'windowVisitWebPage');
contentUpdateById('webpage', 'help');
contentUpdateById('window-visit-sources', 'windowVisitSources');
contentUpdateById('sources', 'sources');
contentUpdateById('window-visit-releases', 'windowVisitReleases');
contentUpdateById('releases', 'releases');
fetch('http://proxy.i2p').then(myJson => {
console.log('FETCH RESULT', myJson);
contentUpdateById('proxy-check', 'proxySuccessStatus');
});

View File

@ -79,8 +79,11 @@ p {
background: #f8f8ff;
min-width: 95%
}
#header,
.application-info,
.extended-info {
.browser-info,
.extended-info,
.search-info {
min-height: 3rem;
padding: 1rem;
margin-top: 1.5rem;
@ -100,7 +103,6 @@ h1 {
color: #41465f;
border: 1px solid #dee2e6;
border-radius: 2px 2px 0 0;
width: 90%;
padding-left: 5%
}
h2,
@ -111,7 +113,6 @@ h3 {
font-size: 25px;
text-transform: uppercase;
color: #41465f;
border: 1px solid #dee2e6;
border-radius: 2px 2px 0 0;
width: 90%;
padding-left: 5%
@ -167,21 +168,23 @@ li {
margin: .5rem .5rem .5rem 32%
}
#readyness {
min-height: 5rem;
padding: .5rem;
margin: .5rem;
padding-top: 1rem;
padding-bottom: 1rem;
margin: 1rem;
width: 42%;
min-width: 42%;
background: #dee2e6;
text-align: center!important;
border: 1px solid #dee2e6;
border-radius: 2px;
box-shadow: inset 0 0 0 1px #fff,0 0 1px #ccc
box-shadow: inset 0 0 0 1px #fff,0 0 1px #ccc;
display: inline-block
}
#onboarding {
min-height: 5rem;
padding: .5rem;
margin: .5rem;
margin-top: 4rem;
width: 42%;
min-width: 42%;
font-size: 2rem;
@ -192,19 +195,16 @@ li {
box-shadow: inset 0 0 0 1px #fff,0 0 1px #ccc
}
#i2pbrowser-description {
padding-top: 1rem;
padding-bottom: 1rem;
width: 50%;
min-width: 50%;
min-height: 5rem;
padding: .5rem;
display: inline;
display: inline-block;
background: #dee2e6;
float: right;
border: 1px solid #dee2e6;
border-radius: 2px;
box-shadow: inset 0 0 0 1px #fff,0 0 1px #ccc
}
#applicationExplain,
#controlExplain,
#linksExplain {
min-height: 5rem;
padding: .5rem;
@ -212,19 +212,32 @@ li {
width: 30%;
min-width: 30%;
background: #dee2e6;
float: left;
text-align: center!important;
border: 1px solid #dee2e6;
border-radius: 2px;
box-shadow: inset 0 0 0 1px #fff,0 0 1px #ccc
}
#applicationExplain,
#controlExplain {
min-height: 5rem;
padding: .5rem;
margin: .5rem;
width: 30%;
min-width: 30%;
background: #dee2e6;
text-align: center!important;
border: 1px solid #dee2e6;
border-radius: 2px;
box-shadow: inset 0 0 0 1px #fff,0 0 1px #ccc;
float: left
}
#proxyReady {
min-height: 3rem;
padding: .5rem;
margin: .2rem;
width: 38%;
min-width: 38%;
display: inline;
display: inline-block;
background: #d9d9d6;
float: right;
text-align: center!important;
@ -238,7 +251,7 @@ li {
margin: .2rem;
width: 38%;
min-width: 38%;
display: inline;
display: inline-block;
float: right;
text-align: center!important;
border: 1px solid #ffc56d;
@ -252,7 +265,7 @@ li {
margin: .2rem;
width: 38%;
min-width: 38%;
display: inline;
display: inline-block;
float: left;
text-align: center!important;
border: 1px solid #f7e59a;

View File

@ -0,0 +1,391 @@
var hello = 'hello i2pcontrol';
function makeid(length) {
var result = '';
var characters =
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
var charactersLength = characters.length;
for (var i = 0; i < length; i++) {
result += characters.charAt(Math.floor(Math.random() * charactersLength));
}
return result;
}
function send(
message,
control_host = "127.0.0.1",
control_port = "7677",
control_path = "jsonrpc"
) {
async function postData(url = "", data = {}) {
// Default options are marked with *
let requestBody = JSON.stringify(data);
//console.log("(i2pcontrol) sending request", requestBody);
let opts = {
method: 'POST', // *GET, POST, PUT, DELETE, etc.
mode: 'cors', // no-cors, *cors, same-origin
cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
credentials: 'same-origin', // include, *same-origin, omit
headers: {
'Content-Type': 'application/json'
},
redirect: 'follow', // manual, *follow, error
referrerPolicy: 'no-referrer', // no-referrer, *client
body: requestBody // body data type must match "Content-Type" header
};
const response = await fetch(url, opts);
return await response.json(); // parses JSON response into native JavaScript objects
}
//console.log("http://" + control_host + ":" + control_port + "/" + control_path)
return postData(
'http://' + control_host + ':' + control_port + '/' + control_path + '/',
message
);
}
async function authenticate(
password = "itoopie",
control_host = "127.0.0.1",
control_port = "7677",
control_path = "jsonrpc"
) {
var json = new Object();
json['id'] = makeid(6);
json['jsonrpc'] = '2.0';
json['method'] = 'Authenticate';
json['params'] = new Object();
json['params']['API'] = 1;
json['params']['Password'] = password;
return send(json, control_host, control_port, control_path);
}
async function GetToken(
password = "itoopie",
control_host = "127.0.0.1",
control_port = "7677",
control_path = "jsonrpc"
) {
function gettoken(authtoken) {
return authtoken.result.Token;
}
let me = authenticate(password, control_host, control_port, control_path);
return await me.then(gettoken);
}
async function Echo(
message,
control_host = "127.0.0.1",
control_port = "7677",
control_path = "jsonrpc",
password = "itoopie"
) {
function echo(token) {
console.log('(i2pcontrol) testing I2PControl connection');
var json = new Object();
json['id'] = makeid(6);
json['jsonrpc'] = '2.0';
json['method'] = 'Echo';
json['params'] = new Object();
json['params']['Token'] = token;
json['params']['Echo'] = message;
return send(json, control_host, control_port, control_path);
}
let token = GetToken(password, control_host, control_port, control_path);
let done = await token.then(echo);
return done;
}
function UpdateEchoElementByID(
Query,
ID,
control_host = "127.0.0.1",
control_port = "7677",
control_path = "jsonrpc"
) {
function updateelement(update) {
//console.log("(i2pcontrol)", update);
if (document.getElementById(ID) !== null)
document.getElementById(ID).innerText = update;
}
let net = Echo(Query, control_host, control_port, control_path, password);
net.then(updateleement);
}
async function GetRate(
Query,
control_host = "127.0.0.1",
control_port = "7677",
control_path = "jsonrpc",
password = "itoopie"
) {
function getrate(token) {
var json = new Object();
json['id'] = makeid(6);
json['jsonrpc'] = '2.0';
json['method'] = 'I2PControl';
json['params'] = new Object();
json['params']['Token'] = token;
json['params']['Stat'] = Query;
json['params']['Period'] = 2000;
return send(json, control_host, control_port, control_path);
}
let token = GetToken(password, control_host, control_port, control_path);
let done = await token.then(getrate);
return done;
}
function UpdateGetRateElementByID(
Query,
ID,
control_host = "127.0.0.1",
control_port = "7677",
control_path = "jsonrpc"
) {
function updateelement(update) {
//console.log("(i2pcontrol)", update);
if (document.getElementById(ID) !== null)
document.getElementById(ID).innerText = update;
}
let net = GetRate(Query, control_host, control_port, control_path, password);
net.then(updateleement);
}
async function I2PControl(
Query,
control_host = "127.0.0.1",
control_port = "7677",
control_path = "jsonrpc",
password = "itoopie"
) {
function i2pcontrol(token) {
var json = new Object();
json['id'] = makeid(6);
json['jsonrpc'] = '2.0';
json['method'] = 'I2PControl';
json['params'] = new Object();
json['params']['Token'] = token;
json['params'][Query] = null;
return send(json, control_host, control_port, control_path);
}
let token = GetToken(password, control_host, control_port, control_path);
let done = await token.then(i2pcontrol);
return done;
}
function UpdateI2PControlElementByID(
Query,
ID,
control_host = "127.0.0.1",
control_port = "7677",
control_path = "jsonrpc"
) {
function updateelement(update) {
//console.log("(i2pcontrol)", update);
if (document.getElementById(ID) !== null)
document.getElementById(ID).innerText = update;
}
let net = I2PControl(
Query,
control_host,
control_port,
control_path,
password
);
net.then(updateleement);
}
async function RouterInfo(
Query,
control_host = "127.0.0.1",
control_port = "7677",
control_path = "jsonrpc",
password = "itoopie"
) {
function routerinfo(token) {
var json = new Object();
json['id'] = makeid(6);
json['jsonrpc'] = '2.0';
json['method'] = 'RouterInfo';
json['params'] = new Object();
json['params']['Token'] = token;
json['params'][Query] = null;
return send(json, control_host, control_port, control_path);
}
let token = GetToken(password, control_host, control_port, control_path);
let done = await token.then(routerinfo);
return done;
}
function UpdateRouterInfoElementByID(
Query,
ID,
control_host = "127.0.0.1",
control_port = "7677",
control_path = "jsonrpc",
password = "itoopie"
) {
function updateelement(update) {
/*console.log(
"(i2pcontrol) element",
update.result[Query],
ID,
document.getElementById(ID)
);*/
if (document.getElementById(ID) !== null)
document.getElementById(ID).innerText = update.result[Query];
}
let net = RouterInfo(
Query,
control_host,
control_port,
control_path,
password
);
net.then(updateelement);
}
async function RouterManager(
Query,
control_host = "127.0.0.1",
control_port = "7677",
control_path = "jsonrpc",
password = "itoopie"
) {
function routermanager(token) {
var json = new Object();
json['id'] = makeid(6);
json['jsonrpc'] = '2.0';
json['method'] = 'RouterManager';
json['params'] = new Object();
json['params']['Token'] = token;
json['params'][Query] = null;
return send(json, control_host, control_port, control_path);
}
let token = GetToken(password, control_host, control_port, control_path);
let done = await token.then(routermanager);
return done;
}
function UpdateRouterManagerElementByID(
Query,
ID,
control_host = "127.0.0.1",
control_port = "7677",
control_path = "jsonrpc",
password = "itoopie"
) {
function updateelement(update) {
//console.log("(i2pcontrol)", update);
if (document.getElementById(ID) !== null)
document.getElementById(ID).innerText = update;
}
let net = RouterManager(
Query,
control_host,
control_port,
control_path,
password
);
net.then(updateleement);
}
async function NetworkSetting(
Query,
control_host = "127.0.0.1",
control_port = "7677",
control_path = "jsonrpc",
password = "itoopie"
) {
function networksetting(token) {
var json = new Object();
json['id'] = makeid(6);
json['jsonrpc'] = '2.0';
json['method'] = 'NetworkSetting';
json['params'] = new Object();
json['params']['Token'] = token;
json['params'][Query] = null;
return send(json, control_host, control_port, control_path);
}
let token = GetToken(password, control_host, control_port, control_path);
let done = await token.then(networksetting);
return done;
}
function UpdateNetworkSettingElementByID(
Query,
ID,
control_host = "127.0.0.1",
control_port = "7677",
control_path = "jsonrpc",
password = "itoopie"
) {
function updateelement(update) {
//console.log("(i2pcontrol)", update);
document.getElementById(ID).innerText = update;
}
let net = NetworkSetting(
Query,
control_host,
control_port,
control_path,
password
);
net.then(updateleement);
}
function UpdateContents() {
UpdateRouterInfoElementByID('i2p.router.status', 'router-status');
UpdateRouterInfoElementByID('i2p.router.uptime', 'router-uptime');
UpdateRouterInfoElementByID('i2p.router.version', 'router-version');
UpdateRouterInfoElementByID(
'i2p.router.net.bw.inbound.1s',
'router-net-bw-inbound-1s'
);
UpdateRouterInfoElementByID(
'i2p.router.net.bw.inbound.15s',
'router-net-bw-inbound-15s'
);
UpdateRouterInfoElementByID(
'i2p.router.net.bw.outbound.1s',
'router-net-bw-outbound-1s'
);
UpdateRouterInfoElementByID(
'i2p.router.net.bw.outbound.15s',
'router-net-bw-outbound-15s'
);
UpdateRouterInfoElementByID('i2p.router.net.status', 'router-net-status');
UpdateRouterInfoElementByID(
'i2p.router.net.tunnels.participating',
'router-net-tunnels-participating'
);
UpdateRouterInfoElementByID(
'i2p.router.netdb.activepeers',
'router-netdb-activepeers'
);
UpdateRouterInfoElementByID(
'i2p.router.netdb.fastpeers',
'router-netdb-fastpeers'
);
UpdateRouterInfoElementByID(
'i2p.router.netdb.highcapacitypeers',
'router-netdb-highcapacitypeers'
);
UpdateRouterInfoElementByID(
'i2p.router.netdb.isreseeding',
'router-netdb-isreseeding'
);
UpdateRouterInfoElementByID(
'i2p.router.netdb.knownpeers',
'router-netdb-knownpeers'
);
}
var done = Echo(hello);
done.then(Done);
function Done(output) {
console.log('(i2pcontrol) I2PControl connection tested,', output);
return output;
}

62
www/index.html Normal file
View File

@ -0,0 +1,62 @@
<!DOCTYPE html>
<html>
<head>
<title>I2P Router Information</title>
<link href="home.css" rel="stylesheet" type="text/css">
<link href="sidebar.css" rel="stylesheet" type="text/css">
</head>
<body>
<h1>I2P Router Information</h1>
<ul>
<li><button id="label-router-restart" target="_blank">Restart: <span id="router-restart">Gracefully restart router</span></button>
</li>
<li><button id="label-router-shutdown" target="_blank">Shutdown: <span id="router-shutdown">Gracefully shutdown router</span></button>
</li>
</ul>
<ul>
<li><span id="label-router-status">Router Status:</span> <span id="router-status">Replace with Router Status</span></li>
<li><span id="label-router-uptime">Router Uptime(Ms):</span> <span id="router-uptime">Replace with Router Uptime</span></li>
<li><span id="label-router-version">Router Version:</span> <span id="router-version">Replace with Router Version</span></li>
<li>
<ul>
<li><span id="label-router-bw-outbound-1s">Outbound bw 1s:</span> <span id="router-net-bw-outbound-1s">Replace with Router Bandwidth Outbound 1s</span></li>
<li><span id="label-router-bw-outbound-15s">Outbound bw 15s:</span> <span id="router-net-bw-outbound-15s">Replace with Router Bandwidth Outbound 15s</span></li>
<li><span id="label-router-bw-inbound-1s">Inbound bw 1s:</span> <span id="router-net-bw-inbound-1s">Replace with Router Bandwidth Inbound 1s</span></li>
<li><span id="label-router-bw-inbound-15s">Inbound bw 15s:</span> <span id="router-net-bw-inbound-15s">Replace with Router Bandwidth Outbound 15s</span></li>
</ul>
</li>
<!--<li>
<span id="label-router-net-status">Network Status:</span>
<span id="router-net-status">Replace with Router Network Status</span>
</li>-->
<li>
<ul>
<li><span id="label-router-net-tunnels-participating">Participating Tunnels:</span> <span id="router-net-tunnels-participating">Replace with Router Participating Tunnel Count</span></li>
<li><span id="label-router-activepeers">Active Peers:</span> <span id="router-netdb-activepeers">Replace with Router Active Peers</span></li>
<li><span id="label-router-netdb-fastpeers">Fast Peers:</span> <span id="router-netdb-fastpeers">Replace with Router Fast Peers</span></li>
<li><span id="label-router-netdb-highcapacitypeers">High Capacity Peers:</span> <span id="router-netdb-highcapacitypeers">Replace with High Capacity Peers</span></li>
<li><span id="label-router-netdb-isreseeding">Reseed status:</span> <span id="router-netdb-isreseeding">Replace with Router netDB Reseeding Status</span></li>
<li><span id="label-router-netdb-knownpeers">Known Peers:</span> <span id="router-netdb-knownpeers">Replace with Router Known Peers</span></li>
</ul>
</li>
</ul>
<script src="i2pcontrol/i2pcontrol.js"></script>
<script src="input-info.js"></script>
<script src="content.js"></script>
</body>
</html>

100
www/input-info.js Normal file
View File

@ -0,0 +1,100 @@
document.addEventListener("click", clickEvent => {
if (clickEvent.target.id === "window-create-help-panel") {
let createData = {
type: "panel",
incognito: true
};
let creating = browser.tabs.create(createData);
creating.then(() => {
console.log("The help panel has been created");
});
} else if (clickEvent.target.id === "window-create-news-panel") {
let createData = {
type: "panel",
incognito: true
};
let creating = browser.tabs.create(createData);
creating.then(() => {
console.log("The news panel has been created");
});
} else if (clickEvent.target.id === "generate-fresh-tunnel") {
function refreshIdentity() {
console.log("Generating new identity");
const Http = new XMLHttpRequest();
const url = "http://" + controlHost + ":" + controlPort;
Http.open("GET", url);
Http.send();
Http.onreadystatechange = event => {
console.log(Http.responseText);
};
}
refreshIdentity();
} else if (clickEvent.target.id === "label-router-restart") {
console.log("attempting to initiate graceful restart");
RouterManager("RestartGraceful");
} else if (clickEvent.target.id === "label-router-shutdown") {
console.log("attempting to initiate graceful shutdown");
RouterManager("ShutdownGraceful");
} else if (clickEvent.target.id === "search-submit") {
console.log("attempting to create search tab");
goSearch();
} else if (clickEvent.target.id === "browser-action") {
console.log("showing a browser action");
showBrowsing();
} else if (clickEvent.target.id === "torrent-action") {
console.log("showing a torrent action");
showTorrentsMenu();
} else if (clickEvent.target.id === "window-preface-title") {
console.log("attempting to create homepage tab");
goHome();
} else if (clickEvent.target.id === "window-visit-index") {
console.log("attempting to create index tab");
goIndex();
} else if (clickEvent.target.id === "window-visit-homepage") {
console.log("attempting to create homepage tab");
goHome();
} else if (clickEvent.target.id === "window-visit-toopie") {
console.log("attempting to create toopie tab");
goToopie();
} else if (clickEvent.target.id === "window-visit-i2ptunnel") {
console.log("attempting to create i2ptunnel tab");
goTunnel();
} else if (clickEvent.target.id === "window-visit-susimail") {
console.log("attempting to create susimail tab");
goMail();
} else if (clickEvent.target.id === "window-visit-snark") {
console.log("attempting to create snark tab");
goSnark();
} else if (clickEvent.target.id === "clear-browser-data") {
forgetBrowsingData();
} else if (clickEvent.target.id === "check-i2p-control") {
//echo("I2P Router Detected", "panel-section-i2pcontrol-check");
} else if (clickEvent.target.id === "enable-web-rtc") {
if (clickEvent.target.checked) {
browser.runtime.sendMessage({ rtc: "enableWebRTC" });
} else {
browser.runtime.sendMessage({ rtc: "disableWebRTC" });
}
checkPeerConnection();
return;
} else if (clickEvent.target.id === "disable-history") {
if (clickEvent.target.checked) {
browser.runtime.sendMessage({ history: "disableHistory" });
} else {
browser.runtime.sendMessage({ history: "enableHistory" });
}
return;
}
clickEvent.preventDefault();
});
if (UpdateContents !== undefined) UpdateContents();
const minutes = 0.2;
const interval = minutes * 60 * 1000;
setInterval(function() {
if (UpdateContents !== undefined) UpdateContents();
}, interval);

7
www/sidebar.css Normal file
View File

@ -0,0 +1,7 @@
li {
width: 90%;
margin-left: 0
}
#applicationExplain {
float: unset
}