mirror of
https://github.com/node-red/node-red.git
synced 2023-10-10 13:36:53 +02:00
Allow a user to pick existing sshkeys from ~/.ssh
This commit is contained in:
parent
00a396014b
commit
6516e0dfd2
@ -44,32 +44,44 @@ RED.projects.userSettings = (function() {
|
|||||||
function createSSHKeySection(pane) {
|
function createSSHKeySection(pane) {
|
||||||
var container = $('<div class="user-settings-section"></div>').appendTo(pane);
|
var container = $('<div class="user-settings-section"></div>').appendTo(pane);
|
||||||
var popover;
|
var popover;
|
||||||
var title = $('<h4></h4>').text("SSH Keys").appendTo(container);
|
var title = $('<h3></h3>').text("SSH Keys").appendTo(container);
|
||||||
|
var subtitle = $('<div style="color:#aaa;"></div>').appendTo(container).text("Allows you to create secure connections to remote git repositories.");
|
||||||
|
|
||||||
var addKeyButton = $('<button class="editor-button editor-button-small" style="float: right; margin-right: 10px;">generate key</button>')
|
var addKeyButton = $('<button class="editor-button editor-button-small" style="float: right; margin-right: 10px;">add key</button>')
|
||||||
.appendTo(title)
|
.appendTo(subtitle)
|
||||||
.click(function(evt) {
|
.click(function(evt) {
|
||||||
addKeyButton.attr('disabled',true);
|
addKeyButton.attr('disabled',true);
|
||||||
|
saveButton.attr('disabled',true);
|
||||||
|
// bg.children().removeClass("selected");
|
||||||
|
// addLocalButton.click();
|
||||||
addKeyDialog.slideDown(200);
|
addKeyDialog.slideDown(200);
|
||||||
keyNameInput.focus();
|
keyNameInput.focus();
|
||||||
saveButton.attr('disabled',true);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
var validateForm = function() {
|
var validateForm = function() {
|
||||||
var validName = /^[a-zA-Z0-9\-_]+$/.test(keyNameInput.val());
|
var valid = /^[a-zA-Z0-9\-_]+$/.test(keyNameInput.val());
|
||||||
var passphrase = passphraseInput.val();
|
keyNameInput.toggleClass('input-error',keyNameInputChanged&&!valid);
|
||||||
var validPassphrase = passphrase.length === 0 || passphrase.length >= 8;
|
|
||||||
|
|
||||||
saveButton.attr('disabled',!validName || !validPassphrase);
|
// var selectedButton = bg.find(".selected");
|
||||||
keyNameInput.toggleClass('input-error',keyNameInputChanged&&!validName);
|
// if (selectedButton[0] === addLocalButton[0]) {
|
||||||
passphraseInput.toggleClass('input-error',!validPassphrase);
|
// valid = valid && localPublicKeyPathInput.val().length > 0 && localPrivateKeyPathInput.val().length > 0;
|
||||||
if (!validPassphrase) {
|
// } else if (selectedButton[0] === uploadButton[0]) {
|
||||||
passphraseInputSubLabel.text("Passphrase too short");
|
// valid = valid && publicKeyInput.val().length > 0 && privateKeyInput.val().length > 0;
|
||||||
} else if (passphrase.length === 0) {
|
// } else if (selectedButton[0] === generateButton[0]) {
|
||||||
passphraseInputSubLabel.text("Optional");
|
var passphrase = passphraseInput.val();
|
||||||
} else {
|
var validPassphrase = passphrase.length === 0 || passphrase.length >= 8;
|
||||||
passphraseInputSubLabel.text("");
|
passphraseInput.toggleClass('input-error',!validPassphrase);
|
||||||
}
|
if (!validPassphrase) {
|
||||||
|
passphraseInputSubLabel.text("Passphrase too short");
|
||||||
|
} else if (passphrase.length === 0) {
|
||||||
|
passphraseInputSubLabel.text("Optional");
|
||||||
|
} else {
|
||||||
|
passphraseInputSubLabel.text("");
|
||||||
|
}
|
||||||
|
valid = valid && validPassphrase;
|
||||||
|
// }
|
||||||
|
|
||||||
|
saveButton.attr('disabled',!valid);
|
||||||
|
|
||||||
if (popover) {
|
if (popover) {
|
||||||
popover.close();
|
popover.close();
|
||||||
@ -79,27 +91,88 @@ RED.projects.userSettings = (function() {
|
|||||||
|
|
||||||
var row = $('<div class="user-settings-row"></div>').appendTo(container);
|
var row = $('<div class="user-settings-row"></div>').appendTo(container);
|
||||||
var addKeyDialog = $('<div class="projects-dialog-list-dialog"></div>').hide().appendTo(row);
|
var addKeyDialog = $('<div class="projects-dialog-list-dialog"></div>').hide().appendTo(row);
|
||||||
$('<div class="projects-dialog-list-dialog-header">').text('Generate SSH Key').appendTo(addKeyDialog);
|
$('<div class="projects-dialog-list-dialog-header">').text('Add SSH Key').appendTo(addKeyDialog);
|
||||||
var addKeyDialogBody = $('<div>').appendTo(addKeyDialog);
|
var addKeyDialogBody = $('<div>').appendTo(addKeyDialog);
|
||||||
|
|
||||||
|
row = $('<div class="user-settings-row"></div>').appendTo(addKeyDialogBody);
|
||||||
|
$('<div style="color:#aaa;"></div>').appendTo(row).text("Generate a new public/private key pair");
|
||||||
|
// var bg = $('<div></div>',{class:"button-group", style:"text-align: center"}).appendTo(row);
|
||||||
|
// var addLocalButton = $('<button class="editor-button toggle selected">use local key</button>').appendTo(bg);
|
||||||
|
// var uploadButton = $('<button class="editor-button toggle">upload key</button>').appendTo(bg);
|
||||||
|
// var generateButton = $('<button class="editor-button toggle">generate key</button>').appendTo(bg);
|
||||||
|
// bg.children().click(function(e) {
|
||||||
|
// e.preventDefault();
|
||||||
|
// if ($(this).hasClass("selected")) {
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// bg.children().removeClass("selected");
|
||||||
|
// $(this).addClass("selected");
|
||||||
|
// if (this === addLocalButton[0]) {
|
||||||
|
// addLocalKeyPane.show();
|
||||||
|
// generateKeyPane.hide();
|
||||||
|
// uploadKeyPane.hide();
|
||||||
|
// } else if (this === uploadButton[0]) {
|
||||||
|
// addLocalKeyPane.hide();
|
||||||
|
// generateKeyPane.hide();
|
||||||
|
// uploadKeyPane.show();
|
||||||
|
// } else if (this === generateButton[0]){
|
||||||
|
// addLocalKeyPane.hide();
|
||||||
|
// generateKeyPane.show();
|
||||||
|
// uploadKeyPane.hide();
|
||||||
|
// }
|
||||||
|
// validateForm();
|
||||||
|
// })
|
||||||
|
|
||||||
|
|
||||||
row = $('<div class="user-settings-row"></div>').appendTo(addKeyDialogBody);
|
row = $('<div class="user-settings-row"></div>').appendTo(addKeyDialogBody);
|
||||||
$('<label for=""></label>').text('Name').appendTo(row);
|
$('<label for=""></label>').text('Name').appendTo(row);
|
||||||
|
var keyNameInputChanged = false;
|
||||||
var keyNameInput = $('<input type="text">').appendTo(row).on("change keyup paste",function() {
|
var keyNameInput = $('<input type="text">').appendTo(row).on("change keyup paste",function() {
|
||||||
keyNameInputChanged = true;
|
keyNameInputChanged = true;
|
||||||
validateForm();
|
validateForm();
|
||||||
});
|
});
|
||||||
var keyNameInputChanged = false;
|
|
||||||
$('<label class="projects-edit-form-sublabel"><small>Must contain only A-Z 0-9 _ -</small></label>').appendTo(row).find("small");
|
$('<label class="projects-edit-form-sublabel"><small>Must contain only A-Z 0-9 _ -</small></label>').appendTo(row).find("small");
|
||||||
|
|
||||||
row = $('<div class="user-settings-row"></div>').appendTo(addKeyDialogBody);
|
var generateKeyPane = $('<div>').appendTo(addKeyDialogBody);
|
||||||
|
row = $('<div class="user-settings-row"></div>').appendTo(generateKeyPane);
|
||||||
$('<label for=""></label>').text('Passphrase').appendTo(row);
|
$('<label for=""></label>').text('Passphrase').appendTo(row);
|
||||||
passphraseInput = $('<input type="password">').appendTo(row).on("change keyup paste",validateForm);
|
var passphraseInput = $('<input type="password">').appendTo(row).on("change keyup paste",validateForm);
|
||||||
var passphraseInputSubLabel = $('<label class="projects-edit-form-sublabel"><small>Optional</small></label>').appendTo(row).find("small");
|
var passphraseInputSubLabel = $('<label class="projects-edit-form-sublabel"><small>Optional</small></label>').appendTo(row).find("small");
|
||||||
|
|
||||||
|
// var addLocalKeyPane = $('<div>').hide().appendTo(addKeyDialogBody);
|
||||||
|
// row = $('<div class="user-settings-row"></div>').appendTo(addLocalKeyPane);
|
||||||
|
// $('<label for=""></label>').text('Public key').appendTo(row);
|
||||||
|
// var localPublicKeyPathInput = $('<input type="text">').appendTo(row).on("change keyup paste",validateForm);
|
||||||
|
// $('<label class="projects-edit-form-sublabel"><small>Public key file path, for example: ~/.ssh/id_rsa.pub</small></label>').appendTo(row).find("small");
|
||||||
|
// row = $('<div class="user-settings-row"></div>').appendTo(addLocalKeyPane);
|
||||||
|
// $('<label for=""></label>').text('Private key').appendTo(row);
|
||||||
|
// var localPrivateKeyPathInput = $('<input type="text">').appendTo(row).on("change keyup paste",validateForm);
|
||||||
|
// $('<label class="projects-edit-form-sublabel"><small>Private key file path, for example: ~/.ssh/id_rsa</small></label>').appendTo(row).find("small");
|
||||||
|
//
|
||||||
|
// var uploadKeyPane = $('<div>').hide().appendTo(addKeyDialogBody);
|
||||||
|
// row = $('<div class="user-settings-row"></div>').appendTo(uploadKeyPane);
|
||||||
|
// $('<label for=""></label>').text('Public key').appendTo(row);
|
||||||
|
// var publicKeyInput = $('<textarea>').appendTo(row).on("change keyup paste",validateForm);
|
||||||
|
// $('<label class="projects-edit-form-sublabel"><small>Paste in public key contents, for example: ~/.ssh/id_rsa.pub</small></label>').appendTo(row).find("small");
|
||||||
|
// row = $('<div class="user-settings-row"></div>').appendTo(uploadKeyPane);
|
||||||
|
// $('<label for=""></label>').text('Private key').appendTo(row);
|
||||||
|
// var privateKeyInput = $('<textarea>').appendTo(row).on("change keyup paste",validateForm);
|
||||||
|
// $('<label class="projects-edit-form-sublabel"><small>Paste in private key contents, for example: ~/.ssh/id_rsa</small></label>').appendTo(row).find("small");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var hideEditForm = function() {
|
var hideEditForm = function() {
|
||||||
addKeyButton.attr('disabled',false);
|
addKeyButton.attr('disabled',false);
|
||||||
addKeyDialog.hide();
|
addKeyDialog.hide();
|
||||||
|
|
||||||
keyNameInput.val("");
|
keyNameInput.val("");
|
||||||
|
keyNameInputChanged = false;
|
||||||
passphraseInput.val("");
|
passphraseInput.val("");
|
||||||
|
// localPublicKeyPathInput.val("");
|
||||||
|
// localPrivateKeyPathInput.val("");
|
||||||
|
// publicKeyInput.val("");
|
||||||
|
// privateKeyInput.val("");
|
||||||
if (popover) {
|
if (popover) {
|
||||||
popover.close();
|
popover.close();
|
||||||
popover = null;
|
popover = null;
|
||||||
@ -118,11 +191,24 @@ RED.projects.userSettings = (function() {
|
|||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
var spinner = utils.addSpinnerOverlay(addKeyDialog).addClass('projects-dialog-spinner-contain');
|
var spinner = utils.addSpinnerOverlay(addKeyDialog).addClass('projects-dialog-spinner-contain');
|
||||||
var payload = {
|
var payload = {
|
||||||
name: keyNameInput.val(),
|
name: keyNameInput.val()
|
||||||
comment: gitEmailInput.val(),
|
|
||||||
password: passphraseInput.val(),
|
|
||||||
size: 4096
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var selectedButton = bg.find(".selected");
|
||||||
|
if (selectedButton[0] === addLocalButton[0]) {
|
||||||
|
payload.type = "local";
|
||||||
|
payload.publicKeyPath = localPublicKeyPathInput.val();
|
||||||
|
payload.privateKeyPath = localPrivateKeyPathInput.val();
|
||||||
|
} else if (selectedButton[0] === uploadButton[0]) {
|
||||||
|
payload.type = "upload";
|
||||||
|
payload.publicKey = publicKeyInput.val();
|
||||||
|
payload.privateKey = privateKeyInput.val();
|
||||||
|
} else if (selectedButton[0] === generateButton[0]) {
|
||||||
|
payload.type = "generate";
|
||||||
|
payload.comment = gitEmailInput.val();
|
||||||
|
payload.password = passphraseInput.val();
|
||||||
|
payload.size = 4096;
|
||||||
|
}
|
||||||
var done = function(err) {
|
var done = function(err) {
|
||||||
spinner.remove();
|
spinner.remove();
|
||||||
if (err) {
|
if (err) {
|
||||||
@ -181,6 +267,7 @@ RED.projects.userSettings = (function() {
|
|||||||
$('<button class="editor-button editor-button-small">Copy to clipboard</button>')
|
$('<button class="editor-button editor-button-small">Copy to clipboard</button>')
|
||||||
.appendTo(formButtons)
|
.appendTo(formButtons)
|
||||||
.click(function(evt) {
|
.click(function(evt) {
|
||||||
|
evt.stopPropagation();
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
document.getSelection().selectAllChildren(keyBox[0]);
|
document.getSelection().selectAllChildren(keyBox[0]);
|
||||||
var ret = document.execCommand('copy');
|
var ret = document.execCommand('copy');
|
||||||
@ -189,7 +276,7 @@ RED.projects.userSettings = (function() {
|
|||||||
|
|
||||||
return row;
|
return row;
|
||||||
}
|
}
|
||||||
var keyList = $('<ol>').appendTo(row).editableList({
|
var keyList = $('<ol class="projects-dialog-ssh-key-list">').appendTo(row).editableList({
|
||||||
height: 'auto',
|
height: 'auto',
|
||||||
addButton: false,
|
addButton: false,
|
||||||
scrollOnAdd: false,
|
scrollOnAdd: false,
|
||||||
@ -210,66 +297,67 @@ RED.projects.userSettings = (function() {
|
|||||||
|
|
||||||
var tools = $('<span class="button-row entry-tools">').appendTo(container);
|
var tools = $('<span class="button-row entry-tools">').appendTo(container);
|
||||||
var expandedRow;
|
var expandedRow;
|
||||||
$('<button class="editor-button editor-button-small"><i class="fa fa-eye"></i></button>')
|
row.click(function(e) {
|
||||||
.appendTo(tools)
|
if (expandedRow) {
|
||||||
.click(function(e) {
|
expandedRow.slideUp(200,function() {
|
||||||
if (expandedRow) {
|
expandedRow.remove();
|
||||||
expandedRow.slideUp(200,function() {
|
expandedRow = null;
|
||||||
expandedRow.remove();
|
})
|
||||||
expandedRow = null;
|
} else {
|
||||||
})
|
expandedRow = expandKey(container,entry);
|
||||||
} else {
|
}
|
||||||
expandedRow = expandKey(container,entry);
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
$('<button class="editor-button editor-button-small"><i class="fa fa-trash"></i></button>')
|
if (!entry.system) {
|
||||||
.appendTo(tools)
|
$('<button class="editor-button editor-button-small"><i class="fa fa-trash"></i></button>')
|
||||||
.click(function(e) {
|
.appendTo(tools)
|
||||||
var spinner = utils.addSpinnerOverlay(row).addClass('projects-dialog-spinner-contain');
|
.click(function(e) {
|
||||||
var notification = RED.notify("Are you sure you want to delete the SSH key '"+entry.name+"'? This cannot be undone.", {
|
e.stopPropagation();
|
||||||
type: 'warning',
|
var spinner = utils.addSpinnerOverlay(row).addClass('projects-dialog-spinner-contain');
|
||||||
modal: true,
|
var notification = RED.notify("Are you sure you want to delete the SSH key '"+entry.name+"'? This cannot be undone.", {
|
||||||
fixed: true,
|
type: 'warning',
|
||||||
buttons: [
|
modal: true,
|
||||||
{
|
fixed: true,
|
||||||
text: RED._("common.label.cancel"),
|
buttons: [
|
||||||
click: function() {
|
{
|
||||||
spinner.remove();
|
text: RED._("common.label.cancel"),
|
||||||
notification.close();
|
click: function() {
|
||||||
}
|
spinner.remove();
|
||||||
},
|
notification.close();
|
||||||
{
|
}
|
||||||
text: "Delete key",
|
},
|
||||||
click: function() {
|
{
|
||||||
notification.close();
|
text: "Delete key",
|
||||||
var url = "settings/user/keys/"+entry.name;
|
click: function() {
|
||||||
var options = {
|
notification.close();
|
||||||
url: url,
|
var url = "settings/user/keys/"+entry.name;
|
||||||
type: "DELETE",
|
var options = {
|
||||||
responses: {
|
url: url,
|
||||||
200: function(data) {
|
type: "DELETE",
|
||||||
row.fadeOut(200,function() {
|
responses: {
|
||||||
keyList.editableList('removeItem',entry);
|
200: function(data) {
|
||||||
setTimeout(spinner.remove, 100);
|
row.fadeOut(200,function() {
|
||||||
if (keyList.editableList('length') === 0) {
|
keyList.editableList('removeItem',entry);
|
||||||
keyList.editableList('addItem',emptyItem);
|
setTimeout(spinner.remove, 100);
|
||||||
}
|
if (keyList.editableList('length') === 0) {
|
||||||
});
|
keyList.editableList('addItem',emptyItem);
|
||||||
},
|
}
|
||||||
400: {
|
});
|
||||||
'unexpected_error': function(error) {
|
},
|
||||||
console.log(error);
|
400: {
|
||||||
spinner.remove();
|
'unexpected_error': function(error) {
|
||||||
}
|
console.log(error);
|
||||||
},
|
spinner.remove();
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
utils.sendRequest(options);
|
||||||
}
|
}
|
||||||
utils.sendRequest(options);
|
|
||||||
}
|
}
|
||||||
}
|
]
|
||||||
]
|
});
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
if (entry.expand) {
|
if (entry.expand) {
|
||||||
expandedRow = expandKey(container,entry);
|
expandedRow = expandKey(container,entry);
|
||||||
}
|
}
|
||||||
@ -288,7 +376,11 @@ RED.projects.userSettings = (function() {
|
|||||||
key.expand = true;
|
key.expand = true;
|
||||||
}
|
}
|
||||||
keyList.editableList('addItem',key);
|
keyList.editableList('addItem',key);
|
||||||
})
|
});
|
||||||
|
if (keyList.editableList('length') === 0) {
|
||||||
|
keyList.editableList('addItem',emptyItem);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -1232,7 +1232,7 @@ RED.projects = (function() {
|
|||||||
//data-i18n="[placeholder]menu.label.searchInput"
|
//data-i18n="[placeholder]menu.label.searchInput"
|
||||||
delay: 200,
|
delay: 200,
|
||||||
change: function() {
|
change: function() {
|
||||||
filterTerm = $(this).val();
|
filterTerm = $(this).val().toLowerCase();
|
||||||
list.editableList('filter');
|
list.editableList('filter');
|
||||||
if (selectedListItem && !selectedListItem.is(":visible")) {
|
if (selectedListItem && !selectedListItem.is(":visible")) {
|
||||||
selectedListItem.children().children().removeClass('selected');
|
selectedListItem.children().children().removeClass('selected');
|
||||||
@ -1241,6 +1241,12 @@ RED.projects = (function() {
|
|||||||
if (options.select) {
|
if (options.select) {
|
||||||
options.select(selectedListItem.children().data('data'));
|
options.select(selectedListItem.children().data('data'));
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
selectedListItem = list.children(":visible").first();
|
||||||
|
selectedListItem.children().children().addClass('selected');
|
||||||
|
if (options.select) {
|
||||||
|
options.select(selectedListItem.children().data('data'));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ensureSelectedIsVisible();
|
ensureSelectedIsVisible();
|
||||||
}
|
}
|
||||||
|
@ -780,6 +780,15 @@ div.projects-dialog-ssh-public-key {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.projects-dialog-ssh-key-list {
|
||||||
|
li {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
li:hover {
|
||||||
|
background: #f3f3f3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.projects-dialog-list {
|
.projects-dialog-list {
|
||||||
position: relative;
|
position: relative;
|
||||||
.red-ui-editableList-container {
|
.red-ui-editableList-container {
|
||||||
|
@ -73,7 +73,11 @@
|
|||||||
display: table;
|
display: table;
|
||||||
clear: both;
|
clear: both;
|
||||||
}
|
}
|
||||||
.uneditable-input, input {
|
.uneditable-input, input, textarea {
|
||||||
width: calc(100% - 150px);
|
width: calc(100% - 150px);
|
||||||
}
|
}
|
||||||
|
textarea {
|
||||||
|
resize: none;
|
||||||
|
height: 10em;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -84,7 +84,7 @@ module.exports = {
|
|||||||
app.post("/", needsPermission("settings.write"), function(req,res) {
|
app.post("/", needsPermission("settings.write"), function(req,res) {
|
||||||
var username = getUsername(req.user);
|
var username = getUsername(req.user);
|
||||||
// console.log('req.body:', req.body);
|
// console.log('req.body:', req.body);
|
||||||
if ( req.body && req.body.name ) {
|
if ( req.body && req.body.name && /^[a-zA-Z0-9\-_]+$/.test(req.body.name)) {
|
||||||
runtime.storage.sshkeys.generateSSHKey(username, req.body)
|
runtime.storage.sshkeys.generateSSHKey(username, req.body)
|
||||||
.then(function(name) {
|
.then(function(name) {
|
||||||
// console.log('generate key --- success name:', name);
|
// console.log('generate key --- success name:', name);
|
||||||
|
@ -949,7 +949,9 @@ function getProject(name) {
|
|||||||
function listProjects() {
|
function listProjects() {
|
||||||
return fs.readdir(projectsDir).then(function(fns) {
|
return fs.readdir(projectsDir).then(function(fns) {
|
||||||
var dirs = [];
|
var dirs = [];
|
||||||
fns.sort().filter(function(fn) {
|
fns.sort(function(A,B) {
|
||||||
|
return A.toLowerCase().localeCompare(B.toLowerCase());
|
||||||
|
}).filter(function(fn) {
|
||||||
var fullPath = fspath.join(projectsDir,fn);
|
var fullPath = fspath.join(projectsDir,fn);
|
||||||
if (fn[0] != ".") {
|
if (fn[0] != ".") {
|
||||||
var stats = fs.lstatSync(fullPath);
|
var stats = fs.lstatSync(fullPath);
|
||||||
|
@ -23,12 +23,14 @@ var settings;
|
|||||||
var runtime;
|
var runtime;
|
||||||
var log;
|
var log;
|
||||||
var sshkeyDir;
|
var sshkeyDir;
|
||||||
|
var userSSHKeyDir;
|
||||||
|
|
||||||
function init(_settings, _runtime) {
|
function init(_settings, _runtime) {
|
||||||
settings = _settings;
|
settings = _settings;
|
||||||
runtime = _runtime;
|
runtime = _runtime;
|
||||||
log = runtime.log;
|
log = runtime.log;
|
||||||
sshkeyDir = fspath.join(settings.userDir, "projects", ".sshkeys");
|
sshkeyDir = fspath.join(settings.userDir, "projects", ".sshkeys");
|
||||||
|
userSSHKeyDir = fspath.join(process.env.HOME || process.env.USERPROFILE || process.env.HOMEPATH, ".ssh");
|
||||||
// console.log('sshkeys.init()');
|
// console.log('sshkeys.init()');
|
||||||
return createSSHKeyDirectory();
|
return createSSHKeyDirectory();
|
||||||
}
|
}
|
||||||
@ -38,12 +40,23 @@ function createSSHKeyDirectory() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function listSSHKeys(username) {
|
function listSSHKeys(username) {
|
||||||
var startStr = username + '_';
|
return listSSHKeysInDir(sshkeyDir,username + '_').then(function(customKeys) {
|
||||||
// console.log('sshkeyDir:', sshkeyDir);
|
return listSSHKeysInDir(userSSHKeyDir).then(function(existingKeys) {
|
||||||
return fs.readdir(sshkeyDir).then(function(fns) {
|
existingKeys.forEach(function(k){
|
||||||
|
k.system = true;
|
||||||
|
customKeys.push(k);
|
||||||
|
})
|
||||||
|
return customKeys;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function listSSHKeysInDir(dir,startStr) {
|
||||||
|
startStr = startStr || "";
|
||||||
|
return fs.readdir(dir).then(function(fns) {
|
||||||
var ret = fns.sort()
|
var ret = fns.sort()
|
||||||
.filter(function(fn) {
|
.filter(function(fn) {
|
||||||
var fullPath = fspath.join(sshkeyDir,fn);
|
var fullPath = fspath.join(dir,fn);
|
||||||
if (fn.length > 2 || fn[0] != ".") {
|
if (fn.length > 2 || fn[0] != ".") {
|
||||||
var stats = fs.lstatSync(fullPath);
|
var stats = fs.lstatSync(fullPath);
|
||||||
if (stats.isFile()) {
|
if (stats.isFile()) {
|
||||||
@ -73,6 +86,10 @@ function listSSHKeys(username) {
|
|||||||
name: filename
|
name: filename
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
}).then(function(result) {
|
||||||
|
return result;
|
||||||
|
}).catch(function() {
|
||||||
|
return []
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,7 +98,13 @@ function getSSHKey(username, name) {
|
|||||||
.then(function(publicSSHKeyPath) {
|
.then(function(publicSSHKeyPath) {
|
||||||
return fs.readFile(publicSSHKeyPath, 'utf-8');
|
return fs.readFile(publicSSHKeyPath, 'utf-8');
|
||||||
}).catch(function() {
|
}).catch(function() {
|
||||||
return null;
|
var privateKeyPath = fspath.join(userSSHKeyDir,name);
|
||||||
|
var publicKeyPath = privateKeyPath+".pub";
|
||||||
|
return checkFilePairExist(privateKeyPath,publicKeyPath).then(function() {
|
||||||
|
return fs.readFile(publicKeyPath, 'utf-8');
|
||||||
|
}).catch(function() {
|
||||||
|
return null
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,29 +139,29 @@ function checkExistSSHKeyFiles(username, name) {
|
|||||||
var sshKeyFileBasename = username + '_' + name;
|
var sshKeyFileBasename = username + '_' + name;
|
||||||
var privateKeyFilePath = fspath.join(sshkeyDir, sshKeyFileBasename);
|
var privateKeyFilePath = fspath.join(sshkeyDir, sshKeyFileBasename);
|
||||||
var publicKeyFilePath = fspath.join(sshkeyDir, sshKeyFileBasename + '.pub');
|
var publicKeyFilePath = fspath.join(sshkeyDir, sshKeyFileBasename + '.pub');
|
||||||
return Promise.all([
|
return checkFilePairExist(privateKeyFilePath,publicKeyFilePath)
|
||||||
fs.access(privateKeyFilePath, (fs.constants || fs).R_OK),
|
.then(function() {
|
||||||
fs.access(publicKeyFilePath , (fs.constants || fs).R_OK)
|
return true;
|
||||||
])
|
})
|
||||||
.then(function() {
|
.catch(function() {
|
||||||
return true;
|
return false;
|
||||||
})
|
});
|
||||||
.catch(function() {
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkSSHKeyFileAndGetPublicKeyFileName(username, name) {
|
function checkSSHKeyFileAndGetPublicKeyFileName(username, name) {
|
||||||
var sshKeyFileBasename = username + '_' + name;
|
var sshKeyFileBasename = username + '_' + name;
|
||||||
var privateKeyFilePath = fspath.join(sshkeyDir, sshKeyFileBasename);
|
var privateKeyFilePath = fspath.join(sshkeyDir, sshKeyFileBasename);
|
||||||
var publicKeyFilePath = fspath.join(sshkeyDir, sshKeyFileBasename + '.pub');
|
var publicKeyFilePath = fspath.join(sshkeyDir, sshKeyFileBasename + '.pub');
|
||||||
|
return checkFilePairExist(privateKeyFilePath,publicKeyFilePath).then(function() {
|
||||||
|
return publicKeyFilePath;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkFilePairExist(privateKeyFilePath,publicKeyFilePath) {
|
||||||
return Promise.all([
|
return Promise.all([
|
||||||
fs.access(privateKeyFilePath, (fs.constants || fs).R_OK),
|
fs.access(privateKeyFilePath, (fs.constants || fs).R_OK),
|
||||||
fs.access(publicKeyFilePath , (fs.constants || fs).R_OK)
|
fs.access(publicKeyFilePath , (fs.constants || fs).R_OK)
|
||||||
])
|
])
|
||||||
.then(function() {
|
|
||||||
return publicKeyFilePath;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function deleteSSHKeyFiles(username, name) {
|
function deleteSSHKeyFiles(username, name) {
|
||||||
@ -149,9 +172,6 @@ function deleteSSHKeyFiles(username, name) {
|
|||||||
fs.remove(privateKeyFilePath),
|
fs.remove(privateKeyFilePath),
|
||||||
fs.remove(publicKeyFilePath)
|
fs.remove(publicKeyFilePath)
|
||||||
])
|
])
|
||||||
.then(function() {
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateSSHKeyPair(name, privateKeyPath, comment, password, size) {
|
function generateSSHKeyPair(name, privateKeyPath, comment, password, size) {
|
||||||
|
@ -33,12 +33,17 @@ describe("storage/localfilesystem/sshkeys", function() {
|
|||||||
trace: function() { }
|
trace: function() { }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
var oldHOME;
|
||||||
|
|
||||||
beforeEach(function(done) {
|
beforeEach(function(done) {
|
||||||
|
oldHOME = process.env.HOME;
|
||||||
|
process.env.HOME = "/tmp/doesnt/exist";
|
||||||
fs.remove(userDir,function(err) {
|
fs.remove(userDir,function(err) {
|
||||||
fs.mkdir(userDir,done);
|
fs.mkdir(userDir,done);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
afterEach(function(done) {
|
afterEach(function(done) {
|
||||||
|
process.env.HOME = oldHOME;
|
||||||
fs.remove(userDir,done);
|
fs.remove(userDir,done);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -463,8 +468,7 @@ describe("storage/localfilesystem/sshkeys", function() {
|
|||||||
sshkeys.init(mockSettings, mockRuntime).then(function() {
|
sshkeys.init(mockSettings, mockRuntime).then(function() {
|
||||||
fs.writeFileSync(path.join(sshkeyDirPath,username+"_"+filename),"","utf8");
|
fs.writeFileSync(path.join(sshkeyDirPath,username+"_"+filename),"","utf8");
|
||||||
fs.writeFileSync(path.join(sshkeyDirPath,username+"_"+filename+".pub"),fileContent,"utf8");
|
fs.writeFileSync(path.join(sshkeyDirPath,username+"_"+filename+".pub"),fileContent,"utf8");
|
||||||
sshkeys.deleteSSHKey(username, filename).then(function(retObj) {
|
sshkeys.deleteSSHKey(username, filename).then(function() {
|
||||||
retObj.should.be.true();
|
|
||||||
fs.existsSync(path.join(sshkeyDirPath,username+'_'+filename)).should.be.false();
|
fs.existsSync(path.join(sshkeyDirPath,username+'_'+filename)).should.be.false();
|
||||||
fs.existsSync(path.join(sshkeyDirPath,username+'_'+filename+'.pub')).should.be.false();
|
fs.existsSync(path.join(sshkeyDirPath,username+'_'+filename+'.pub')).should.be.false();
|
||||||
done();
|
done();
|
||||||
|
Loading…
Reference in New Issue
Block a user