@@ -19,30 +19,35 @@ axios.defaults.timeout = 30000;
1919 * @param {string } password The password to use for the login
2020 */
2121async function login ( username , password ) {
22+ console . log ( 'Login' , { username, password, baseUrl } ) ;
2223 try {
23- let response = await axios . post (
24- `${ baseUrl } /api/auth/login` ,
25- {
26- username,
27- password,
28- } ,
29- {
30- headers : { 'Content-Type' : 'application/json' } ,
31- withCredentials : true ,
32- } ,
33- ) ;
34- const cookies = response . headers [ 'set-cookie' ] ;
24+ axios
25+ . post (
26+ `${ baseUrl } /api/auth/login` ,
27+ {
28+ username,
29+ password,
30+ } ,
31+ {
32+ headers : { 'Content-Type' : 'application/json' } ,
33+ withCredentials : true ,
34+ } ,
35+ )
36+ . then ( async ( response ) => {
37+ const cookies = response . headers [ 'set-cookie' ] ;
3538
36- response = await axios . get ( `${ baseUrl } /api/auth/profile` , {
37- headers : { Cookie : cookies } ,
38- withCredentials : true ,
39- } ) ;
39+ response = await axios . get ( `${ baseUrl } /api/auth/profile` , {
40+ headers : { Cookie : cookies } ,
41+ withCredentials : true ,
42+ } ) ;
4043
41- fs . writeFileSync ( GIT_PROXY_COOKIE_FILE , JSON . stringify ( cookies ) , 'utf8' ) ;
44+ fs . writeFileSync ( GIT_PROXY_COOKIE_FILE , JSON . stringify ( cookies ) , 'utf8' ) ;
4245
43- const user = `"${ response . data . username } " <${ response . data . email } >` ;
44- const isAdmin = response . data . admin ? ' (admin)' : '' ;
45- console . log ( `Login ${ user } ${ isAdmin } : OK` ) ;
46+ const user = `"${ response . data . username } " <${ response . data . email } >` ;
47+ const isAdmin = response . data . admin ? ' (admin)' : '' ;
48+ console . log ( `Login ${ user } ${ isAdmin } : OK` ) ;
49+ } )
50+ . catch ( ( loginError ) => console . error ) ;
4651 } catch ( error ) {
4752 if ( error . response ) {
4853 console . error ( `Error: Login '${ username } ': '${ error . response . status } '` ) ;
@@ -306,6 +311,60 @@ async function logout() {
306311 console . log ( 'Logout: OK' ) ;
307312}
308313
314+ /**
315+ * Add SSH key for a user
316+ * @param {string } username The username to add the key for
317+ * @param {string } keyPath Path to the public key file
318+ */
319+ async function addSSHKey ( username , keyPath ) {
320+ console . log ( 'Add SSH key' , { username, keyPath } ) ;
321+ if ( ! fs . existsSync ( GIT_PROXY_COOKIE_FILE ) ) {
322+ console . error ( 'Error: SSH key: Authentication required' ) ;
323+ process . exitCode = 1 ;
324+ return ;
325+ }
326+
327+ try {
328+ const cookies = JSON . parse ( fs . readFileSync ( GIT_PROXY_COOKIE_FILE , 'utf8' ) ) ;
329+ const publicKey = fs . readFileSync ( keyPath , 'utf8' ) . trim ( ) ;
330+
331+ console . log ( 'Adding SSH key' , { username, publicKey } ) ;
332+ await axios . post (
333+ `${ baseUrl } /api/v1/user/${ username } /ssh-keys` ,
334+ { publicKey } ,
335+ {
336+ headers : {
337+ Cookie : cookies ,
338+ 'Content-Type' : 'application/json' ,
339+ } ,
340+ withCredentials : true ,
341+ } ,
342+ ) ;
343+
344+ console . log ( `SSH key added successfully for user ${ username } ` ) ;
345+ } catch ( error ) {
346+ let errorMessage = `Error: SSH key: '${ error . message } '` ;
347+ process . exitCode = 2 ;
348+
349+ if ( error . response ) {
350+ switch ( error . response . status ) {
351+ case 401 :
352+ errorMessage = 'Error: SSH key: Authentication required' ;
353+ process . exitCode = 3 ;
354+ break ;
355+ case 404 :
356+ errorMessage = `Error: SSH key: User '${ username } ' not found` ;
357+ process . exitCode = 4 ;
358+ break ;
359+ }
360+ } else if ( error . code === 'ENOENT' ) {
361+ errorMessage = `Error: SSH key: Could not find key file at ${ keyPath } ` ;
362+ process . exitCode = 5 ;
363+ }
364+ console . error ( errorMessage ) ;
365+ }
366+ }
367+
309368// Parsing command line arguments
310369yargs ( hideBin ( process . argv ) )
311370 . command ( {
@@ -436,6 +495,37 @@ yargs(hideBin(process.argv))
436495 rejectGitPush ( argv . id ) ;
437496 } ,
438497 } )
498+ . command ( {
499+ command : 'ssh-key' ,
500+ describe : 'Manage SSH keys' ,
501+ builder : {
502+ action : {
503+ describe : 'Action to perform (add/remove)' ,
504+ demandOption : true ,
505+ type : 'string' ,
506+ choices : [ 'add' , 'remove' ] ,
507+ } ,
508+ username : {
509+ describe : 'Username to manage keys for' ,
510+ demandOption : true ,
511+ type : 'string' ,
512+ } ,
513+ keyPath : {
514+ describe : 'Path to the public key file' ,
515+ demandOption : true ,
516+ type : 'string' ,
517+ } ,
518+ } ,
519+ handler ( argv ) {
520+ if ( argv . action === 'add' ) {
521+ addSSHKey ( argv . username , argv . keyPath ) ;
522+ } else if ( argv . action === 'remove' ) {
523+ // TODO: Implement remove SSH key
524+ console . error ( 'Error: SSH key: Remove action not implemented yet' ) ;
525+ process . exitCode = 1 ;
526+ }
527+ } ,
528+ } )
439529 . demandCommand ( 1 , 'You need at least one command before moving on' )
440530 . strict ( )
441531 . help ( ) . argv ;
0 commit comments