47 Commits
0.3.1 ... 0.3.8

Author SHA1 Message Date
a6d97dc00a version bump 2019-11-03 00:42:12 +01:00
92a908907b A lot of bugfixing around the initial dialog and portchecking of the i2p console 2019-11-01 22:02:41 +01:00
b40d5578f8 Fixes noscript issue 2019-10-27 13:44:01 +01:00
199f3b839e Add services 2019-10-27 13:32:53 +01:00
dbf0d53e5c Make the progress dialog show until console is up 2019-10-27 13:31:47 +01:00
00f3ac2afb Adding waitForPortToOpen function 2019-10-27 13:25:43 +01:00
32bb96b18e Adding reseed and restart methods 2019-10-27 12:55:23 +01:00
52c3c6a6c2 Merge remote-tracking branch 'upstream/master' 2019-10-27 12:53:54 +01:00
301bcf6d33 Adding json rpc client for use with i2p control 2019-10-27 12:49:02 +01:00
b52f7f7510 Merge pull request #3 from eyedeekay/master
Minor tweak to the about:i2p display
2019-10-18 10:18:58 +02:00
idk
116f787d25 Minor tweak to the about:i2p display 2019-09-16 13:02:14 -04:00
abc0ce454f Re-adding temporary fix for jetty 2019-09-15 18:25:57 +02:00
b90ed676fd version bump 2019-09-14 23:04:28 +02:00
91b0d0500e Update port numbers 2019-09-14 23:03:41 +02:00
1cafe3fd25 version bump 2019-09-13 12:07:12 +02:00
3a1ce635b1 Adding missing functions 2019-09-12 22:59:05 +02:00
506f675664 Adding missing functions 2019-09-12 22:58:42 +02:00
822fd90f6d function for listing addons 2019-09-12 22:58:16 +02:00
953da8a8e2 Added missing functions etc 2019-09-12 22:50:10 +02:00
ee146800ee Integration with the delay dialog 2019-09-12 22:49:23 +02:00
8ef76f4ebb Added progress dialog aka delay the user dialog 2019-09-12 22:48:07 +02:00
348846f5d3 Misc refactoring and fixes 2019-09-11 22:29:21 +02:00
e42e60276b Refactor away some duplicated code 2019-09-11 22:28:41 +02:00
235bbda10b Bugfixes, cleanup and improvements for the launcher part of the code 2019-09-11 00:04:59 +02:00
ced728b0f4 Functions for reading the router log files 2019-09-10 22:03:22 +02:00
015fa2166b version bump 2019-09-10 22:02:58 +02:00
637ff45592 Misc 2019-09-10 17:45:01 +02:00
78959d60c7 Use the subprocess as indicator for console 2019-09-10 17:44:40 +02:00
00283bde24 Write webapps.config as well 2019-09-10 07:15:57 +02:00
2c0666dcf2 Router config: routerconsole.welcomeWizardComplete=true 2019-09-10 05:56:47 +02:00
b06dded801 Router config: router.startup.jetty9.migrated=true 2019-09-10 05:53:53 +02:00
4bed82f527 Use different i2cp port 2019-09-10 05:52:26 +02:00
ed36de6cae Merge branch 'master' of github.com:mikalv/i2pbutton 2019-09-10 01:04:28 +02:00
676c2348d8 Use more secure permissions 2019-09-10 01:03:34 +02:00
e7d888c776 Merge pull request #2 from eyedeekay/master
Fix links on about:i2p to correspond to i2p browser router console
2019-09-09 05:12:25 +02:00
idk
6adb55d048 correct the links on the about:i2p page and direct new users to the router console for now 2019-09-08 22:56:36 -04:00
idk
4a680de5a2 Merge branch 'master' of https://github.com/mikalv/i2pbutton 2019-09-08 22:08:07 -04:00
79a32618f8 version bump 2019-09-09 03:16:54 +02:00
8d249f4831 omfg 2019-09-09 03:16:23 +02:00
67ed95fc25 version bump 2019-09-09 03:01:08 +02:00
5b6504a11d Temporary jetty fix 2019-09-09 02:54:05 +02:00
832c79f4b5 Make webapps, docs and hosts.txt get copied to config directory when it don't exists 2019-09-09 02:47:16 +02:00
988047ec4e Correct /tunnel/clients/ 2019-09-09 01:39:45 +02:00
6fa1736321 version bump 2019-09-09 01:05:14 +02:00
890438ffe9 Fixed a issue with launching router on osx 2019-09-09 01:04:56 +02:00
ebf6f2577a Use self to avoid error 2019-09-09 00:48:19 +02:00
idk
c19ea1d76c Merge branch 'master' of https://github.com/mikalv/i2pbutton 2019-09-06 13:25:41 -04:00
23 changed files with 1090 additions and 175 deletions

View File

@ -99,7 +99,7 @@ var AboutI2pListener = {
onLocaleChange: function(aLocale) {
// Display the Tor Browser product name and version.
// Display the I2P Browser product name and version.
try {
const kBrandBundle = "chrome://branding/locale/brand.properties";
let brandBundle = Cc["@mozilla.org/intl/stringbundle;1"]

View File

@ -34,8 +34,11 @@ window.addEventListener("pageshow", function() {
<div class='section-header'>
<h1>&aboutI2p.browser_name;</h1>
</div>
<div id="i2pbrowser-version"></div>
<p>
&aboutI2p.browser_name; ( &aboutI2p.browser_short_name; ) &aboutI2p.browser_description;
&aboutI2p.browser_name; ( &aboutI2p.browser_short_name; ) &aboutI2p.browser_description; <br />
&aboutI2p.startup; <a href="&aboutI2p.routerconsole;">&aboutI2p.rc;</a> &aboutI2p.startup_b;
<h3>&aboutI2p.links;</h3>
<p>
<ul>
@ -50,8 +53,8 @@ window.addEventListener("pageshow", function() {
&aboutI2p.warn_experimental;
</p>
<p class="hideIfI2POn">&aboutI2p.warn_not_running; <a href="about:i2p">&aboutI2p.refresh_text;</a> &aboutI2p.reccommend_not_running;</p>
<p class="hideIfI2POff">&aboutI2p.all_checks_ok;</p>
<!--<p class="hideIfI2POn">&aboutI2p.warn_not_running; <a href="about:i2p">&aboutI2p.refresh_text;</a> &aboutI2p.reccommend_not_running;</p>-->
<p class="hideIfI2PConsoleOff">&aboutI2p.all_checks_ok;</p>
<p class="hideIfI2PConsoleOff">
<ul>
<li>&aboutI2p.i2ptunnel_visit_msg; <a href="&aboutI2p.routerconsole;/i2ptunnelmgr">&aboutI2p.i2ptunnel;</a></li>

View File

@ -21,6 +21,7 @@ var m_ib_window_height = window.outerHeight
var m_ib_window_width = window.outerWidth
let checkSvc = Cc["@geti2p.net/i2pbutton-i2pCheckService;1"].getService(Ci.nsISupports).wrappedJSObject
let routerCtrl = Cc["@geti2p.net/i2pbutton-process-service;1"].getService(Ci.nsISupports).wrappedJSObject
function checkI2P(callback,proxyCallback) {
let req = checkSvc.createCheckConsoleRequest(true);
@ -50,10 +51,40 @@ function i2pbutton_i2p_check_ok()
// It's important to check both if failed and if it's initialised to not report wrong to the end user
return (checkSvc.isConsoleWorking && checkSvc.isProxyWorking && checkSvc.kCheckNotInitiated != checkSvc.statusOfI2PCheck)
}
function i2pbutton_i2p_console_check_ok()
function i2pbutton_i2p_console_check_ok() {
// This check will now test if the router subprocess is running
if (routerCtrl.mI2PProcess != null) {
if (routerCtrl.mI2PProcess.isRunning) {
return true
}
}
return false
}
var i2pbutton_window_pref_observer =
{
// It's important to check both if failed and if it's initialised to not report wrong to the end user
return (checkSvc.isConsoleWorking && checkSvc.kCheckNotInitiated != checkSvc.statusOfI2PCheck)
register: function()
{
m_ib_prefs.addObserver("extensions.i2pbutton", this, false);
},
unregister: function()
{
m_ib_prefs.removeObserver("extensions.i2pbutton", this);
},
// topic: what event occurred
// subject: what nsIPrefBranch we're observing
// data: which pref has been changed (relative to subject)
observe: function(subject, topic, data)
{
if (topic != "nsPref:changed") return;
switch (data) {
case k_ib_browser_update_needed_pref:
torbutton_notify_if_update_needed();
break;
}
}
}
var i2pbutton_unique_pref_observer =
@ -195,14 +226,82 @@ function i2pbutton_is_mobile() {
return false;
}
function i2pbutton_update_is_needed() {
var updateNeeded = false
try {
updateNeeded = m_ib_prefs.getBoolPref(k_ib_browser_update_needed_pref)
} catch (e) {}
return updateNeeded
}
function i2pbutton_notify_if_update_needed() {
function setOrClearAttribute(aElement, aAttrName, aValue)
{
if (!aElement || !aAttrName)
return
if (aValue)
aElement.setAttribute(aAttrName, aValue)
else
aElement.removeAttribute(aAttrName)
}
let updateNeeded = i2pbutton_update_is_needed()
// Change look of toolbar item (enable/disable animated update icon).
var btn = i2pbutton_get_toolbutton()
setOrClearAttribute(btn, "ibUpdateNeeded", updateNeeded)
// Make the "check for update" menu item bold if an update is needed.
var item = document.getElementById("i2pbutton-checkForUpdate")
setOrClearAttribute(item, "ibUpdateNeeded", updateNeeded)
}
function i2pbutton_check_for_update() {
// Open the update prompt in the correct mode. The update state
// checks used here were adapted from isPending() and isApplied() in
// Mozilla's browser/base/content/aboutDialog.js code.
let updateMgr = Cc["@mozilla.org/updates/update-manager;1"]
.getService(Ci.nsIUpdateManager)
let update = updateMgr.activeUpdate
let updateState = (update) ? update.state : undefined
let pendingStates = [ "pending", "pending-service",
"applied", "applied-service" ]
let isPending = (updateState && (pendingStates.indexOf(updateState) >= 0))
let prompter = Cc["@mozilla.org/updates/update-prompt;1"]
.createInstance(Ci.nsIUpdatePrompt)
if (isPending)
prompter.showUpdateDownloaded(update, false)
else
prompter.checkForUpdates()
}
function i2pbutton_get_toolbutton() {
var o_toolbutton = false;
i2pbutton_log(1, 'get_toolbutton(): looking for button element');
if (document.getElementById("i2pbutton-button")) {
o_toolbutton = document.getElementById("i2pbutton-button");
} else if (document.getElementById("i2pbutton-button-ib")) {
o_toolbutton = document.getElementById("i2pbutton-button-ib");
} else if (document.getElementById("i2pbutton-button-ib-msg")) {
o_toolbutton = document.getElementById("i2pbutton-button-ib-msg");
} else {
i2pbutton_log(3, 'get_toolbutton(): did not find i2pbutton-button');
}
return o_toolbutton;
}
// This function closes all XUL browser windows except this one. For this
// window, it closes all existing tabs and creates one about:blank tab.
function i2pbutton_close_tabs_on_new_identity() {
if (!m_ib_prefs.getBoolPref("extensions.i2pbutton.close_newnym", true)) {
i2pbutton_log(3, "Not closing tabs");
return;
i2pbutton_log(3, "Not closing tabs")
return
}
// TODO: muck around with browser.tabs.warnOnClose.. maybe..
@ -450,6 +549,28 @@ function i2pbutton_new_identity() {
}
}
/* The "New Identity" implementation does the following:
* 1. Disables Javascript and plugins on all tabs
* 2. Clears state:
* a. OCSP
* b. Cache + image cache
* c. Site-specific zoom
* d. Cookies+DOM Storage+safe browsing key
* e. google wifi geolocation token
* f. http auth
* g. SSL Session IDs
* h. last open location url
* i. clear content prefs
* j. permissions
* k. site security settings (e.g. HSTS)
* l. IndexedDB and asmjscache storage
* 3. Sends tor the NEWNYM signal to get a new circuit
* 4. Opens a new window with the default homepage
* 5. Closes this window
*
* XXX: intermediate SSL certificates are not cleared.
*/
function i2pbutton_do_new_identity() {
var obsSvc = Components.classes["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
// This is todo.
@ -1000,7 +1121,7 @@ var i2pbutton_resizelistener =
// in XUL that should be in an XPCOM component
function i2pbutton_close_window(event) {
i2pbutton_window_pref_observer.unregister();
i2pbutton_tor_check_observer.unregister();
i2pbutton_i2p_check_observer.unregister();
window.removeEventListener("sizemodechange", m_ib_resize_handler,
false);

View File

@ -12,6 +12,8 @@ function i2pbutton_log(nLevel, sMsg) {
return true;
}
function i2pbutton_init_security_ui() {}
// get a preferences branch object
// FIXME: this is lame.
function i2pbutton_get_prefbranch(branch_name) {

View File

@ -20,18 +20,17 @@
accesskey="&i2pbutton.context_menu.new_identity_key;"
insertafter="context-stop"
oncommand="i2pbutton_new_identity()"/>
<menuseparator/>
<menuitem id="i2pbutton-cookie-protector"
label="&i2pbutton.context_menu.cookieProtections;"
accesskey="&i2pbutton.context_menu.cookieProtections.key;"
insertafter="context-stop"
insertafter="i2pbutton-new-identity"
hidden="true"
oncommand="i2pbutton_open_cookie_dialog()"/>
<menuseparator id="i2pbutton-checkForUpdateSeparator"/>
<menuitem id="i2pbutton-checkForUpdate"
label="&i2pbutton.context_menu.downloadUpdate;"
accesskey="&i2pbutton.context_menu.downloadUpdate.key;"
insertafter="context-stop"
insertafter="i2pbutton-cookie-protector"
oncommand="i2pbutton_check_for_update()"/>
</vbox>
</hbox>

View File

@ -0,0 +1,216 @@
const Cc = Components.classes
const Ci = Components.interfaces
const Cu = Components.utils
const kI2PProcessExitedTopic = "I2PProcessExited"
const kBootstrapStatusTopic = "I2PBootstrapStatus"
const kI2PBootstrapErrorTopic = "I2PBootstrapError"
const kI2PLogHasWarnOrErrTopic = "I2PLogHasWarnOrErr"
Cu.import("resource://gre/modules/Services.jsm")
Cu.import("resource://gre/modules/XPCOMUtils.jsm")
XPCOMUtils.defineLazyModuleGetter(this, "LauncherUtil", "resource://i2pbutton/modules/launcher-util.jsm")
const I2PLauncherLogger = Cc["@geti2p.net/i2pbutton-logger;1"].getService(Ci.nsISupports).wrappedJSObject
var gObsSvc
var gOpenerCallbackFunc // Set when opened from network settings.
var gIsInitialBootstrap
var gInitialPanelID
function closeThisWindow(reason) {
dump('closeThisWindow\n')
window.close()
}
function initDialog()
{
// If i2p bootstrap has already finished, just close the progress dialog.
// This situation can occur if bootstrapping is very fast and/or if this
// window opens s vlowly (observed with Adblock Plus installed).
try
{
let processSvc = Cc["@geti2p.net/i2pbutton-process-service;1"].getService(Ci.nsISupports).wrappedJSObject
if (processSvc.I2PIsBootstrapDone || processSvc.I2PBootstrapErrorOccurred)
{
closeThisWindow(processSvc.I2PIsBootstrapDone)
return
}
}
catch (e) { dump(`${e}\n`) }
try
{
gObsSvc = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService)
gObsSvc.addObserver(gObserver, kI2PProcessExitedTopic, false)
gObsSvc.addObserver(gObserver, kBootstrapStatusTopic, false)
gObsSvc.addObserver(gObserver, kI2PBootstrapErrorTopic, false)
gObsSvc.addObserver(gObserver, kI2PLogHasWarnOrErrTopic, false)
var isBrowserStartup = false
if (window.arguments)
{
let wargs = window.arguments || window.arguments.wrappedJSObject
isBrowserStartup = wargs[0]
dump(`window.arguments = ${wargs}\n`)
dump(`window.arguments.length = ${wargs.length}\n`)
if (window.arguments.length > 1)
gInitialPanelID = window.arguments[1]
}
if (gOpenerCallbackFunc)
{
// Dialog was opened from network settings: hide Open Settings button.
var extraBtn = document.documentElement.getButton("extra2")
extraBtn.setAttribute("hidden", true)
}
else
{
// Dialog was not opened from network settings: change Cancel to Quit.
var cancelBtn = document.documentElement.getButton("cancel")
var quitKey = (LauncherUtil.isWindows) ? "quit_win" : "quit"
cancelBtn.label = 'Cancel'//LauncherUtil.getLocalizedString(quitKey)
}
// If opened during browser startup, display the "please wait" message.
if (isBrowserStartup)
{
var pleaseWait = document.getElementById("progressPleaseWait")
if (pleaseWait)
pleaseWait.removeAttribute("hidden")
}
// Test if the i2p console port is open or not
let consolePort = Services.prefs.getIntPref("extensions.i2pbutton.console_port_i2pj", 7647)
LauncherUtil.waitForPortToOpen(consolePort, () => {
var meter = document.getElementById("progressMeter")
if (meter) {
meter.value = meter.value + 30
}
setTimeout(() => {
window.close()
}, 5000)
})
}
catch (e) {
dump(`Error: ${e}\n`)
}
dump('initDialog done\n')
}
function onCancel() {
//
dump('onCancel\n')
cleanup()
}
function cleanup()
{
if (gObsSvc)
{
gObsSvc.removeObserver(gObserver, kI2PProcessExitedTopic)
gObsSvc.removeObserver(gObserver, kBootstrapStatusTopic)
gObsSvc.removeObserver(gObserver, kI2PBootstrapErrorTopic)
gObsSvc.removeObserver(gObserver, kI2PLogHasWarnOrErrTopic)
}
}
function onOpenSettings()
{
//stopI2PBootstrap()
//cleanup()
window.close()
}
function stopI2PBootstrap()
{
// Tell i2p to disable use of the network; this should stop the bootstrap
// process.
const kErrorPrefix = "Setting DisableNetwork=1 failed: ";
try
{
var settings = {};
settings["DisableNetwork"] = true;
var errObj = {};
I2PLauncherLogger.log(5, kErrorPrefix + errObj.details);
}
catch(e)
{
I2PLauncherLogger.log(5, kErrorPrefix + e);
}
}
var gObserver = {
// nsIObserver implementation.
observe: function(aSubject, aTopic, aParam)
{
if ((kI2PProcessExitedTopic == aTopic) ||
(kI2PBootstrapErrorTopic == aTopic))
{
// In these cases, an error alert will be displayed elsewhere so it is
// best to close this window.
// TODO: provide a way to access tor log e.g., leave this dialog open
// and display the open settings button or provide a way to do
// that from our error alerts.
if (kI2PBootstrapErrorTopic == aTopic)
stopI2PBootstrap();
cleanup();
window.close();
}
else if (kBootstrapStatusTopic == aTopic)
{
var statusObj = aSubject.wrappedJSObject
var labelText = LauncherUtil.getLocalizedBootstrapStatus(statusObj, "TAG")
var percentComplete = (statusObj.PROGRESS) ? statusObj.PROGRESS : 0
var meter = document.getElementById("progressMeter")
if (meter)
meter.value = percentComplete
var bootstrapDidComplete = (percentComplete >= 100)
if (percentComplete >= 100)
{
// To ensure that 100% progress is displayed, wait a short while
// before closing this window.
window.setTimeout(function() { closeThisWindow(true) }, 250)
}
else if (statusObj._errorOccurred)
{
var s = LauncherUtil.getLocalizedBootstrapStatus(statusObj, "REASON");
if (s)
labelText = s;
if (meter)
meter.setAttribute("hidden", true);
var pleaseWait = document.getElementById("progressPleaseWait");
if (pleaseWait)
pleaseWait.setAttribute("hidden", true);
}
var desc = document.getElementById("progressDesc");
if (labelText && desc)
desc.textContent = labelText;
}
else if (kI2PLogHasWarnOrErrTopic == aTopic)
{
var extra2Btn = document.documentElement.getButton("extra2");
var clz = extra2Btn.getAttribute("class");
extra2Btn.setAttribute("class", clz ? clz + " i2pWarning" : "i2pWarning");
// TODO: show error / warning message in this dialog?
}
},
}

View File

@ -0,0 +1,43 @@
<?xml version="1.0"?>
<!--
- Copyright (c) 2019, The Invisible Internet Project.
- See LICENSE for licensing information.
- vim: set sw=2 sts=2 ts=8 et syntax=xml:
-->
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<?xml-stylesheet href="chrome://i2pbutton/skin/progress.css" type="text/css"?>
<!DOCTYPE overlay SYSTEM "chrome://i2pbutton/locale/progress.dtd">
<dialog id="I2PProgress"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
title="&i2pprogress.dialog.title;"
windowtype="I2PLauncher:Progress"
persist="screenX screenY"
buttons="cancel"
buttonlabelextra2="&i2pprogress.openSettings;"
ondialogcancel="onCancel();"
ondialogextra2="onOpenSettings();"
onload="initDialog();"> <!-- extra2 was removed from buttons for now. -->
<script type="application/x-javascript"
src="chrome://i2pbutton/content/progress.js"/>
<vbox>
<hbox>
<vbox>
<spacer flex="1" />
<image id="ibb-icon" />
<spacer flex="1" />
</vbox>
<separator orient="vertical" />
<vbox flex="1">
<label id="progressHeading" value="&i2pprogress.heading;" />
<description id="progressDesc" />
</vbox>
</hbox>
<progressmeter id="progressMeter" mode="determined" value="0" max="100" />
<description id="progressPleaseWait"
hidden="true">&i2pprogress.pleaseWait;</description>
</vbox>
</dialog>

View File

@ -31,6 +31,10 @@
<!ENTITY aboutI2p.refresh_link "Refresh">
<!ENTITY aboutI2p.site "http://i2p-projekt.i2p/en">
<!ENTITY aboutI2p.routerconsole "http://localhost:7657">
<!ENTITY aboutI2p.routerconsole "http://localhost:7647">
<!ENTITY aboutI2p.github "https://github.com/mikalv">
<!ENTITY aboutI2p.trac "http://trac.i2p2.i2p">
<!ENTITY aboutI2p.startup "Sometimes it takes a minute or two for I2P to get started for the first time. While you wait, visit the">
<!ENTITY aboutI2p.startup_b "to get acquainted with all the capabilities of I2P.">
<!ENTITY aboutI2p.rc "Router Console">

View File

@ -0,0 +1,4 @@
<!ENTITY i2pprogress.dialog.title "Starting the I2P router">
<!ENTITY i2pprogress.openSettings "Settings">
<!ENTITY i2pprogress.heading "I2P Browser">
<!ENTITY i2pprogress.pleaseWait "Please wait while the router establish a connection to the I2P network. This may take several minutes">

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@ -0,0 +1,44 @@
/*
* Copyright (c) 2019, The Invisible Internet Project.
* See LICENSE for licensing information.
*
* vim: set sw=2 sts=2 ts=8 et syntax=css:
*/
dialog {
width: 400px;
}
#progressHeading {
font-size: 110%;
margin: 8px 0px 8px 0px;
font-weight: bold;
}
#progressPleaseWait {
font-size: 110%;
margin-bottom: 15px;
}
#ibb-icon {
list-style-image: url("chrome://i2pbutton/skin/default48.png");
width: 48px;
height: 48px;
}
#progressDesc {
height: 48px;
}
#progressMeter {
margin-bottom: 16px;
}
.i2pWarning {
list-style-image: url("chrome://i2pbutton/skin/warning.png");
}
/* Ensure that our caution icon is always shown on GTK-based platforms. */
.i2pWarning .button-icon {
display: inline !important;
}

BIN
src/chrome/skin/warning.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -35,13 +35,15 @@ IBI2PCheckService.prototype =
isConsoleWorking: false,
isProxyWorking: false,
isInProgressOfTestingConsole: false,
isInProgressOfTestingProxy: false,
wrappedJSObject: null,
_logger: null,
_statusOfI2PCheck: 0, // this.kCheckNotInitiated,
// make this an nsIClassInfo object
flags: Ci.nsIClassInfo.DOM_OBJECT,
// make this an singleton object
flags: Ci.nsIClassInfo.SINGLETON,
// method of nsIClassInfo
classDescription: kMODULE_NAME,
@ -71,17 +73,21 @@ IBI2PCheckService.prototype =
init: function () {
let self = this
this.isInProgressOfTestingConsole = true
let req = this.createCheckConsoleRequest(true)
req.onreadystatechange = function (event) {
if (req.readyState === 4) {
self.parseCheckConsoleResponse(req)
self.isInProgressOfTestingConsole = false
}
}
req.send(null)
this.isInProgressOfTestingProxy = true
let proxyReq = this.createCheckProxyRequest(true)
proxyReq.onreadystatechange = function (event) {
if (proxyReq.readyState === 4) {
self.parseCheckProxyResponse(proxyReq)
self.isInProgressOfTestingConsole = false
}
}
proxyReq.send(null)
@ -100,7 +106,7 @@ IBI2PCheckService.prototype =
createCheckConsoleRequest: function(aAsync)
{
let prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch)
let port = prefs.getIntPref("extensions.i2pbutton.console_port_i2pj", 17657)
let port = prefs.getIntPref("extensions.i2pbutton.console_port_i2pj", 7647)
let url = `http://localhost:${port}/netdb?r=.`
return this._createRequest(url, aAsync, "text/html")
},

View File

@ -8,11 +8,29 @@ const Cu = Components.utils
// ctypes can be disabled at build time
try { Cu.import("resource://gre/modules/ctypes.jsm") } catch(e) {}
Cu.import("resource://gre/modules/XPCOMUtils.jsm")
Cu.import("resource://gre/modules/Services.jsm")
XPCOMUtils.defineLazyModuleGetter(this, "LauncherUtil", "resource://i2pbutton/modules/launcher-util.jsm")
//let observerService = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService)
const timer = Cc["@mozilla.org/timer;1"].createInstance(Components.interfaces.nsITimer)
let routerStateLoglines = [
'Router state change from STARTING_1 to STARTING_2',
'Router state change from STARTING_2 to STARTING_3',
'Router state change from STARTING_3 to NETDB_READY',
'Router state change from NETDB_READY to RUNNING'
]
function setTimeout(fn, sleep) {
let event = {
notify: fn
}
return timer.initWithCallback(event, sleep, Components.interfaces.nsITimer.TYPE_ONE_SHOT)
}
function I2PProcessService()
{
this._logger = Cc["@geti2p.net/i2pbutton-logger;1"].getService(Ci.nsISupports).wrappedJSObject
@ -94,19 +112,49 @@ I2PProcessService.prototype =
const self = this
this._logger.log(3, 'Checking if a console is already up (an router already running)')
this._isConsoleRunning(function(res) {
if (res!=4) {
// Yes, 4 is success
let canStartPromise = this._config_checker.ensure_config()
//this._logger.log(3, 'Checking if a console is already up (an router already running)')
let prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch)
let shouldShowDelayUserDialog = prefs.getBoolPref("extensions.i2pbutton.delay_user_with_dialog", true)
let canStartPromise = self._config_checker.ensure_config()
canStartPromise.then(() => {
self._logger.log(3, 'Starting the router')
self.I2PStartAndControlI2P(true)
})
try {
if (shouldShowDelayUserDialog) {
self.openWaitForRouterDialog()
setTimeout(() => {
let progressmeter = self.mDelayUserDialog.document.getElementById('progressMeter')
progressmeter.value = progressmeter.value + 35
var text = self.mDelayUserDialog.document.getElementById('progressPleaseWait')
text.value = 'Waiting for the router to open the console and proxy port.'
}, 5000)
}
} catch (err) {
self._logger.log(5, `Unknown error while executing delay user dialog: ${err}`)
}
// After the router process is spawned.
/*if (self.mDelayUserDialog) {
setTimeout(() => {
let progressmeter = self.mDelayUserDialog.document.getElementById('progressMeter')
progressmeter.value = progressmeter.value + 35
var text = self.mDelayUserDialog.document.getElementById('progressPleaseWait')
text.value = 'Waiting for the router to open the console and proxy port.'
}, 5000)
}*/
/*this._isConsoleRunning(function(res) {
if (res!=4) {
// Yes, 4 is success
} else {
self._logger.log(3, 'Already found a router, won\'t launch.')
}
})
})*/
}
else if ("quit-application-granted" == aTopic)
{
@ -119,8 +167,8 @@ I2PProcessService.prototype =
let prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch)
let shouldKillRouter = prefs.getBoolPref("extensions.i2pbutton.kill_router_on_exit", true)
if (shouldKillRouter) this.mI2PProcess.kill()
this._logger.log(4, "Disconnecting from i2p process (pid " + this.mI2PProcess.pid + ")");
this.mI2PProcess = null;
this._logger.log(4, "Disconnecting from i2p process (pid " + this.mI2PProcess.pid + ")")
this.mI2PProcess = null
}
}
else if (("process-failed" == aTopic) || ("process-finished" == aTopic))
@ -135,11 +183,11 @@ I2PProcessService.prototype =
this.mI2PProcessStatus = this.kStatusExited;
this.mIsBootstrapDone = false;
this.mObsSvc.notifyObservers(null, "I2PProcessExited", null);
this.mObsSvc.notifyObservers(null, "I2PProcessExited", null)
if (this.mIsQuitting)
{
LauncherUtil.cleanupTempDirectories();
LauncherUtil.cleanupTempDirectories()
}
else
{
@ -147,9 +195,9 @@ I2PProcessService.prototype =
var cancelBtnLabel = "OK";
try
{
const kSysBundleURI = "chrome://global/locale/commonDialogs.properties";
var sysBundle = Cc["@mozilla.org/intl/stringbundle;1"].getService(Ci.nsIStringBundleService).createBundle(kSysBundleURI);
cancelBtnLabel = sysBundle.GetStringFromName(cancelBtnLabel);
const kSysBundleURI = "chrome://global/locale/commonDialogs.properties"
var sysBundle = Cc["@mozilla.org/intl/stringbundle;1"].getService(Ci.nsIStringBundleService).createBundle(kSysBundleURI)
cancelBtnLabel = sysBundle.GetStringFromName(cancelBtnLabel)
} catch(e) {}
this._logger.log(3, 'The router stopped..')
@ -167,9 +215,9 @@ I2PProcessService.prototype =
this.mObsSvc.notifyObservers(null, "I2PProcessIsReady", null)
}
} else if (kBootstrapStatusTopic == aTopic) {
//this._processBootstrapStatus(aSubject.wrappedJSObject);
this._processBootstrapStatus(aSubject.wrappedJSObject)
} else if (kUserQuitTopic == aTopic) {
this.mQuitSoon = true;
this.mQuitSoon = true
}
},
@ -227,6 +275,46 @@ I2PProcessService.prototype =
},
openWaitForRouterDialog: function() {
const self = this
//var win = ww.openWindow(null, "chrome://i2pbutton/content/progress.xul", "wizard", "chrome,dialog=no,modal,centerscreen", {blabla:0})
const ww = Components.classes["@mozilla.org/embedcomp/window-watcher;1"].getService(Components.interfaces.nsIWindowWatcher)
self.mDelayUserDialog = ww.openWindow(
null,
"chrome://i2pbutton/content/progress.xul",
"startingrouter",
"chrome,dialog=no,modal,centerscreen",
[true])
this._logger.log(3, 'After open wait for router dialog')
setTimeout(() => {
let progressmeter = self.mDelayUserDialog.document.getElementById('progressMeter')
progressmeter.value = progressmeter.value + 15
var text = self.mDelayUserDialog.document.getElementById('progressPleaseWait')
text.hidden = false
}, 1000)
return self.mDelayUserDialog
},
getWrapperLog: function() {
let wrapperLogFile = LauncherUtil.dataDirectoryObject
wrapperLogFile.append('I2P')
wrapperLogFile.append('wrapper.log')
return this._getFileAsString(wrapperLogFile)
},
getLogsLogTxt: function() {
let logTxtFile = LauncherUtil.dataDirectoryObject
logTxtFile.append('I2P')
logTxtFile.append('logs')
logTxtFile.append('log-0.txt')
return this._getFileAsString(logTxtFile)
},
retrieveBootstrapStatus: function() {},
I2PStartAndControlI2P: function()
{
this._startI2P()
@ -256,8 +344,22 @@ I2PProcessService.prototype =
mLastI2PWarningPhase: null,
mLastI2PWarningReason: null,
mDefaultPreferencesAreLoaded: false,
mDelayUserDialog: null,
// Private Methods /////////////////////////////////////////////////////////
_resetLogFiles: function() {
let wrapperLogFile = LauncherUtil.dataDirectoryObject
wrapperLogFile.append('I2P')
wrapperLogFile.append('wrapper.log')
if (wrapperLogFile.exists()) wrapperLogFile.remove(false)
let logTxtFile = LauncherUtil.dataDirectoryObject
logTxtFile.append('I2P')
logTxtFile.append('logs')
logTxtFile.append('log-0.txt')
if (logTxtFile.exists()) logTxtFile.remove(false)
},
_startI2P: function()
{
this.mI2PProcessStatus = this.kStatusUnknown;
@ -270,13 +372,13 @@ I2PProcessService.prototype =
try
{
// Ideally, we would cd to the Firefox application directory before
// starting tor (but we don't know how to do that). Instead, we
// rely on the TBB launcher to start Firefox from the right place.
// starting i2p (but we don't know how to do that). Instead, we
// rely on the IBB launcher to start Firefox from the right place.
// Get the I2P data directory first so it is created before we try to
// construct paths to files that will be inside it.
let dataDir = LauncherUtil.getI2PConfigPath(true)
let exeFile = LauncherUtil.getI2PFile("i2p", false)
let exeFile = LauncherUtil.getI2PBinary()
this._logger.log(3, `Datadir => ${dataDir.path}\nExeFile => ${exeFile.path}`)
var detailsKey;
@ -294,13 +396,13 @@ I2PProcessService.prototype =
return;
}
this._resetLogFiles()
let args = LauncherUtil.getRouterDefaultArgs()
// Set an environment variable that points to the I2P data directory.
// This is used by meek-client-torbrowser to find the location for
// the meek browser profile.
let env = Cc["@mozilla.org/process/environment;1"].getService(Ci.nsIEnvironment)
env.set("I2P_BROWSER_I2P_DATA_DIR", dataDir.path)
env.set('I2P_BROWSER_I2P_DATA_DIR', dataDir.path)
// On Windows, prepend the I2P program directory to PATH. This is
// needed so that pluggable transports can find OpenSSL DLLs, etc.
@ -322,7 +424,7 @@ I2PProcessService.prototype =
p.init(exeFile)
for (var i = 0; i < args.length; ++i)
this._logger.log(2, " " + args[i])
this._logger.log(2, ` ${args[i]}`)
// Possible fix for Windows and cmd.exe window spawn.
p.startHidden = true
@ -336,42 +438,90 @@ I2PProcessService.prototype =
{
this.mI2PProcessStatus = this.kStatusExited
//var s = LauncherUtil.getLocalizedString("i2p_failed_to_start");
//this._notifyUserOfError(s, null, this.kI2PProcessDidNotStartTopic);
this._notifyUserOfError('Failed to start the I2P router', null, this.kI2PProcessDidNotStartTopic);
this._logger.log(4, "_startI2P error: ", e)
}
}, // _startI2P()
_isConsoleRunning: function(callback) {
let checkSvc = Cc["@geti2p.net/i2pbutton-i2pCheckService;1"].getService(Ci.nsISupports).wrappedJSObject
let req = checkSvc.createCheckConsoleRequest(true);
let obsSvc = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService)
let req = checkSvc.createCheckConsoleRequest(true)
const self = this
req.onreadystatechange = function(event) {
if (req.readyState === 4) {
// Done
let result = checkSvc.parseCheckConsoleResponse(req)
self.mIsBootstrapDone = true
self.mI2PProcessStatus = self.kStatusRunning
self._processBootstrapStatus({ PROGRESS: 100, message: 'The router has succcessfully started.' })
var statusObj = { bootstrap: 'done', success: true }
statusObj.wrappedJSObject = statusObj
obsSvc.notifyObservers(statusObj, "I2PBootstrapStatus", null)
callback(result)
}
}
req.send(null)
},
_processBootstrapStatus: function(aStatusObj)
{
if (!aStatusObj)
return
if (100 == aStatusObj.PROGRESS)
{
this.mIsBootstrapDone = true
this.mBootstrapErrorOccurred = false
LauncherUtil.setBoolPref(this.kPrefPromptAtStartup, false)
}
else
{
this.mIsBootstrapDone = false
if (aStatusObj._errorOccurred)
{
this.mBootstrapErrorOccurred = true
LauncherUtil.setBoolPref(this.kPrefPromptAtStartup, true)
let phase = LauncherUtil.getLocalizedBootstrapStatus(aStatusObj, "TAG")
let reason = LauncherUtil.getLocalizedBootstrapStatus(aStatusObj, "REASON")
let details = LauncherUtil.getFormattedLocalizedString(
"i2p_bootstrap_failed_details", [phase, reason], 2)
I2PLauncherLogger.log(5, "I2P bootstrap error: [" + aStatusObj.TAG +
"/" + aStatusObj.REASON + "] " + details);
if ((aStatusObj.TAG != this.mLastI2PWarningPhase) ||
(aStatusObj.REASON != this.mLastI2PWarningReason))
{
this.mLastI2PWarningPhase = aStatusObj.TAG
this.mLastI2PWarningReason = aStatusObj.REASON
let msg = LauncherUtil.getLocalizedString("i2p_bootstrap_failed")
this._notifyUserOfError(msg, details, this.kI2PBootstrapErrorTopic)
}
}
}
}, // _processBootstrapStatus()
_controlI2P: function(aIsRunningI2P)
{
try
{
if (aIsRunningI2P)
this._monitorI2PProcessStartup();
this._monitorI2PProcessStartup()
// If the user pressed "Quit" within settings/progress, exit.
if (this.mQuitSoon)
this._quitApp();
this._quitApp()
}
catch (e)
{
this.mI2PProcessStatus = this.kStatusExited;
var s = LauncherUtil.getLocalizedString("i2p_control_failed");
this._notifyUserOfError(s, null, null);
this._logger.log(4, "_controlI2P error: ", e);
this.mI2PProcessStatus = this.kStatusExited
var s = LauncherUtil.getLocalizedString("i2p_control_failed")
this._notifyUserOfError(s, null, null)
this._logger.log(4, "_controlI2P error: ", e)
}
}, // controlI2P()
@ -384,8 +534,8 @@ I2PProcessService.prototype =
this.mI2PProcess.kill()
}
var asSvc = Cc["@mozilla.org/toolkit/app-startup;1"].getService(Ci.nsIAppStartup);
var flags = asSvc.eAttemptQuit;
let asSvc = Cc["@mozilla.org/toolkit/app-startup;1"].getService(Ci.nsIAppStartup);
let flags = asSvc.eAttemptQuit;
asSvc.quit(flags);
}
catch (e)
@ -403,25 +553,25 @@ I2PProcessService.prototype =
_notifyUserOfError: function(aMessage, aDetails, aNotifyTopic)
{
let errorObj = { handled: false, message: aMessage };
let errorObj = { handled: false, message: aMessage }
if (aDetails)
errorObj.details = aDetails;
errorObj.details = aDetails
if (aNotifyTopic)
{
// Give other code an opportunity to handle this error, e.g., if the
// network settings window is open, errors are displayed using an
// overlaid XUL element.
errorObj.wrappedJSObject = errorObj;
this.mObsSvc.notifyObservers(errorObj, aNotifyTopic, null);
errorObj.wrappedJSObject = errorObj
this.mObsSvc.notifyObservers(errorObj, aNotifyTopic, null)
}
if (!errorObj.handled)
{
let msg = aMessage;
let msg = aMessage
if (aDetails)
msg += "\n\n" + aDetails;
I2PLauncherUtil.showAlert(null, msg);
msg += "\n\n" + aDetails
LauncherUtil.showAlert(null, msg)
}
},

View File

@ -11,6 +11,7 @@ const Cu = Components.utils
Cu.import("resource://i2pbutton/modules/default-prefs.js", {}).ensureDefaultPrefs()
Cu.import("resource://gre/modules/Services.jsm")
Cu.import("resource://gre/modules/Log.jsm")
let console = (Cu.import("resource://gre/modules/Console.jsm", {})).console
@ -158,7 +159,7 @@ I2pbuttonLogger.prototype =
true);
} else if (Services.prefs.
getIntPref("extensions.i2plauncher.logmethod", 3) !== 0) {
// If Tor Launcher is not available or its log method is not 0
// If I2P Launcher is not available or its log method is not 0
// then let's reset the dump pref.
Services.prefs.setBoolPref("browser.dom.window.dump.enabled",
false);

View File

@ -22,8 +22,14 @@ Cu.import('resource://gre/modules/FileUtils.jsm')
XPCOMUtils.defineLazyModuleGetter(this, "LauncherUtil", "resource://i2pbutton/modules/launcher-util.jsm")
let consolePort = Services.prefs.getIntPref("extensions.i2pbutton.console_port_i2pj", 17657)
let httpProxyPort = Services.prefs.getIntPref("network.proxy.http_port", 14444)
let consolePort = Services.prefs.getIntPref("extensions.i2pbutton.console_port_i2pj", 7647)
let httpProxyPort = Services.prefs.getIntPref("network.proxy.http_port", 7644)
const defaultWebappsConfig = `# Autogenerated by I2P Browser
webapps.jsonrpc.startOnLoad=true
webapps.routerconsole.startOnLoad=true
webapps.i2ptunnel.startOnLoad=true
`
const defaultProxyTunnels = `# Autogenerated by I2P Browser
tunnel.0.description=HTTP proxy for browsing eepsites and the web
@ -125,8 +131,14 @@ i2p.reseedURL=https://download.xxlspeed.com/,https://i2p.mooo.com/netDb/,https:/
router.outboundPool.quantity=7
router.inboundPool.quantity=7
router.sharePercentage=50
i2cp.hostname=127.0.0.1
i2cp.port=17654
router.startup.jetty9.migrated=true
routerconsole.welcomeWizardComplete=true
`
let noscript = Cu.import("resource://i2pbutton/modules/noscript-control.js")
noscript.initialize()
function RouterConfigManager() {
this.version = '0.1'
@ -149,6 +161,7 @@ RouterConfigManager.prototype = {
mDoesRouterConfigExists: false,
mDoesClientsConfigExists: false,
mDoesTunnelConfigExists: false,
mDoesWebappsConfigExists: false,
mHasChecksStarted: false,
mIsChecksDone: false,
@ -161,23 +174,60 @@ RouterConfigManager.prototype = {
},
_write_router_config: function(configfile,onComplete) {
_write_config: function(configfile, content, onComplete) {
const self = this
LauncherUtil.writeFileWithData(configfile, defaultRouterConfig, file => { onComplete(file) }, (err) => {
this._logger.log(6,`Can't write router config file :( - path was ${configfile.path}`)
LauncherUtil.writeFileWithData(configfile, content, file => { onComplete(file) }, (err) => {
this._logger.log(6,`Can't write config file :( - path was ${configfile.path}, error: ${err}`)
})
},
_write_tunnel_config: function(configfile,onComplete) {
const self = this
LauncherUtil.writeFileWithData(configfile, defaultProxyTunnels, file => { onComplete(file) }, (err) => {
this._logger.log(6,`Can't write tunnel proxy config file :( - path was ${configfile.path}`)
})
copy_recursive: async function(sourceDir, destDir) {
let items = sourceDir.directoryEntries
while (items.hasMoreElements()) {
let item = items.getNext().QueryInterface(Components.interfaces.nsIFile)
if (item.isFile()) {
item.copyTo(destDir, "")
this._logger.log(3, `Copied ${item.path}`)
} else if (item.isDirectory()) {
let newDir = destDir.clone()
newDir.append(item.leafName)
newDir.create(newDir.DIRECTORY_TYPE, 0o700)
this._logger.log(3, `Recursively copying ${item.path}`)
this.copy_recursive(item, newDir)
}
}
},
_write_clients_config: function(configfile,onComplete) {
const self = this
LauncherUtil.writeFileWithData(configfile, defaultClientsConfig, file => { onComplete(file) }, (err) => {
this._logger.log(6,`Can't write clients config file :( - path was ${configfile.path}`)
})
ensure_docs: async function() {
let configDirectory = LauncherUtil.getI2PConfigPath(true)
let destDocsDir = configDirectory.clone()
let distDocsDir = LauncherUtil.getI2PBinary()
distDocsDir = distDocsDir.parent.parent
distDocsDir.append('docs')
destDocsDir.append('docs')
if (!destDocsDir.exists()) {
this.copy_recursive(distDocsDir, destDocsDir)
}
},
ensure_webapps: async function() {
let configDirectory = LauncherUtil.getI2PConfigPath(true)
let destWebappDir = configDirectory.clone()
let distWebppDir = LauncherUtil.getI2PBinary()
distWebppDir = distWebppDir.parent.parent
distWebppDir.append('webapps')
destWebappDir.append('webapps')
if (!destWebappDir.exists()) {
destWebappDir.create(destWebappDir.DIRECTORY_TYPE, 0o700)
let items = distWebppDir.directoryEntries
while (items.hasMoreElements()) {
let item = items.getNext().QueryInterface(Components.interfaces.nsIFile)
if (item.isFile()) {
item.copyTo(destWebappDir, "")
this._logger.log(3, `Copied ${item.path}`)
}
}
}
},
@ -191,6 +241,38 @@ RouterConfigManager.prototype = {
tunnelConfigFile.append('i2ptunnel.config')
let clientsConfigFile = configDirectory.clone()
clientsConfigFile.append('clients.config')
let webappsConfigFile = configDirectory.clone()
webappsConfigFile.append('webapps.config')
let hoststxtFile = configDirectory.clone()
hoststxtFile.append('hosts.txt')
if (!hoststxtFile.exists()) {
let distFile = LauncherUtil.getI2PBinary().parent.parent
distFile.append('hosts.txt')
distFile.copyTo(hoststxtFile.parent, "")
this._logger.log(3, `Copied hosts.txt file`)
}
// Temporary jetty fix
let orgDir = configDirectory.clone()
orgDir.append('org')
if (!orgDir.exists()) {
orgDir.create(orgDir.DIRECTORY_TYPE, 0o700)
orgDir.append('eclipse')
orgDir.create(orgDir.DIRECTORY_TYPE, 0o700)
orgDir.append('jetty')
orgDir.create(orgDir.DIRECTORY_TYPE, 0o700)
orgDir.append('webapp')
orgDir.create(orgDir.DIRECTORY_TYPE, 0o700)
let distJettyFile = LauncherUtil.getI2PBinary().parent.parent
distJettyFile.append('org')
distJettyFile.append('eclipse')
distJettyFile.append('jetty')
distJettyFile.append('webapp')
distJettyFile.append('webdefault.xml')
distJettyFile.copyTo(orgDir, '')
}
// Ensure they exists
const self = this
@ -198,7 +280,7 @@ RouterConfigManager.prototype = {
this.ensureRouterConfigPromise = () => {
return new Promise(resolve => {
if (!routerConfigFile.exists()) {
self._write_router_config(routerConfigFile, file => {
self._write_config(routerConfigFile, defaultRouterConfig, file => {
self.mDoesRouterConfigExists = true
self._logger.log(3, 'Wrote router.config')
if (typeof onCompleteCallback === 'function') onCompleteCallback(file)
@ -215,7 +297,7 @@ RouterConfigManager.prototype = {
this.ensureTunnelConfigPromise = () => {
return new Promise(resolve => {
if (!tunnelConfigFile.exists()) {
self._write_tunnel_config(tunnelConfigFile, tfile => {
self._write_config(tunnelConfigFile, defaultProxyTunnels, tfile => {
self._logger.log(3, 'Wrote i2ptunnel.config')
self.mDoesTunnelConfigExists = true
if (typeof onCompleteCallback === 'function') onCompleteCallback(tfile)
@ -232,7 +314,7 @@ RouterConfigManager.prototype = {
this.ensureClientsConfigPromise = () => {
return new Promise(resolve => {
if (!clientsConfigFile.exists()) {
self._write_tunnel_config(tunnelConfigFile, tfile => {
self._write_config(clientsConfigFile, defaultClientsConfig, tfile => {
self._logger.log(3, 'Wrote clients.config')
self.mDoesClientsConfigExists = true
if (typeof onCompleteCallback === 'function') onCompleteCallback(tfile)
@ -246,12 +328,30 @@ RouterConfigManager.prototype = {
})
}
this.ensureWebappsConfigPromise = () => {
return new Promise(resolve => {
if (!webappsConfigFile.exists()) {
self._write_config(webappsConfigFile, defaultWebappsConfig, tfile => {
self._logger.log(3, 'Wrote webapps.config')
self.mDoesWebappsConfigExists = true
if (typeof onCompleteCallback === 'function') onCompleteCallback(tfile)
resolve(webappsConfigFile)
})
} else {
self._logger.log(3, 'Found webapps.config from earlier')
self.mDoesWebappsConfigExists = true
resolve(null)
}
})
}
// Promises are not done but at least done here.
this.mIsChecksDone = true
return Promise.all([
this.ensureRouterConfigPromise(),
this.ensureTunnelConfigPromise(),
this.ensureClientsConfigPromise(),
this.ensureWebappsConfigPromise(),
])
},
}

View File

@ -73,13 +73,13 @@ StartupObserver.prototype = {
this._prefs.setIntPref("network.proxy.type", 1);
this._prefs.setIntPref("network.proxy.socks_port", 0);
this._prefs.setCharPref("network.proxy.socks", "");
this._prefs.setIntPref("extensions.i2pbutton.console_port_i2pj", 17657);
this._prefs.setIntPref("extensions.i2pbutton.console_port_i2pj", 7647);
this._prefs.setCharPref("network.proxy.http", "127.0.0.1");
this._prefs.setIntPref("network.proxy.http_port", 14444);
this._prefs.setIntPref("network.proxy.http_port", 7644);
this._prefs.setCharPref("network.proxy.ssl", "127.0.0.1");
this._prefs.setIntPref("network.proxy.ssl_port", 14444);
this._prefs.setIntPref("network.proxy.ssl_port", 7644);
this._prefs.setCharPref("network.proxy.ftp", "127.0.0.1");
this._prefs.setIntPref("network.proxy.ftp_port", 14444);
this._prefs.setIntPref("network.proxy.ftp_port", 7644);
this._prefs.setCharPref("network.proxy.no_proxies_on", "localhost, 127.0.0.1");
// Force prefs to be synced to disk

View File

@ -56,7 +56,7 @@ pref("browser.startup.homepage", "chrome://i2pbutton/content/locale/non-localize
pref("extensions.i2pbutton.start_i2p", true);
pref("extensions.i2pbutton.kill_router_on_exit", true);
pref("extensions.i2pbutton.console_host", "127.0.0.1");
pref("extensions.i2pbutton.console_port_i2pj", 17657);
pref("extensions.i2pbutton.console_port_i2pj", 7647);
pref("extensions.i2pbutton.console_port_i2pd", 17070);
// I2P Implementation

View File

@ -6,7 +6,7 @@
<em:name>I2pbutton</em:name>
<em:creator>Meeh, Mikal Villa</em:creator>
<em:id>i2pbutton@geti2p.net</em:id>
<em:version>0.3.1</em:version>
<em:version>0.3.8</em:version>
<em:multiprocessCompatible>true</em:multiprocessCompatible>
<em:homepageURL>https://geti2p.net/en/download/lab</em:homepageURL>
<em:iconURL>chrome://i2pbutton/skin/i2p.png</em:iconURL>

View File

@ -0,0 +1,93 @@
const EXPORTED_SYMBOLS = ['JsonPrcClient']
// vim: set sw=2 sts=2 ts=8 et syntax=javascript:
const Cc = Components.classes
const Ci = Components.interfaces
const Cr = Components.results
const Cu = Components.utils
Cu.import("resource://gre/modules/Services.jsm")
Cu.import("resource://gre/modules/XPCOMUtils.jsm")
Cu.import("resource://gre/modules/Log.jsm")
Cu.import("resource://i2pbutton/modules/http.jsm")
Cu.importGlobalProperties(["XMLHttpRequest"])
var log = Log.repository.getLogger("i2pbutton.jsonrpc-client")
log.level = Log.Level.Debug
// A console appender logs to the browser console.
log.addAppender(new Log.ConsoleAppender(new Log.BasicFormatter()))
class JsonRpcClient {
constructor(url) {
this.serverUrl = url
this.mReqIdSequence = 0
this.responses = new Array()
this.token = ''
}
_createTemplateData(method, params, id) {
this.mReqIdSequence++
return JSON.stringify({
'id': id || this.mReqIdSequence,
'method': method,
'params': params || {},
'jsonrpc': '2.0'
})
}
_onload(method, callback) {
const self = this
return () => {
console.log('done', method)
switch (method) {
case 'Authenticate':
let jData = JSON.parse(self.xhr.response)
let token = jData.result.Token
self.token = token
break
case 'RouterManager':
break
default:
console.log('Unknown method')
}
if('function' === typeof callback) {
callback(self.xhr)
}
self.responses.push(self.xhr.response)
console.log(self.xhr.responseText)
}
}
makeRequest(method, params, callback) {
this.xhr = new XMLHttpRequest()
this.xhr.open('POST', this.serverUrl)
let data = this._createTemplateData(method, params)
this.xhr.onload = this._onload(method, callback)
this.xhr.setRequestHeader('Content-Length', `${data.length}`)
this.xhr.setRequestHeader('Content-Type', 'application/json')
this.xhr.send(data)
}
}
class I2PControlClient extends JsonRpcClient {
constructor() {
super('http://127.0.0.1:7647/jsonrpc/')
}
authenticate(password, callback) {
this.makeRequest('Authenticate', {'API':1, 'Password':password}, callback)
}
shutdownRouter(callback) {
this.makeRequest('RouterManager', {'API':1,'Token':this.token, 'Shutdown': true}, callback)
}
reseedRouter(callback) {
this.makeRequest('RouterManager', {'API':1,'Token':this.token, 'Reseed': true}, callback)
}
restartRouter(callback) {
this.makeRequest('RouterManager', {'API':1,'Token':this.token, 'Restart': true}, callback)
}
}

View File

@ -5,6 +5,8 @@ const Ci = Components.interfaces
const Cu = Components.utils
const Cr = Components.results
Cu.importGlobalProperties(["XMLHttpRequest"])
const kPropBundleURI = "chrome://i2pbutton/locale/i2pbutton.properties"
const kPropNamePrefix = "i2pbutton."
@ -19,6 +21,38 @@ let logger = {
}
}
const Timer = Components.Constructor("@mozilla.org/timer;1", "nsITimer", "initWithCallback");
function delay(timeout, func) {
let timer = new Timer(function () {
// Remove the reference so that it can be reaped.
delete delay.timers[idx];
func();
}, timeout, Ci.nsITimer.TYPE_ONE_SHOT);
// Store a reference to the timer so that it's not reaped before it fires.
let idx = delay.timers.push(timer) - 1;
return idx
}
delay.timers = []
function repeat(timeout, func) {
let timer = new Timer(function () {
func();
}, timeout, Ci.nsITimer.TYPE_REPEATING_SLACK);
// Store a reference to the timer so that it's not reaped before it fires.
let idx = delay.timers.push(timer) - 1;
return idx
}
repeat.timers = []
// Wrapper since window.setTimeout isn't always available in context/scope.
function setTimeout(func, interval) {
delay(interval, func)
}
const LauncherUtil = {
get isMac()
@ -49,7 +83,7 @@ const LauncherUtil = {
{
var wm = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator)
let browserWindow = wm.getMostRecentWindow("navigator:browser")
if (TLUtilInternal._isWindowVisible(browserWindow))
if (LauncherUtilInternal._isWindowVisible(browserWindow))
aParentWindow = browserWindow;
}
@ -83,34 +117,40 @@ const LauncherUtil = {
return argsArray;
},
setTimeout: (func, interval) => {
delay(interval, func)
},
setInterval: (func, interval) => {
repeat(interval, func)
},
get _networkSettingsWindow()
{
var wm = Cc["@mozilla.org/appshell/window-mediator;1"]
.getService(Ci.nsIWindowMediator);
return wm.getMostRecentWindow("I2PLauncher:NetworkSettings");
let wm = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator)
return wm.getMostRecentWindow("I2PLauncher:NetworkSettings")
},
_openNetworkSettings: function(aIsInitialBootstrap, aStartAtWizardPanel)
{
var win = this._networkSettingsWindow;
var win = this._networkSettingsWindow
if (win)
{
// Return to "Starting i2p" panel if being asked to open & dlog already exists.
//win.showStartingTorPanel();
win.focus();
//win.showStartingI2PPanel()
win.focus()
return;
}
const kSettingsURL = "chrome://i2pbutton/content/network-settings.xul";
const kWizardURL = "chrome://i2pbutton/content/network-settings-wizard.xul";
const kSettingsURL = "chrome://i2pbutton/chrome/content/i2pstartup-confdlg.xul"
const kWizardURL = "chrome://i2pbutton/chrome/content/i2pstartup-confdlg-wizard.xul"
var wwSvc = Cc["@mozilla.org/embedcomp/window-watcher;1"]
.getService(Ci.nsIWindowWatcher);
var winFeatures = "chrome,dialog=yes,modal,all";
var argsArray = this._createOpenWindowArgsArray(aIsInitialBootstrap,
aStartAtWizardPanel);
let isProgress = (this.kWizardProgressPageID == aStartAtWizardPanel);
let url = (aIsInitialBootstrap || isProgress) ? kWizardURL : kSettingsURL;
wwSvc.openWindow(null, url, "_blank", winFeatures, argsArray);
.getService(Ci.nsIWindowWatcher)
var winFeatures = "chrome,dialog=no,modal,all"
var argsArray = this._createOpenWindowArgsArray(aIsInitialBootstrap,aStartAtWizardPanel)
let isProgress = (this.kWizardProgressPageID == aStartAtWizardPanel)
//let url = (aIsInitialBootstrap || isProgress) ? kWizardURL : kSettingsURL
wwSvc.openWindow(null, kWizardURL, "_blank", winFeatures, argsArray)
},
// Returns true if user confirms; false if not.
@ -147,8 +187,8 @@ const LauncherUtil = {
{
try
{
let dirPath = this.getCharPref(TLUtilInternal.kIPCDirPrefName);
this.clearUserPref(TLUtilInternal.kIPCDirPrefName);
let dirPath = this.getCharPref(LauncherUtilInternal.kIPCDirPrefName);
this.clearUserPref(LauncherUtilInternal.kIPCDirPrefName);
if (dirPath)
{
let f = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile);
@ -164,35 +204,65 @@ const LauncherUtil = {
asSvc.quit(0x12) // eAttemptQuit (0x02) + eRestart (0x10)
},
waitForPortToOpen: function(portNum, doneCallback, interval) {
interval = interval || 3000
let portOpen = false
let testPort = () => {
var xhr = new XMLHttpRequest()
xhr.open('GET', `http://127.0.0.1:${portNum}`)
xhr.onerror = () => {
console.log(`Still waiting for ${portNum} to open`)
if (!portOpen) {
setTimeout(testPort, interval)
}
}
xhr.onload = () => {
console.log(`Port ${portNum} seem open now finally`)
portOpen = true
if ('function' === typeof doneCallback) {
doneCallback(portNum)
}
}
xhr.send()
}
testPort()
},
//waitForPortToOpen(7647, () => { console.log('ALL DONE') })
getRouterDefaultArgs: function() {
let dataDir = this.getI2PConfigPath(true)
let exeFile = this.getI2PBinary()
let libDir = dataDir.clone()
let i2pDir = libDir.clone()
let i2pDir = exeFile.parent.parent.clone()
libDir.append('lib')
let args = []
// NOTE: Don't mind spaces as nsIProcess escapes them.
args.push(`-Di2p.dir.base=${i2pDir.path}`)
logger.log(2, `Path for base is => ${i2pDir.path}`)
args.push(`-Duser.dir=${dataDir.path}`) // make PWD equal dataDir
let logFile = dataDir.clone()
logFile.append('wrapper.log')
args.push(`-Dwrapper.logfile=${logFile.path}`)
args.push(`-Djetty.home=${i2pDir.path}`)
args.push(`-Di2p.dir.config=${dataDir.path}`)
args.push(`-Di2p.dir.router=${dataDir.path}`)
args.push(`-Di2p.dir.app=${dataDir.path}`)
let nativeLib = libDir.clone()
nativeLib.append('jbigi.jar')
let clientConfigFile = dataDir.clone()
clientConfigFile.append('clients.config')
let routerCofigFile = dataDir.clone()
routerCofigFile.append('router.config')
logger.log(2, `Path for base is => ${i2pDir.path}`)
// NOTE: Don't mind spaces as nsIProcess escapes them.
args.push(`-Di2p.dir.base=${i2pDir.path}`)
args.push(`-Duser.dir=${dataDir.path}`) // make PWD equal dataDir
args.push(`-Dwrapper.logfile=${logFile.path}`)
args.push(`-Djetty.home=${i2pDir.path}`)
args.push(`-Djava.library.path=${libDir.path}`)
args.push(`-Di2p.dir.config=${dataDir.path}`)
args.push(`-Di2p.dir.router=${dataDir.path}`)
args.push(`-Di2p.dir.app=${dataDir.path}`)
args.push(`-Drouter.clientConfigFile=${clientConfigFile.path}`)
args.push(`-Drouter.configLocation=${routerCofigFile.path}`)
args.push('-Di2p.dir.portableMode=false')
args.push('-Dwrapper.name=i2pbrowser')
args.push('-Dwrapper.displayname=I2PBrowser')
args.push('-cp')
args.push(`${i2pDir.path}:${libDir.path}:${dataDir.path}`)
args.push(`${i2pDir.path}:${nativeLib.path}:${libDir.path}:${dataDir.path}`)
args.push("-Djava.awt.headless=true")
args.push("-Dwrapper.console.loglevel=DEBUG")
// Main class to execute
@ -250,7 +320,7 @@ const LauncherUtil = {
let dataDir = profDir.parent.parent.clone()
dataDir.append('I2P')
if (!dataDir.exists() && create) {
dataDir.create(dataDir.DIRECTORY_TYPE, 0o775)
dataDir.create(dataDir.DIRECTORY_TYPE, 0o700)
}
return dataDir
@ -290,18 +360,17 @@ const LauncherUtil = {
}
}
i2pFile = LauncherUtilInternal._appDir.clone()
try {
// Turn 'path' into an absolute path.
i2pFile = LauncherUtilInternal._appDir.clone()
if (this.isMac) {
i2pFile.append("I2PBrowser")
} else {
if (!this.isMac) {
let lnxpath = i2pFile.clone()
lnxpath.append(path)
return lnxpath
}
//i2pFile.appendRelativePath(path)
logger.log(2, `getI2PFile - Path before append: ${i2pFile.path}`)
i2pFile.appendRelativePath(path)
logger.log(2, `getI2PFile - Gonna try path ${i2pFile.path}`)
@ -311,7 +380,7 @@ const LauncherUtil = {
return i2pFile
} else {
logger.log(4, aI2PFileType + " file not found: "+ i2pFile.path)
return ''
return null
}
} catch(e) {
@ -320,22 +389,27 @@ const LauncherUtil = {
}
},
get internal() {
return LauncherUtilInternal
},
get dataDirectoryObject() {
let dataDir = LauncherUtilInternal._dataDir
try { dataDir.normalize() } catch(e) {}
logger.log(3, `Decided to use file ${dataDir.path}`)
return dataDir.clone()
},
get appDirectoryObject() {
return LauncherUtilInternal._appDir.clone()
},
flushLocalizedStringCache: function()
{
LauncherUtilInternal.mStringBundle = undefined
},
// "i2pbutton." is prepended to aStringName.
getLocalizedString: function(aStringName)
{
@ -345,7 +419,7 @@ const LauncherUtil = {
try
{
var key = kPropNamePrefix + aStringName;
return TLUtilInternal._stringBundle.GetStringFromName(key);
return LauncherUtilInternal._stringBundle.GetStringFromName(key);
} catch(e) {}
return aStringName;
@ -360,7 +434,7 @@ const LauncherUtil = {
try
{
var key = kPropNamePrefix + aStringName;
return TLUtilInternal._stringBundle.formatStringFromName(key, aArray, aLen)
return LauncherUtilInternal._stringBundle.formatStringFromName(key, aArray, aLen)
} catch(e) {}
return aStringName;
@ -415,6 +489,7 @@ let LauncherUtilInternal = {
return this.mOS
},
get _stringBundle()
{
if (!this.mStringBundle)

View File

@ -8,12 +8,50 @@ const { utils: Cu } = Components;
const { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
const { LegacyExtensionContext } =
Cu.import("resource://gre/modules/LegacyExtensionsUtils.jsm", {});
const { bindPref } =
Cu.import("resource://i2pbutton/modules/utils.js", {});
let logger = Components.classes["@geti2p.net/i2pbutton-logger;1"]
.getService(Components.interfaces.nsISupports).wrappedJSObject;
let log = (level, msg) => logger.log(level, msg);
// __prefs__. A shortcut to Mozilla Services.prefs.
let prefs = Services.prefs;
// __getPrefValue(prefName)__
// Returns the current value of a preference, regardless of its type.
var getPrefValue = function (prefName) {
switch(prefs.getPrefType(prefName)) {
case prefs.PREF_BOOL: return prefs.getBoolPref(prefName);
case prefs.PREF_INT: return prefs.getIntPref(prefName);
case prefs.PREF_STRING: return prefs.getCharPref(prefName);
default: return null;
}
};
// __bindPref(prefName, prefHandler, init)__
// Applies prefHandler whenever the value of the pref changes.
// If init is true, applies prefHandler to the current value.
// Returns a zero-arg function that unbinds the pref.
var bindPref = function (prefName, prefHandler, init = false) {
let update = () => { prefHandler(getPrefValue(prefName)); },
observer = { observe : function (subject, topic, data) {
if (data === prefName) {
update();
}
} };
prefs.addObserver(prefName, observer, false);
if (init) {
update();
}
return () => { prefs.removeObserver(prefName, observer); };
};
// __bindPrefAndInit(prefName, prefHandler)__
// Applies prefHandler to the current value of pref specified by prefName.
// Re-applies prefHandler whenever the value of the pref changes.
// Returns a zero-arg function that unbinds the pref.
var bindPrefAndInit = (prefName, prefHandler) =>
bindPref(prefName, prefHandler, true);
// ## NoScript settings
// Minimum and maximum capability states as controlled by NoScript.

View File

@ -77,7 +77,7 @@ const getProfileDir = function() {
getService(Ci.nsIProperties)
// this is a reference to the profile dir (ProfD) now.
let localDir = directoryService.get("ProfD", Ci.nsIFile)
return localDir.path
return localDir
}
function openFile(path, mode) {
@ -112,6 +112,22 @@ function array_to_hexdigits(array) {
}).join('');
}
function listExtensions(callbackFn) {
AddonManager.getAddonsByTypes(["extension"], function(addons) {
var addonData = [];
for (let i in addons) {
let cur = addons[i];
addonData.push({
id: cur.id.toString(),
name: cur.name,
});
};
console.log(JSON.stringify(addonData, null, ' '));
callbackFn(addonData)
});
}
//window.open("chrome://browser/content/browser.xul", "bmarks", "chrome,width=600,height=300")
// __prefs__. A shortcut to Mozilla Services.prefs.
@ -200,14 +216,14 @@ let dialogsByName = {};
// Like window.openDialog, but if the window is already
// open, just focuses it instead of opening a new one.
var showDialog = function (parent, url, name, features) {
let existingDialog = dialogsByName[name];
let existingDialog = dialogsByName[name]
if (existingDialog && !existingDialog.closed) {
existingDialog.focus();
return existingDialog;
existingDialog.focus()
return existingDialog
} else {
let newDialog = parent.openDialog.apply(parent, Array.slice(arguments, 1));
dialogsByName[name] = newDialog;
return newDialog;
let newDialog = parent.openDialog.apply(parent, Array.slice(arguments, 1))
dialogsByName[name] = newDialog
return newDialog
}
}