1616
1717RED . projects . userSettings = ( function ( ) {
1818
19+ var gitconfigContainer ;
1920 var gitUsernameInput ;
2021 var gitEmailInput ;
2122
@@ -24,11 +25,9 @@ RED.projects.userSettings = (function() {
2425 var currentGitSettings = RED . settings . get ( 'git' ) || { } ;
2526 currentGitSettings . user = currentGitSettings . user || { } ;
2627
27-
28-
2928 var title = $ ( '<h3></h3>' ) . text ( "Committer Details" ) . appendTo ( pane ) ;
3029
31- var gitconfigContainer = $ ( '<div class="user-settings-section"></div>' ) . appendTo ( pane ) ;
30+ gitconfigContainer = $ ( '<div class="user-settings-section"></div>' ) . appendTo ( pane ) ;
3231 $ ( '<div style="color:#aaa;"></div>' ) . appendTo ( gitconfigContainer ) . text ( "Leave blank to use system default" ) ;
3332
3433 var row = $ ( '<div class="user-settings-row"></div>' ) . appendTo ( gitconfigContainer ) ;
@@ -40,77 +39,245 @@ RED.projects.userSettings = (function() {
4039 $ ( '<label for=""></label>' ) . text ( 'Email' ) . appendTo ( row ) ;
4140 gitEmailInput = $ ( '<input type="text">' ) . appendTo ( row ) ;
4241 gitEmailInput . val ( currentGitSettings . user . email || "" ) ;
43- // var sshkeyTitle = $('<h4></h4>').text("SSH Keys").appendTo(gitconfigContainer);
44- // var generateSshKeyButton = $('<button class="editor-button editor-button-small" style="float: right;">generate new ssh key</button>')
45- // .appendTo(sshkeyTitle)
46- // .click(function(evt) {
47- // console.log('click generateSshKeyButton');
48- // });
49-
50- // row = $('<div class="user-settings-row projects-dialog-remote-list"></div>').appendTo(gitconfigContainer);
51- // var sshkeysList = $('<ol>').appendTo(row);
52- // sshkeysList.editableList({
53- // addButton: false,
54- // height: 'auto',
55- // addItem: function(outer,index,entry) {
56-
57- // var header = $('<div class="projects-dialog-remote-list-entry-header"></div>').appendTo(outer);
58- // entry.header = $('<span>').text(entry.path||"Add new remote").appendTo(header);
59- // var body = $('<div>').appendTo(outer);
60- // entry.body = body;
61- // if (entry.path) {
62- // entry.removeButton = $('<button class="editor-button editor-button-small projects-dialog-remote-list-entry-delete">remove</button>')
63- // // .hide()
64- // .appendTo(header)
65- // .click(function(e) {
66- // entry.removed = true;
67- // body.fadeOut(100);
68- // entry.header.css("text-decoration","line-through")
69- // entry.header.css("font-style","italic")
70- // if (entry.copyToClipboard) {
71- // entry.copyToClipboard.hide();
72- // }
73- // $(this).hide();
74- // });
75- // if (entry.data) {
76- // entry.copyToClipboard = $('<button class="editor-button editor-button-small projects-dialog-remote-list-entry-copy">copy</button>')
77- // // .hide()
78- // .appendTo(header)
79- // .click(function(e) {
80- // var textarea = document.createElement("textarea");
81- // textarea.style.position = 'fixed';
82- // textarea.style.top = 0;
83- // textarea.style.left = 0;
84- // textarea.style.width = '2em';
85- // textarea.style.height = '2em';
86- // textarea.style.padding = 0;
87- // textarea.style.border = 'none';
88- // textarea.style.outline = 'none';
89- // textarea.style.boxShadow = 'none';
90- // textarea.style.background = 'transparent';
91- // textarea.value = entry.data;
92- // document.body.appendChild(textarea);
93- // textarea.select();
94- // try {
95- // var ret = document.execCommand('copy');
96- // var msg = ret ? 'successful' : 'unsuccessful';
97- // console.log('Copy text command was ' + msg);
98- // } catch (err) {
99- // console.log('Oops unable to copy');
100- // }
101- // document.body.removeChild(textarea);
102- // });
103- // }
104- // }
105- // }
106- // });
107-
108- // var remoteListAddButton = row.find(".red-ui-editableList-addButton").hide();
42+
43+ var sshkeyTitle = $ ( '<h4></h4>' ) . text ( "SSH Keys" ) . appendTo ( gitconfigContainer ) ;
44+ var editSshKeyListButton = $ ( '<button class="editor-button editor-button-small" style="float: right;">edit</button>' )
45+ . appendTo ( sshkeyTitle )
46+ . click ( function ( evt ) {
47+ editSshKeyListButton . hide ( ) ;
48+ formButtons . show ( ) ;
49+ sshkeyInputRow . show ( ) ;
50+ $ ( ".projects-dialog-sshkey-list-button-remove" ) . css ( 'display' , 'inline-block' ) ;
51+ } ) ;
52+
53+ var sshkeyListOptions = {
54+ height : "300px" ,
55+ deleteAction : function ( entry , header ) {
56+ sendSSHKeyManagementAPI ( "DELETE_KEY" , entry . name , function ( data ) {
57+ hideSSHKeyGenerateForm ( ) ;
58+ utils . refreshSSHKeyList ( sshkeysList ) ;
59+ } ) ;
60+ } ,
61+ selectAction : function ( entry , header ) {
62+ sendSSHKeyManagementAPI ( "GET_KEY_DETAIL" , entry . name , function ( data ) {
63+ setDialogContext ( entry . name , data . publickey ) ;
64+ dialog . dialog ( "open" ) ;
65+ } ) ;
66+ }
67+ } ;
68+ var sshkeysListRow = $ ( '<div class="user-settings-row projects-dialog-sshkeylist"></div>' ) . appendTo ( gitconfigContainer ) ;
69+ var sshkeysList = utils . createSSHKeyList ( sshkeyListOptions ) . appendTo ( sshkeysListRow ) ;
70+
71+ var sshkeyInputRow = $ ( '<div class="user-settings-row"></div>' ) . hide ( ) . appendTo ( gitconfigContainer ) ;
72+ var sshkeyNameLabel = $ ( '<label for=""></label>' ) . text ( 'Key Name' ) . appendTo ( sshkeyInputRow ) ;
73+ var sshkeyNameInput = $ ( '<input type="text">' ) . appendTo ( sshkeyInputRow ) ;
74+ var sshkeyPassphraseLabel = $ ( '<label for=""></label>' ) . text ( 'Passphrase' ) . appendTo ( sshkeyInputRow ) ;
75+ var sshkeyPassphraseInput = $ ( '<input type="password">' ) . appendTo ( sshkeyInputRow ) ;
76+ var sshkeySamePassphraseLabel = $ ( '<label for=""></label>' ) . text ( 'Same Passphrase' ) . appendTo ( sshkeyInputRow ) ;
77+ var sshkeySamePassphraseInput = $ ( '<input type="password">' ) . appendTo ( sshkeyInputRow ) ;
78+
79+ var formButtonArea = $ ( '<div style="width: 100%; height: 35px;"></div>' ) . appendTo ( gitconfigContainer ) ;
80+ var formButtons = $ ( '<span class="button-group" style="position: absolute; right: 0px; margin-right: 0px;"></span>' )
81+ . hide ( ) . appendTo ( formButtonArea ) ;
82+
83+ function hideSSHKeyGenerateForm ( ) {
84+ editSshKeyListButton . show ( ) ;
85+ formButtons . hide ( ) ;
86+ sshkeyInputRow . hide ( ) ;
87+ sshkeyNameInput . val ( "" ) ;
88+ sshkeyPassphraseInput . val ( "" ) ;
89+ sshkeySamePassphraseInput . val ( "" ) ;
90+ if ( sshkeyNameInput . hasClass ( 'input-error' ) ) {
91+ sshkeyNameInput . removeClass ( 'input-error' ) ;
92+ }
93+ if ( sshkeyPassphraseInput . hasClass ( 'input-error' ) ) {
94+ sshkeyPassphraseInput . removeClass ( 'input-error' ) ;
95+ }
96+ if ( sshkeySamePassphraseInput . hasClass ( 'input-error' ) ) {
97+ sshkeySamePassphraseInput . removeClass ( 'input-error' ) ;
98+ }
99+ $ ( ".projects-dialog-sshkey-list-button-remove" ) . hide ( ) ;
100+ }
101+
102+ $ ( '<button class="editor-button">Cancel</button>' )
103+ . appendTo ( formButtons )
104+ . click ( function ( evt ) {
105+ evt . preventDefault ( ) ;
106+ hideSSHKeyGenerateForm ( ) ;
107+ } ) ;
108+ var generateButton = $ ( '<button class="editor-button">Generate</button>' )
109+ . appendTo ( formButtons )
110+ . click ( function ( evt ) {
111+ evt . preventDefault ( ) ;
112+ if ( sshkeyNameInput . hasClass ( 'input-error' ) ) {
113+ sshkeyNameInput . removeClass ( 'input-error' ) ;
114+ }
115+ if ( sshkeyPassphraseInput . hasClass ( 'input-error' ) ) {
116+ sshkeyPassphraseInput . removeClass ( 'input-error' ) ;
117+ }
118+ if ( sshkeySamePassphraseInput . hasClass ( 'input-error' ) ) {
119+ sshkeySamePassphraseInput . removeClass ( 'input-error' ) ;
120+ }
121+ var valid = true ;
122+ if ( sshkeyNameInput . val ( ) === "" ) {
123+ sshkeyNameInput . addClass ( 'input-error' ) ;
124+ valid = false ;
125+ }
126+ if ( sshkeyPassphraseInput . val ( ) !== sshkeySamePassphraseInput . val ( ) ) {
127+ sshkeySamePassphraseInput . addClass ( 'input-error' ) ;
128+ valid = false ;
129+ }
130+ if ( valid ) {
131+ sendSSHKeyManagementAPI ( "GENERATE_KEY" ,
132+ {
133+ name : sshkeyNameInput . val ( ) ,
134+ email : gitEmailInput . val ( ) ,
135+ password : sshkeyPassphraseInput . val ( ) ,
136+ size : 4096
137+ } ,
138+ function ( ) {
139+ hideSSHKeyGenerateForm ( ) ;
140+ utils . refreshSSHKeyList ( sshkeysList ) ;
141+ } ,
142+ function ( err ) {
143+ console . log ( 'err message:' , err . message ) ;
144+ if ( err . message . includes ( 'Some SSH Keyfile exists' ) ) {
145+ sshkeyNameInput . addClass ( 'input-error' ) ;
146+ }
147+ else if ( err . message . includes ( 'Failed to generate ssh key files' ) ) {
148+ sshkeyPassphraseInput . addClass ( 'input-error' ) ;
149+ sshkeySamePassphraseInput . addClass ( 'input-error' ) ;
150+ }
151+ }
152+ ) ;
153+ }
154+ } ) ;
155+ }
156+
157+ function sendSSHKeyManagementAPI ( type , param , successCallback , failCallback ) {
158+ var url ;
159+ var method ;
160+ var payload ;
161+ switch ( type ) {
162+ case 'GET_KEY_LIST' :
163+ method = 'GET' ;
164+ url = "settings/user/keys" ;
165+ break ;
166+ case 'GET_KEY_DETAIL' :
167+ method = 'GET' ;
168+ url = "settings/user/keys/" + param ;
169+ break ;
170+ case 'GENERATE_KEY' :
171+ method = 'POST' ;
172+ url = "settings/user/keys" ;
173+ payload = param ;
174+ break ;
175+ case 'DELETE_KEY' :
176+ method = 'DELETE' ;
177+ url = "settings/user/keys/" + param ;
178+ break ;
179+ default :
180+ console . error ( 'Unexpected type....' ) ;
181+ return ;
182+ }
183+ var spinner = utils . addSpinnerOverlay ( gitconfigContainer ) ;
184+
185+ var done = function ( err ) {
186+ spinner . remove ( ) ;
187+ if ( err ) {
188+ console . log ( err ) ;
189+ return ;
190+ }
191+ } ;
192+
193+ console . log ( 'method:' , method ) ;
194+ console . log ( 'url:' , url ) ;
195+
196+ utils . sendRequest ( {
197+ url : url ,
198+ type : method ,
199+ responses : {
200+ 0 : function ( error ) {
201+ if ( failCallback ) {
202+ failCallback ( error ) ;
203+ }
204+ done ( error ) ;
205+ } ,
206+ 200 : function ( data ) {
207+ if ( successCallback ) {
208+ successCallback ( data ) ;
209+ }
210+ done ( ) ;
211+ } ,
212+ 400 : {
213+ 'unexpected_error' : function ( error ) {
214+ console . log ( error ) ;
215+ if ( failCallback ) {
216+ failCallback ( error ) ;
217+ }
218+ done ( error ) ;
219+ }
220+ } ,
221+ }
222+ } , payload ) ;
223+ }
224+
225+ var dialog ;
226+ var dialogBody ;
227+ function createPublicKeyDialog ( ) {
228+ dialog = $ ( '<div id="projects-dialog" class="hide node-red-dialog projects-edit-form"><form class="form-horizontal"></form></div>' )
229+ . appendTo ( "body" )
230+ . dialog ( {
231+ modal : true ,
232+ autoOpen : false ,
233+ width : 600 ,
234+ resize : false ,
235+ open : function ( e ) {
236+ $ ( this ) . parent ( ) . find ( ".ui-dialog-titlebar-close" ) . hide ( ) ;
237+ } ,
238+ close : function ( e ) {
239+
240+ }
241+ } ) ;
242+ dialogBody = dialog . find ( "form" ) ;
243+ dialog . dialog ( 'option' , 'title' , 'SSH public key' ) ;
244+ dialog . dialog ( 'option' , 'buttons' , [
245+ {
246+ text : RED . _ ( "common.label.close" ) ,
247+ click : function ( ) {
248+ $ ( this ) . dialog ( "close" ) ;
249+ }
250+ } ,
251+ {
252+ text : "Copy to Clipboard" ,
253+ click : function ( ) {
254+ var target = document . getElementById ( 'public-key-data' ) ;
255+ document . getSelection ( ) . selectAllChildren ( target ) ;
256+ var ret = document . execCommand ( 'copy' ) ;
257+ var msg = ret ? 'successful' : 'unsuccessful' ;
258+ console . log ( 'Copy text command was ' + msg ) ;
259+ $ ( this ) . dialog ( "close" ) ;
260+ }
261+ }
262+ ] ) ;
263+ dialog . dialog ( { position : { 'my' : 'center' , 'at' : 'center' , 'of' : window } } ) ;
264+ var container = $ ( '<div class="projects-dialog-screen-start"></div>' ) ;
265+ $ ( '<div class="projects-dialog-ssh-public-key-name"></div>' ) . appendTo ( container ) ;
266+ $ ( '<div class="projects-dialog-ssh-public-key"><pre id="public-key-data"></pre></div>' ) . appendTo ( container ) ;
267+ dialogBody . append ( container ) ;
268+ }
269+
270+ function setDialogContext ( name , data ) {
271+ var title = dialog . find ( "div.projects-dialog-ssh-public-key-name" ) ;
272+ title . text ( name ) ;
273+ var context = dialog . find ( "div.projects-dialog-ssh-public-key>pre" ) ;
274+ context . text ( data ) ;
109275 }
110276
111277 function createSettingsPane ( activeProject ) {
112278 var pane = $ ( '<div id="user-settings-tab-gitconfig" class="project-settings-tab-pane node-help"></div>' ) ;
113279 createRemoteRepositorySection ( pane ) ;
280+ createPublicKeyDialog ( ) ;
114281 return pane ;
115282 }
116283
0 commit comments