@@ -86,7 +86,7 @@ const internalAccessList = {
86
86
// re-fetch with expansions
87
87
return internalAccessList . get ( access , {
88
88
id : data . id ,
89
- expand : [ 'owner' , 'items' , 'clients' , 'clientcas' , 'proxy_hosts.access_list.[clientcas.certificate ,clients,items]' ]
89
+ expand : [ 'owner' , 'items' , 'clients' , 'clientcas.certificate ' , 'proxy_hosts.access_list.[clientcas,clients,items]' ]
90
90
} , true /* <- skip masking */ ) ;
91
91
} )
92
92
. then ( ( row ) => {
@@ -247,7 +247,6 @@ const internalAccessList = {
247
247
} ) ;
248
248
}
249
249
} )
250
- . then ( internalNginx . reload )
251
250
. then ( ( ) => {
252
251
// Add to audit log
253
252
return internalAuditLog . add ( access , {
@@ -261,10 +260,11 @@ const internalAccessList = {
261
260
// re-fetch with expansions
262
261
return internalAccessList . get ( access , {
263
262
id : data . id ,
264
- expand : [ 'owner' , 'items' , 'clients' , 'clientcas' , 'proxy_hosts.[certificate,access_list.[clientcas.certificate ,clients,items]]' ]
263
+ expand : [ 'owner' , 'items' , 'clients' , 'clientcas.certificate ' , 'proxy_hosts.[certificate,access_list.[clientcas,clients,items]]' ]
265
264
} , true /* <- skip masking */ ) ;
266
265
} )
267
266
. then ( ( row ) => {
267
+ console . log ( row ) ;
268
268
return internalAccessList . build ( row )
269
269
. then ( ( ) => {
270
270
if ( row . proxy_host_count ) {
@@ -274,6 +274,11 @@ const internalAccessList = {
274
274
. then ( ( ) => {
275
275
return internalAccessList . maskItems ( row ) ;
276
276
} ) ;
277
+ } )
278
+ . then ( ( row ) => {
279
+ return internalNginx . reload ( ) . then ( ( ) => {
280
+ return row ;
281
+ } ) ;
277
282
} ) ;
278
283
} ,
279
284
@@ -299,7 +304,7 @@ const internalAccessList = {
299
304
. joinRaw ( 'LEFT JOIN `proxy_host` ON `proxy_host`.`access_list_id` = `access_list`.`id` AND `proxy_host`.`is_deleted` = 0' )
300
305
. where ( 'access_list.is_deleted' , 0 )
301
306
. andWhere ( 'access_list.id' , data . id )
302
- . withGraphFetched ( '[owner,items,clients,clientcas,proxy_hosts.[certificate,access_list.[clientcas.certificate ,clients,items]]]' )
307
+ . allowGraph ( '[owner,items,clients,clientcas.certificate ,proxy_hosts.[certificate,access_list.[clientcas,clients,items]]]' )
303
308
. first ( ) ;
304
309
305
310
if ( access_data . permission_visibility !== 'all' ) {
@@ -420,7 +425,7 @@ const internalAccessList = {
420
425
. joinRaw ( 'LEFT JOIN `proxy_host` ON `proxy_host`.`access_list_id` = `access_list`.`id` AND `proxy_host`.`is_deleted` = 0' )
421
426
. where ( 'access_list.is_deleted' , 0 )
422
427
. groupBy ( 'access_list.id' )
423
- . withGraphFetched ( '[owner,items,clients,clientcas.certificate]' )
428
+ . allowGraph ( '[owner,items,clients,clientcas.certificate]' )
424
429
. orderBy ( 'access_list.name' , 'ASC' ) ;
425
430
426
431
if ( access_data . permission_visibility !== 'all' ) {
@@ -477,6 +482,8 @@ const internalAccessList = {
477
482
} ,
478
483
479
484
/**
485
+ * Mask sensitive items in access list responses
486
+ *
480
487
* @param {Object } list
481
488
* @returns {Object }
482
489
*/
@@ -496,6 +503,24 @@ const internalAccessList = {
496
503
} ) ;
497
504
}
498
505
506
+ // Mask certificates in clientcas responses
507
+ if ( list && typeof list . clientcas !== 'undefined' ) {
508
+ list . clientcas . map ( function ( val , idx ) {
509
+ if ( typeof val . certificate !== 'undefined' ) {
510
+ list . clientcas [ idx ] . certificate . meta = { } ;
511
+ }
512
+ } ) ;
513
+ }
514
+
515
+ // Mask certificates in ProxyHost responses (clear the meta field)
516
+ if ( list && typeof list . proxy_hosts !== 'undefined' ) {
517
+ list . proxy_hosts . map ( function ( val , idx ) {
518
+ if ( typeof val . certificate !== 'undefined' ) {
519
+ list . proxy_hosts [ idx ] . certificate . meta = { } ;
520
+ }
521
+ } ) ;
522
+ }
523
+
499
524
return list ;
500
525
} ,
501
526
@@ -508,17 +533,27 @@ const internalAccessList = {
508
533
return '/data/access/' + list . id ;
509
534
} ,
510
535
536
+ /**
537
+ * @param {Object } list
538
+ * @param {Integer } list.id
539
+ * @returns {String }
540
+ */
541
+ getClientCAFilename : ( list ) => {
542
+ return '/data/clientca/' + list . id ;
543
+ } ,
544
+
511
545
/**
512
546
* @param {Object } list
513
547
* @param {Integer } list.id
514
548
* @param {String } list.name
515
549
* @param {Array } list.items
550
+ * @param {Array } list.clientcas
516
551
* @returns {Promise }
517
552
*/
518
553
build : ( list ) => {
519
- logger . info ( 'Building Access file #' + list . id + ' for: ' + list . name ) ;
520
554
521
- return new Promise ( ( resolve , reject ) => {
555
+ const htPasswdBuild = new Promise ( ( resolve , reject ) => {
556
+ logger . info ( 'Building Access file #' + list . id + ' for: ' + list . name ) ;
522
557
let htpasswd_file = internalAccessList . getFilename ( list ) ;
523
558
524
559
// 1. remove any existing access file
@@ -566,6 +601,39 @@ const internalAccessList = {
566
601
} ) ;
567
602
}
568
603
} ) ;
604
+
605
+ const caCertificateBuild = new Promise ( ( resolve , reject ) => {
606
+ // TODO: we need to ensure this rebuild is run if any certificates change
607
+ logger . info ( 'Building Client CA file #' + list . id + ' for: ' + list . name ) ;
608
+ let clientca_file = internalAccessList . getClientCAFilename ( list ) ;
609
+
610
+ const certificate_bodies = list . clientcas
611
+ . filter ( ( clientca ) => {
612
+ return typeof clientca . certificate . meta !== 'undefined' ;
613
+ } )
614
+ . map ( ( clientca ) => {
615
+ return clientca . certificate . meta . certificate ;
616
+ } ) ;
617
+
618
+ // Unlink the original file (nginx retains file handle till reload)
619
+ try {
620
+ fs . unlinkSync ( clientca_file ) ;
621
+ } catch ( err ) {
622
+ // do nothing
623
+ }
624
+
625
+ // Write the new file in one shot
626
+ try {
627
+ fs . writeFileSync ( clientca_file , certificate_bodies . join ( '\n' ) , { encoding : 'utf8' } ) ;
628
+ logger . success ( 'Built Client CA file #' + list . id + ' for: ' + list . name ) ;
629
+ resolve ( clientca_file ) ;
630
+ } catch ( err ) {
631
+ reject ( err ) ;
632
+ }
633
+ } ) ;
634
+
635
+ // Execute both promises concurrently
636
+ return Promise . all ( [ htPasswdBuild , caCertificateBuild ] ) ;
569
637
}
570
638
} ;
571
639
0 commit comments