2017-12-05 17:14:20 +01:00
/ * *
* Copyright JS Foundation and other contributors , http : //js.foundation
*
* Licensed under the Apache License , Version 2.0 ( the "License" ) ;
* you may not use this file except in compliance with the License .
* You may obtain a copy of the License at
*
* http : //www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing , software
* distributed under the License is distributed on an "AS IS" BASIS ,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
* See the License for the specific language governing permissions and
* limitations under the License .
* * /
RED . projects . userSettings = ( function ( ) {
2017-12-06 00:50:32 +01:00
var gitUsernameInput ;
var gitEmailInput ;
2017-12-05 17:14:20 +01:00
2017-12-21 00:45:17 +01:00
function createGitUserSection ( pane ) {
2017-12-06 00:50:32 +01:00
var currentGitSettings = RED . settings . get ( 'git' ) || { } ;
currentGitSettings . user = currentGitSettings . user || { } ;
var title = $ ( '<h3></h3>' ) . text ( "Committer Details" ) . appendTo ( pane ) ;
2017-12-21 00:45:17 +01:00
var gitconfigContainer = $ ( '<div class="user-settings-section"></div>' ) . appendTo ( pane ) ;
2017-12-06 00:50:32 +01:00
$ ( '<div style="color:#aaa;"></div>' ) . appendTo ( gitconfigContainer ) . text ( "Leave blank to use system default" ) ;
2017-12-05 17:14:20 +01:00
2017-12-06 00:50:32 +01:00
var row = $ ( '<div class="user-settings-row"></div>' ) . appendTo ( gitconfigContainer ) ;
$ ( '<label for=""></label>' ) . text ( 'Username' ) . appendTo ( row ) ;
gitUsernameInput = $ ( '<input type="text">' ) . appendTo ( row ) ;
gitUsernameInput . val ( currentGitSettings . user . name || "" ) ;
row = $ ( '<div class="user-settings-row"></div>' ) . appendTo ( gitconfigContainer ) ;
$ ( '<label for=""></label>' ) . text ( 'Email' ) . appendTo ( row ) ;
gitEmailInput = $ ( '<input type="text">' ) . appendTo ( row ) ;
gitEmailInput . val ( currentGitSettings . user . email || "" ) ;
2017-12-21 00:45:17 +01:00
}
2017-12-15 16:07:47 +01:00
2017-12-21 00:45:17 +01:00
function createSSHKeySection ( pane ) {
var container = $ ( '<div class="user-settings-section"></div>' ) . appendTo ( pane ) ;
var popover ;
2018-01-10 18:37:41 +01:00
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." ) ;
2017-12-21 00:45:17 +01:00
2018-01-11 13:56:49 +01:00
var addKeyButton = $ ( '<button id="user-settings-gitconfig-add-key" class="editor-button editor-button-small" style="float: right; margin-right: 10px;">add key</button>' )
2018-01-10 18:37:41 +01:00
. appendTo ( subtitle )
2017-12-15 16:07:47 +01:00
. click ( function ( evt ) {
2017-12-21 00:45:17 +01:00
addKeyButton . attr ( 'disabled' , true ) ;
2018-01-10 18:37:41 +01:00
saveButton . attr ( 'disabled' , true ) ;
// bg.children().removeClass("selected");
// addLocalButton.click();
2017-12-21 18:40:24 +01:00
addKeyDialog . slideDown ( 200 ) ;
keyNameInput . focus ( ) ;
2017-12-21 00:45:17 +01:00
} ) ;
var validateForm = function ( ) {
2018-01-10 18:37:41 +01:00
var valid = /^[a-zA-Z0-9\-_]+$/ . test ( keyNameInput . val ( ) ) ;
keyNameInput . toggleClass ( 'input-error' , keyNameInputChanged && ! valid ) ;
// var selectedButton = bg.find(".selected");
// if (selectedButton[0] === addLocalButton[0]) {
// valid = valid && localPublicKeyPathInput.val().length > 0 && localPrivateKeyPathInput.val().length > 0;
// } else if (selectedButton[0] === uploadButton[0]) {
// valid = valid && publicKeyInput.val().length > 0 && privateKeyInput.val().length > 0;
// } else if (selectedButton[0] === generateButton[0]) {
var passphrase = passphraseInput . val ( ) ;
var validPassphrase = passphrase . length === 0 || passphrase . length >= 8 ;
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 ) ;
2017-12-21 18:40:24 +01:00
2017-12-21 00:45:17 +01:00
if ( popover ) {
popover . close ( ) ;
popover = null ;
2017-12-15 16:07:47 +01:00
}
} ;
2017-12-21 00:45:17 +01:00
var row = $ ( '<div class="user-settings-row"></div>' ) . appendTo ( container ) ;
var addKeyDialog = $ ( '<div class="projects-dialog-list-dialog"></div>' ) . hide ( ) . appendTo ( row ) ;
2018-01-10 18:37:41 +01:00
$ ( '<div class="projects-dialog-list-dialog-header">' ) . text ( 'Add SSH Key' ) . appendTo ( addKeyDialog ) ;
2017-12-21 18:40:24 +01:00
var addKeyDialogBody = $ ( '<div>' ) . appendTo ( addKeyDialog ) ;
2018-01-10 18:37:41 +01:00
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();
// })
2017-12-21 18:40:24 +01:00
row = $ ( '<div class="user-settings-row"></div>' ) . appendTo ( addKeyDialogBody ) ;
2017-12-21 00:45:17 +01:00
$ ( '<label for=""></label>' ) . text ( 'Name' ) . appendTo ( row ) ;
2018-01-10 18:37:41 +01:00
var keyNameInputChanged = false ;
2017-12-21 00:45:17 +01:00
var keyNameInput = $ ( '<input type="text">' ) . appendTo ( row ) . on ( "change keyup paste" , function ( ) {
keyNameInputChanged = true ;
validateForm ( ) ;
} ) ;
$ ( '<label class="projects-edit-form-sublabel"><small>Must contain only A-Z 0-9 _ -</small></label>' ) . appendTo ( row ) . find ( "small" ) ;
2018-01-10 18:37:41 +01:00
var generateKeyPane = $ ( '<div>' ) . appendTo ( addKeyDialogBody ) ;
row = $ ( '<div class="user-settings-row"></div>' ) . appendTo ( generateKeyPane ) ;
2017-12-21 00:45:17 +01:00
$ ( '<label for=""></label>' ) . text ( 'Passphrase' ) . appendTo ( row ) ;
2018-01-10 18:37:41 +01:00
var passphraseInput = $ ( '<input type="password">' ) . appendTo ( row ) . on ( "change keyup paste" , validateForm ) ;
2017-12-21 18:40:24 +01:00
var passphraseInputSubLabel = $ ( '<label class="projects-edit-form-sublabel"><small>Optional</small></label>' ) . appendTo ( row ) . find ( "small" ) ;
2017-12-21 00:45:17 +01:00
2018-01-10 18:37:41 +01:00
// 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");
2017-12-21 00:45:17 +01:00
var hideEditForm = function ( ) {
addKeyButton . attr ( 'disabled' , false ) ;
addKeyDialog . hide ( ) ;
2018-01-10 18:37:41 +01:00
2017-12-21 00:45:17 +01:00
keyNameInput . val ( "" ) ;
2018-01-10 18:37:41 +01:00
keyNameInputChanged = false ;
2017-12-21 00:45:17 +01:00
passphraseInput . val ( "" ) ;
2018-01-10 18:37:41 +01:00
// localPublicKeyPathInput.val("");
// localPrivateKeyPathInput.val("");
// publicKeyInput.val("");
// privateKeyInput.val("");
2017-12-21 00:45:17 +01:00
if ( popover ) {
popover . close ( ) ;
popover = null ;
2017-12-15 16:07:47 +01:00
}
}
2017-12-21 00:45:17 +01:00
var formButtons = $ ( '<span class="button-row" style="position: relative; float: right; margin: 10px;"></span>' ) . appendTo ( addKeyDialog ) ;
2017-12-15 16:07:47 +01:00
$ ( '<button class="editor-button">Cancel</button>' )
. appendTo ( formButtons )
. click ( function ( evt ) {
evt . preventDefault ( ) ;
2017-12-21 00:45:17 +01:00
hideEditForm ( ) ;
2017-12-15 16:07:47 +01:00
} ) ;
2017-12-21 00:45:17 +01:00
var saveButton = $ ( '<button class="editor-button">Generate key</button>' )
2017-12-15 16:07:47 +01:00
. appendTo ( formButtons )
. click ( function ( evt ) {
evt . preventDefault ( ) ;
2017-12-21 00:45:17 +01:00
var spinner = utils . addSpinnerOverlay ( addKeyDialog ) . addClass ( 'projects-dialog-spinner-contain' ) ;
var payload = {
2018-01-10 18:37:41 +01:00
name : keyNameInput . val ( )
2017-12-21 00:45:17 +01:00
} ;
2018-01-10 18:37:41 +01:00
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 ;
}
2017-12-21 00:45:17 +01:00
var done = function ( err ) {
spinner . remove ( ) ;
if ( err ) {
return ;
}
hideEditForm ( ) ;
2017-12-15 16:07:47 +01:00
}
2017-12-21 00:45:17 +01:00
// console.log(JSON.stringify(payload,null,4));
RED . deploy . setDeployInflight ( true ) ;
utils . sendRequest ( {
url : "settings/user/keys" ,
type : "POST" ,
responses : {
0 : function ( error ) {
done ( error ) ;
2017-12-17 16:53:03 +01:00
} ,
2017-12-21 00:45:17 +01:00
200 : function ( data ) {
2017-12-21 18:40:24 +01:00
refreshSSHKeyList ( payload . name ) ;
2017-12-21 00:45:17 +01:00
done ( ) ;
2017-12-15 16:07:47 +01:00
} ,
2017-12-21 00:45:17 +01:00
400 : {
'unexpected_error' : function ( error ) {
console . log ( error ) ;
done ( error ) ;
2017-12-15 16:07:47 +01:00
}
2017-12-21 00:45:17 +01:00
} ,
}
} , payload ) ;
} ) ;
row = $ ( '<div class="user-settings-row projects-dialog-list"></div>' ) . appendTo ( container ) ;
var emptyItem = { empty : true } ;
var expandKey = function ( container , entry ) {
var row = $ ( '<div class="projects-dialog-ssh-public-key">' , { style : "position:relative" } ) . appendTo ( container ) ;
var keyBox = $ ( '<pre>' , { style : "min-height: 80px" } ) . appendTo ( row ) ;
var spinner = utils . addSpinnerOverlay ( keyBox ) . addClass ( 'projects-dialog-spinner-contain' ) ;
var options = {
url : 'settings/user/keys/' + entry . name ,
type : "GET" ,
responses : {
200 : function ( data ) {
keyBox . text ( data . publickey ) ;
spinner . remove ( ) ;
} ,
400 : {
'unexpected_error' : function ( error ) {
console . log ( error ) ;
spinner . remove ( ) ;
2017-12-15 16:07:47 +01:00
}
2017-12-21 00:45:17 +01:00
} ,
2017-12-15 16:07:47 +01:00
}
2017-12-21 00:45:17 +01:00
}
utils . sendRequest ( options ) ;
var formButtons = $ ( '<span class="button-row" style="position: relative; float: right; margin: 10px;"></span>' ) . appendTo ( row ) ;
2017-12-21 18:40:24 +01:00
$ ( '<button class="editor-button editor-button-small">Copy to clipboard</button>' )
2017-12-21 00:45:17 +01:00
. appendTo ( formButtons )
. click ( function ( evt ) {
2018-01-10 18:37:41 +01:00
evt . stopPropagation ( ) ;
2017-12-21 00:45:17 +01:00
evt . preventDefault ( ) ;
document . getSelection ( ) . selectAllChildren ( keyBox [ 0 ] ) ;
var ret = document . execCommand ( 'copy' ) ;
document . getSelection ( ) . empty ( ) ;
} ) ;
return row ;
}
2018-01-10 18:37:41 +01:00
var keyList = $ ( '<ol class="projects-dialog-ssh-key-list">' ) . appendTo ( row ) . editableList ( {
2017-12-21 00:45:17 +01:00
height : 'auto' ,
addButton : false ,
scrollOnAdd : false ,
addItem : function ( row , index , entry ) {
var container = $ ( '<div class="projects-dialog-list-entry">' ) . appendTo ( row ) ;
if ( entry . empty ) {
container . addClass ( 'red-ui-search-empty' ) ;
container . text ( "No SSH keys" ) ;
return ;
}
$ ( '<span class="entry-icon"><i class="fa fa-key"></i></span>' ) . appendTo ( container ) ;
var content = $ ( '<span>' ) . appendTo ( container ) ;
var topRow = $ ( '<div>' ) . appendTo ( content ) ;
$ ( '<span class="entry-name">' ) . text ( entry . name ) . appendTo ( topRow ) ;
var tools = $ ( '<span class="button-row entry-tools">' ) . appendTo ( container ) ;
var expandedRow ;
2018-01-10 18:37:41 +01:00
row . click ( function ( e ) {
if ( expandedRow ) {
expandedRow . slideUp ( 200 , function ( ) {
expandedRow . remove ( ) ;
expandedRow = null ;
} )
} else {
expandedRow = expandKey ( container , entry ) ;
}
2017-12-21 00:45:17 +01:00
} )
2018-01-10 18:37:41 +01:00
if ( ! entry . system ) {
$ ( '<button class="editor-button editor-button-small"><i class="fa fa-trash"></i></button>' )
. appendTo ( tools )
. click ( function ( e ) {
e . stopPropagation ( ) ;
var spinner = utils . addSpinnerOverlay ( row ) . addClass ( 'projects-dialog-spinner-contain' ) ;
var notification = RED . notify ( "Are you sure you want to delete the SSH key '" + entry . name + "'? This cannot be undone." , {
type : 'warning' ,
modal : true ,
fixed : true ,
buttons : [
{
text : RED . _ ( "common.label.cancel" ) ,
click : function ( ) {
spinner . remove ( ) ;
notification . close ( ) ;
}
} ,
{
text : "Delete key" ,
click : function ( ) {
notification . close ( ) ;
var url = "settings/user/keys/" + entry . name ;
var options = {
url : url ,
type : "DELETE" ,
responses : {
200 : function ( data ) {
row . fadeOut ( 200 , function ( ) {
keyList . editableList ( 'removeItem' , entry ) ;
setTimeout ( spinner . remove , 100 ) ;
if ( keyList . editableList ( 'length' ) === 0 ) {
keyList . editableList ( 'addItem' , emptyItem ) ;
}
} ) ;
} ,
400 : {
'unexpected_error' : function ( error ) {
console . log ( error ) ;
spinner . remove ( ) ;
2017-12-21 00:45:17 +01:00
}
2018-01-10 18:37:41 +01:00
} ,
}
2017-12-21 00:45:17 +01:00
}
2018-01-10 18:37:41 +01:00
utils . sendRequest ( options ) ;
2017-12-21 00:45:17 +01:00
}
}
2018-01-10 18:37:41 +01:00
]
} ) ;
2017-12-21 00:45:17 +01:00
} ) ;
2018-01-10 18:37:41 +01:00
}
2017-12-21 18:40:24 +01:00
if ( entry . expand ) {
expandedRow = expandKey ( container , entry ) ;
}
2017-12-21 00:45:17 +01:00
}
} ) ;
2017-12-21 18:40:24 +01:00
var refreshSSHKeyList = function ( justAdded ) {
2017-12-21 00:45:17 +01:00
$ . getJSON ( "settings/user/keys" , function ( result ) {
if ( result . keys ) {
result . keys . sort ( function ( A , B ) {
return A . name . localeCompare ( B . name ) ;
} ) ;
keyList . editableList ( 'empty' ) ;
result . keys . forEach ( function ( key ) {
2017-12-21 18:40:24 +01:00
if ( key . name === justAdded ) {
key . expand = true ;
}
2017-12-21 00:45:17 +01:00
keyList . editableList ( 'addItem' , key ) ;
2018-01-10 18:37:41 +01:00
} ) ;
if ( keyList . editableList ( 'length' ) === 0 ) {
keyList . editableList ( 'addItem' , emptyItem ) ;
}
2017-12-21 00:45:17 +01:00
}
} )
}
refreshSSHKeyList ( ) ;
2017-12-15 16:07:47 +01:00
}
2017-12-06 00:50:32 +01:00
function createSettingsPane ( activeProject ) {
var pane = $ ( '<div id="user-settings-tab-gitconfig" class="project-settings-tab-pane node-help"></div>' ) ;
2017-12-21 00:45:17 +01:00
createGitUserSection ( pane ) ;
createSSHKeySection ( pane ) ;
2017-12-06 00:50:32 +01:00
return pane ;
}
var utils ;
function init ( _utils ) {
utils = _utils ;
RED . userSettings . add ( {
id : 'gitconfig' ,
title : "Git config" , // TODO: nls
get : createSettingsPane ,
close : function ( ) {
var currentGitSettings = RED . settings . get ( 'git' ) || { } ;
currentGitSettings . user = currentGitSettings . user || { } ;
currentGitSettings . user . name = gitUsernameInput . val ( ) ;
currentGitSettings . user . email = gitEmailInput . val ( ) ;
RED . settings . set ( 'git' , currentGitSettings ) ;
}
} ) ;
}
2017-12-05 17:14:20 +01:00
2017-12-06 00:50:32 +01:00
return {
init : init ,
} ;
} ) ( ) ;