Integrated stackedit-ssh-proxy service
This commit is contained in:
parent
3952ab6af1
commit
d1b0b86fbe
62
app/ssh.js
Normal file
62
app/ssh.js
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
var ssh2 = require('ssh2');
|
||||||
|
|
||||||
|
exports.publish = function(req, res) {
|
||||||
|
var done;
|
||||||
|
function sendResult(result) {
|
||||||
|
if(!done) {
|
||||||
|
res.json(result);
|
||||||
|
}
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
function sendError(error) {
|
||||||
|
sendResult({error: error});
|
||||||
|
}
|
||||||
|
|
||||||
|
var conn = new ssh2();
|
||||||
|
conn.on('ready', function() {
|
||||||
|
conn.sftp(function(err, sftp) {
|
||||||
|
if(err) {
|
||||||
|
return sendError('Unable to establish SFTP connection');
|
||||||
|
}
|
||||||
|
|
||||||
|
var writeStream = sftp.createWriteStream(req.query.path);
|
||||||
|
|
||||||
|
writeStream.on('close', function() {
|
||||||
|
sftp.end();
|
||||||
|
conn.end();
|
||||||
|
});
|
||||||
|
|
||||||
|
writeStream.on('error', function() {
|
||||||
|
sendError('Unable to write "' + req.query.path + '"');
|
||||||
|
sftp.end();
|
||||||
|
conn.end();
|
||||||
|
});
|
||||||
|
|
||||||
|
req.pipe(writeStream);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
conn.on('error', function(err) {
|
||||||
|
if(err.level == "authentication") {
|
||||||
|
return sendError('Authentication failure');
|
||||||
|
}
|
||||||
|
if(err.code == "ENOTFOUND") {
|
||||||
|
return sendError('Host not found');
|
||||||
|
}
|
||||||
|
if(err.code == "ETIMEDOUT") {
|
||||||
|
return sendError('Connection timeout');
|
||||||
|
}
|
||||||
|
sendError(err);
|
||||||
|
});
|
||||||
|
|
||||||
|
conn.on('end', function() {
|
||||||
|
sendResult({});
|
||||||
|
});
|
||||||
|
|
||||||
|
conn.connect({
|
||||||
|
host: req.query.host,
|
||||||
|
port: req.query.port || 22,
|
||||||
|
username: req.query.username,
|
||||||
|
password: req.query.password
|
||||||
|
});
|
||||||
|
};
|
@ -25,8 +25,6 @@ Getting started
|
|||||||
|
|
||||||
(export PORT=80 && node server.js)
|
(export PORT=80 && node server.js)
|
||||||
|
|
||||||
> **NOTE:** StackEdit project itself has no back end. It can run on any apache server.
|
|
||||||
|
|
||||||
- Run Chrome without application cache:
|
- Run Chrome without application cache:
|
||||||
|
|
||||||
chrome --disable-application-cache
|
chrome --disable-application-cache
|
||||||
|
@ -1,93 +1,88 @@
|
|||||||
define([
|
define([
|
||||||
"jquery",
|
"jquery",
|
||||||
"constants",
|
"constants",
|
||||||
"core",
|
"core",
|
||||||
"logger",
|
"logger",
|
||||||
"eventMgr",
|
"eventMgr",
|
||||||
"settings",
|
"settings",
|
||||||
"classes/AsyncTask"
|
"classes/AsyncTask"
|
||||||
], function($, constants, core, logger, eventMgr, settings, AsyncTask) {
|
], function($, constants, core, logger, eventMgr, settings, AsyncTask) {
|
||||||
|
|
||||||
var sshHelper = {};
|
var sshHelper = {};
|
||||||
|
|
||||||
// Listen to offline status changes
|
// Listen to offline status changes
|
||||||
var isOffline = false;
|
var isOffline = false;
|
||||||
eventMgr.addListener("onOfflineChanged", function(isOfflineParam) {
|
eventMgr.addListener("onOfflineChanged", function(isOfflineParam) {
|
||||||
isOffline = isOfflineParam;
|
isOffline = isOfflineParam;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Only used to check the offline status
|
// Only used to check the offline status
|
||||||
function connect(task) {
|
function connect(task) {
|
||||||
task.onRun(function() {
|
task.onRun(function() {
|
||||||
if(isOffline === true) {
|
if(isOffline === true) {
|
||||||
task.error(new Error("Operation not available in offline mode.|stopPublish"));
|
return task.error(new Error("Operation not available in offline mode.|stopPublish"));
|
||||||
return;
|
}
|
||||||
}
|
task.chain();
|
||||||
task.chain();
|
});
|
||||||
});
|
}
|
||||||
}
|
|
||||||
|
|
||||||
sshHelper.upload = function(host, port, username, password, path, title, content, callback) {
|
sshHelper.upload = function(host, port, username, password, path, title, content, callback) {
|
||||||
var task = new AsyncTask();
|
var task = new AsyncTask();
|
||||||
connect(task);
|
connect(task);
|
||||||
task.onRun(function() {
|
task.onRun(function() {
|
||||||
var url = settings.sshProxy + "upload";
|
var url = constants.SSH_PUBLISH_URL + '?' + $.param({
|
||||||
var data = {
|
host: host,
|
||||||
host: host,
|
port: port,
|
||||||
port: port,
|
username: username,
|
||||||
username: username,
|
password: password,
|
||||||
password: password,
|
path: path,
|
||||||
path: path,
|
title: title
|
||||||
title: title,
|
});
|
||||||
content: content
|
$.ajax({
|
||||||
};
|
url: url,
|
||||||
$.ajax({
|
data: content,
|
||||||
url: url,
|
type: "POST",
|
||||||
data: data,
|
timeout: constants.AJAX_TIMEOUT
|
||||||
type: "POST",
|
}).done(function(response) {
|
||||||
dataType: "json",
|
if(response.error === undefined) {
|
||||||
timeout: constants.AJAX_TIMEOUT
|
return task.chain();
|
||||||
}).done(function(response) {
|
}
|
||||||
if(response.error === undefined) {
|
handleError(response.error, task);
|
||||||
task.chain();
|
}).fail(function(jqXHR) {
|
||||||
return;
|
var error = {
|
||||||
}
|
code: jqXHR.status,
|
||||||
handleError(response.error, task);
|
message: jqXHR.statusText
|
||||||
}).fail(function(jqXHR) {
|
};
|
||||||
var error = {
|
handleError(error, task);
|
||||||
code: jqXHR.status,
|
});
|
||||||
message: jqXHR.statusText
|
});
|
||||||
};
|
task.onSuccess(function() {
|
||||||
handleError(error, task);
|
callback();
|
||||||
});
|
});
|
||||||
});
|
task.onError(function(error) {
|
||||||
task.onSuccess(function() {
|
callback(error);
|
||||||
callback();
|
});
|
||||||
});
|
task.enqueue();
|
||||||
task.onError(function(error) {
|
};
|
||||||
callback(error);
|
|
||||||
});
|
|
||||||
task.enqueue();
|
|
||||||
};
|
|
||||||
|
|
||||||
function handleError(error, task) {
|
function handleError(error, task) {
|
||||||
var errorMsg;
|
var errorMsg;
|
||||||
if(error) {
|
if(error) {
|
||||||
logger.error(error);
|
logger.error(error);
|
||||||
// Try to analyze the error
|
// Try to analyze the error
|
||||||
if(typeof error === "string") {
|
if(typeof error === "string") {
|
||||||
errorMsg = "SSH error: " + error + ".";
|
errorMsg = "SSH error: " + error + ".";
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
errorMsg = "Could not publish on SSH server.";
|
errorMsg = "Could not publish on SSH server.";
|
||||||
if(error.code <= 0) {
|
if(error.code <= 0) {
|
||||||
core.setOffline();
|
core.setOffline();
|
||||||
errorMsg = "|stopPublish";
|
errorMsg = "|stopPublish";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
task.error(new Error(errorMsg));
|
task.error(new Error(errorMsg));
|
||||||
}
|
}
|
||||||
|
|
||||||
return sshHelper;
|
return sshHelper;
|
||||||
});
|
});
|
||||||
|
@ -590,11 +590,9 @@
|
|||||||
<label class="col-sm-4 control-label" for="input-publish-ssh-host">Host</label>
|
<label class="col-sm-4 control-label" for="input-publish-ssh-host">Host</label>
|
||||||
<div class="col-sm-7">
|
<div class="col-sm-7">
|
||||||
<input type="text" id="input-publish-ssh-host"
|
<input type="text" id="input-publish-ssh-host"
|
||||||
placeholder="host.name.or.ip" class="form-control"> <span
|
placeholder="hostname.or.ip" class="form-control"> <span
|
||||||
class="help-block"> Host must be accessible publicly,
|
class="help-block"> Host must be accessible publicly,
|
||||||
unless you are hosting your own <a target="_blank"
|
unless you're hosting your own StackEdit instance.
|
||||||
href="https://github.com/benweet/stackedit-ssh-proxy">SSH
|
|
||||||
proxy</a>.
|
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -1310,7 +1308,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<p>This feature is restricted to sponsor users as it's a web service hosted on Amazon EC2.
|
<p>This feature is restricted to sponsor users as it's a web service hosted on Amazon EC2.
|
||||||
Note that sponsoring StackEdit would cost you only <b>$5/year</b>.</p>
|
Note that sponsoring StackEdit would cost you only $5/year.</p>
|
||||||
<p>To see how a PDF looks like <a target="_blank" href="/Welcome%20document.pdf">click here</a>.</p>
|
<p>To see how a PDF looks like <a target="_blank" href="/Welcome%20document.pdf">click here</a>.</p>
|
||||||
<blockquote><b>Tip:</b> PDFs are fully customizable via Settings>Advanced>PDF template/options.</blockquote>
|
<blockquote><b>Tip:</b> PDFs are fully customizable via Settings>Advanced>PDF template/options.</blockquote>
|
||||||
</div>
|
</div>
|
||||||
|
@ -56,7 +56,6 @@ define([
|
|||||||
' "pageSize": "A4"',
|
' "pageSize": "A4"',
|
||||||
'}'
|
'}'
|
||||||
].join('\n'),
|
].join('\n'),
|
||||||
sshProxy: constants.SSH_PROXY_URL,
|
|
||||||
extensionSettings: {}
|
extensionSettings: {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user