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)
|
||||
|
||||
> **NOTE:** StackEdit project itself has no back end. It can run on any apache server.
|
||||
|
||||
- Run Chrome without application cache:
|
||||
|
||||
chrome --disable-application-cache
|
||||
|
@ -1,93 +1,88 @@
|
||||
define([
|
||||
"jquery",
|
||||
"constants",
|
||||
"core",
|
||||
"logger",
|
||||
"eventMgr",
|
||||
"settings",
|
||||
"classes/AsyncTask"
|
||||
"jquery",
|
||||
"constants",
|
||||
"core",
|
||||
"logger",
|
||||
"eventMgr",
|
||||
"settings",
|
||||
"classes/AsyncTask"
|
||||
], function($, constants, core, logger, eventMgr, settings, AsyncTask) {
|
||||
|
||||
var sshHelper = {};
|
||||
var sshHelper = {};
|
||||
|
||||
// Listen to offline status changes
|
||||
var isOffline = false;
|
||||
eventMgr.addListener("onOfflineChanged", function(isOfflineParam) {
|
||||
isOffline = isOfflineParam;
|
||||
});
|
||||
// Listen to offline status changes
|
||||
var isOffline = false;
|
||||
eventMgr.addListener("onOfflineChanged", function(isOfflineParam) {
|
||||
isOffline = isOfflineParam;
|
||||
});
|
||||
|
||||
// Only used to check the offline status
|
||||
function connect(task) {
|
||||
task.onRun(function() {
|
||||
if(isOffline === true) {
|
||||
task.error(new Error("Operation not available in offline mode.|stopPublish"));
|
||||
return;
|
||||
}
|
||||
task.chain();
|
||||
});
|
||||
}
|
||||
// Only used to check the offline status
|
||||
function connect(task) {
|
||||
task.onRun(function() {
|
||||
if(isOffline === true) {
|
||||
return task.error(new Error("Operation not available in offline mode.|stopPublish"));
|
||||
}
|
||||
task.chain();
|
||||
});
|
||||
}
|
||||
|
||||
sshHelper.upload = function(host, port, username, password, path, title, content, callback) {
|
||||
var task = new AsyncTask();
|
||||
connect(task);
|
||||
task.onRun(function() {
|
||||
var url = settings.sshProxy + "upload";
|
||||
var data = {
|
||||
host: host,
|
||||
port: port,
|
||||
username: username,
|
||||
password: password,
|
||||
path: path,
|
||||
title: title,
|
||||
content: content
|
||||
};
|
||||
$.ajax({
|
||||
url: url,
|
||||
data: data,
|
||||
type: "POST",
|
||||
dataType: "json",
|
||||
timeout: constants.AJAX_TIMEOUT
|
||||
}).done(function(response) {
|
||||
if(response.error === undefined) {
|
||||
task.chain();
|
||||
return;
|
||||
}
|
||||
handleError(response.error, task);
|
||||
}).fail(function(jqXHR) {
|
||||
var error = {
|
||||
code: jqXHR.status,
|
||||
message: jqXHR.statusText
|
||||
};
|
||||
handleError(error, task);
|
||||
});
|
||||
});
|
||||
task.onSuccess(function() {
|
||||
callback();
|
||||
});
|
||||
task.onError(function(error) {
|
||||
callback(error);
|
||||
});
|
||||
task.enqueue();
|
||||
};
|
||||
sshHelper.upload = function(host, port, username, password, path, title, content, callback) {
|
||||
var task = new AsyncTask();
|
||||
connect(task);
|
||||
task.onRun(function() {
|
||||
var url = constants.SSH_PUBLISH_URL + '?' + $.param({
|
||||
host: host,
|
||||
port: port,
|
||||
username: username,
|
||||
password: password,
|
||||
path: path,
|
||||
title: title
|
||||
});
|
||||
$.ajax({
|
||||
url: url,
|
||||
data: content,
|
||||
type: "POST",
|
||||
timeout: constants.AJAX_TIMEOUT
|
||||
}).done(function(response) {
|
||||
if(response.error === undefined) {
|
||||
return task.chain();
|
||||
}
|
||||
handleError(response.error, task);
|
||||
}).fail(function(jqXHR) {
|
||||
var error = {
|
||||
code: jqXHR.status,
|
||||
message: jqXHR.statusText
|
||||
};
|
||||
handleError(error, task);
|
||||
});
|
||||
});
|
||||
task.onSuccess(function() {
|
||||
callback();
|
||||
});
|
||||
task.onError(function(error) {
|
||||
callback(error);
|
||||
});
|
||||
task.enqueue();
|
||||
};
|
||||
|
||||
function handleError(error, task) {
|
||||
var errorMsg;
|
||||
if(error) {
|
||||
logger.error(error);
|
||||
// Try to analyze the error
|
||||
if(typeof error === "string") {
|
||||
errorMsg = "SSH error: " + error + ".";
|
||||
}
|
||||
else {
|
||||
errorMsg = "Could not publish on SSH server.";
|
||||
if(error.code <= 0) {
|
||||
core.setOffline();
|
||||
errorMsg = "|stopPublish";
|
||||
}
|
||||
}
|
||||
}
|
||||
task.error(new Error(errorMsg));
|
||||
}
|
||||
function handleError(error, task) {
|
||||
var errorMsg;
|
||||
if(error) {
|
||||
logger.error(error);
|
||||
// Try to analyze the error
|
||||
if(typeof error === "string") {
|
||||
errorMsg = "SSH error: " + error + ".";
|
||||
}
|
||||
else {
|
||||
errorMsg = "Could not publish on SSH server.";
|
||||
if(error.code <= 0) {
|
||||
core.setOffline();
|
||||
errorMsg = "|stopPublish";
|
||||
}
|
||||
}
|
||||
}
|
||||
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>
|
||||
<div class="col-sm-7">
|
||||
<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,
|
||||
unless you are hosting your own <a target="_blank"
|
||||
href="https://github.com/benweet/stackedit-ssh-proxy">SSH
|
||||
proxy</a>.
|
||||
unless you're hosting your own StackEdit instance.
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
@ -1310,7 +1308,7 @@
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<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>
|
||||
<blockquote><b>Tip:</b> PDFs are fully customizable via Settings>Advanced>PDF template/options.</blockquote>
|
||||
</div>
|
||||
|
@ -56,7 +56,6 @@ define([
|
||||
' "pageSize": "A4"',
|
||||
'}'
|
||||
].join('\n'),
|
||||
sshProxy: constants.SSH_PROXY_URL,
|
||||
extensionSettings: {}
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user