@@ -345,6 +345,181 @@ const ConnectForm: FC<Props> = () => {
345
345
const clientCertFromStoreEnabled =
346
346
connection ?. clientCertFromStore !== undefined ;
347
347
348
+ const manualClientCertSection = (
349
+ < >
350
+ { showCertInput && (
351
+ < Grid item xs = { 12 } >
352
+ < label htmlFor = "cert-file" >
353
+ < input
354
+ style = { { display : 'none' } }
355
+ id = "cert-file"
356
+ ref = { certRef }
357
+ type = "file"
358
+ onChange = { handleCertFile }
359
+ />
360
+ < Button variant = "contained" color = "primary" component = "span" >
361
+ Client Certificate from File
362
+ </ Button >
363
+ </ label >
364
+ </ Grid >
365
+ ) }
366
+ { showCertInput && (
367
+ < Grid item xs = { 12 } >
368
+ < Typography variant = "body2" > Client Certificate Text</ Typography >
369
+ < TextArea
370
+ fullWidth
371
+ variant = "filled"
372
+ value = { certText }
373
+ multiline
374
+ required = { ! ! keyText }
375
+ rows = { 5 }
376
+ placeholder = "e.g. copy/paste the cert in PEM format"
377
+ onChange = { ( evt ) : void => saveCertText ( evt . target . value ) }
378
+ spellCheck = { false }
379
+ />
380
+ < FormHelperText sx = { { pl : 2 } } >
381
+ Add a Client Certificate with the File Selector or Copy/Paste to the
382
+ Text Area. Key is required if the Certificate is present.
383
+ </ FormHelperText >
384
+ </ Grid >
385
+ ) }
386
+ { showCertInput && (
387
+ < Grid item xs = { 12 } >
388
+ < label htmlFor = "key-file" >
389
+ < input
390
+ style = { { display : 'none' } }
391
+ id = "key-file"
392
+ ref = { keyRef }
393
+ type = "file"
394
+ onChange = { handleKeyFile }
395
+ />
396
+ < Button variant = "contained" color = "primary" component = "span" >
397
+ Client Certificate Key from File
398
+ </ Button >
399
+ </ label >
400
+ </ Grid >
401
+ ) }
402
+ { showCertInput && (
403
+ < Grid item xs = { 12 } >
404
+ < Typography variant = "body2" > Client Certificate Key Text</ Typography >
405
+ < TextArea
406
+ fullWidth
407
+ variant = "filled"
408
+ value = { keyText }
409
+ required = { ! ! certText }
410
+ multiline
411
+ rows = { 5 }
412
+ placeholder = "e.g. copy/paste the key in PEM format"
413
+ onChange = { ( evt ) : void => saveKeyText ( evt . target . value ) }
414
+ />
415
+ < FormHelperText sx = { { pl : 2 } } >
416
+ Add a Client Certificate Key with the File Selector or Copy/Paste to
417
+ the Text Area. Certificate is required if the Key is present.
418
+ </ FormHelperText >
419
+ </ Grid >
420
+ ) }
421
+
422
+ { ! showCertInput && (
423
+ < Grid item xs = { 12 } >
424
+ < CertDetails
425
+ open = { showDetail }
426
+ onClose = { ( ) => setShowDetail ( false ) }
427
+ certInfo = { connection ?. clientCert ?. info }
428
+ />
429
+ < Typography variant = "body2" > Client Certificate</ Typography >
430
+ < Chip
431
+ label = "Details"
432
+ color = "primary"
433
+ onClick = { ( ) => setShowDetail ( true ) }
434
+ />
435
+ < IconButton
436
+ aria-label = "delete"
437
+ onClick = { handleDeleteCert }
438
+ color = "primary"
439
+ size = "large"
440
+ >
441
+ < Trash />
442
+ </ IconButton >
443
+ </ Grid >
444
+ ) }
445
+ </ >
446
+ ) ;
447
+
448
+ let clientCertSection = manualClientCertSection ;
449
+ const supportsClientCertFromStore =
450
+ process . platform === 'win32' || process . platform === 'darwin' ;
451
+ if ( supportsClientCertFromStore ) {
452
+ clientCertSection = (
453
+ < >
454
+ < Grid item xs = { 12 } >
455
+ < FormControlLabel
456
+ control = {
457
+ < Switch
458
+ checked = { clientCertFromStoreEnabled }
459
+ color = "primary"
460
+ onChange = { ( evt ) : void =>
461
+ saveClientCertFromStore ( evt . target . checked ? { } : undefined )
462
+ }
463
+ />
464
+ }
465
+ label = "Search OS certificate store"
466
+ />
467
+ < FormHelperText sx = { { pl : 2 } } >
468
+ Searches for a client certificate based on the trusted CA names
469
+ provided in the TLS connection handshake.
470
+ </ FormHelperText >
471
+ </ Grid >
472
+ < NestedAccordion
473
+ sx = { { mt : 2 } }
474
+ disabled = { ! clientCertFromStoreEnabled }
475
+ expanded = { clientCertFiltersExpanded }
476
+ onChange = { ( evt , expanded ) => setClientCertFiltersExpanded ( expanded ) }
477
+ >
478
+ < NestedAccordionSummary >
479
+ < Typography >
480
+ Additional OS certificate store filters
481
+ { ! clientCertFiltersExpanded && clientCertFiltersSummary && (
482
+ < >
483
+ :< br />
484
+ { clientCertFiltersSummary }
485
+ </ >
486
+ ) }
487
+ </ Typography >
488
+ </ NestedAccordionSummary >
489
+ < NestedAccordionDetails >
490
+ { clientCertFromStoreEnabled && (
491
+ < >
492
+ < CertFilter
493
+ label = "Issuer Name"
494
+ data = { connection ?. clientCertFromStore ?. issuerFilter }
495
+ onChange = { saveClientCertIssuerFilter }
496
+ disabled = { ! clientCertFromStoreEnabled }
497
+ />
498
+ < CertFilter
499
+ label = "Subject Name"
500
+ data = { connection ?. clientCertFromStore ?. subjectFilter }
501
+ onChange = { saveClientCertSubjectFilter }
502
+ disabled = { ! clientCertFromStoreEnabled }
503
+ />
504
+ </ >
505
+ ) }
506
+ </ NestedAccordionDetails >
507
+ </ NestedAccordion >
508
+
509
+ < NestedAccordion sx = { { my : 2 } } >
510
+ < NestedAccordionSummary >
511
+ < Typography > Set client certificate manually</ Typography >
512
+ </ NestedAccordionSummary >
513
+ < NestedAccordionDetails >
514
+ < Grid container spacing = { 2 } sx = { { pt : 1 } } >
515
+ { manualClientCertSection }
516
+ </ Grid >
517
+ </ NestedAccordionDetails >
518
+ </ NestedAccordion >
519
+ </ >
520
+ ) ;
521
+ }
522
+
348
523
return (
349
524
< Container maxWidth = { false } >
350
525
< BeforeBackActionDialog
@@ -483,189 +658,7 @@ const ConnectForm: FC<Props> = () => {
483
658
Client certificates
484
659
</ Typography >
485
660
</ Grid >
486
- < Grid item xs = { 12 } >
487
- < FormControlLabel
488
- control = {
489
- < Switch
490
- checked = { clientCertFromStoreEnabled }
491
- color = "primary"
492
- onChange = { ( evt ) : void =>
493
- saveClientCertFromStore (
494
- evt . target . checked ? { } : undefined ,
495
- )
496
- }
497
- />
498
- }
499
- label = "Search OS certificate store"
500
- />
501
- < FormHelperText sx = { { pl : 2 } } >
502
- Searches for a client certificate based on the trusted CA
503
- names provided in the TLS connection handshake.
504
- </ FormHelperText >
505
- </ Grid >
506
- < NestedAccordion
507
- sx = { { mt : 2 } }
508
- disabled = { ! clientCertFromStoreEnabled }
509
- expanded = { clientCertFiltersExpanded }
510
- onChange = { ( evt , expanded ) =>
511
- setClientCertFiltersExpanded ( expanded )
512
- }
513
- >
514
- < NestedAccordionSummary >
515
- < Typography >
516
- Additional OS certificate store filters
517
- { ! clientCertFiltersExpanded && clientCertFiltersSummary && (
518
- < >
519
- :< br />
520
- { clientCertFiltersSummary }
521
- </ >
522
- ) }
523
- </ Typography >
524
- </ NestedAccordionSummary >
525
- < NestedAccordionDetails >
526
- { clientCertFromStoreEnabled && (
527
- < >
528
- < CertFilter
529
- label = "Issuer Name"
530
- data = { connection ?. clientCertFromStore ?. issuerFilter }
531
- onChange = { saveClientCertIssuerFilter }
532
- disabled = { ! clientCertFromStoreEnabled }
533
- />
534
- < CertFilter
535
- label = "Subject Name"
536
- data = { connection ?. clientCertFromStore ?. subjectFilter }
537
- onChange = { saveClientCertSubjectFilter }
538
- disabled = { ! clientCertFromStoreEnabled }
539
- />
540
- </ >
541
- ) }
542
- </ NestedAccordionDetails >
543
- </ NestedAccordion >
544
-
545
- < NestedAccordion sx = { { my : 2 } } >
546
- < NestedAccordionSummary >
547
- < Typography > Set client certificate manually</ Typography >
548
- </ NestedAccordionSummary >
549
- < NestedAccordionDetails >
550
- < Grid container spacing = { 2 } sx = { { pt : 1 } } >
551
- { showCertInput && (
552
- < Grid item xs = { 12 } >
553
- < label htmlFor = "cert-file" >
554
- < input
555
- style = { { display : 'none' } }
556
- id = "cert-file"
557
- ref = { certRef }
558
- type = "file"
559
- onChange = { handleCertFile }
560
- />
561
- < Button
562
- variant = "contained"
563
- color = "primary"
564
- component = "span"
565
- >
566
- Client Certificate from File
567
- </ Button >
568
- </ label >
569
- </ Grid >
570
- ) }
571
- { showCertInput && (
572
- < Grid item xs = { 12 } >
573
- < Typography variant = "body2" >
574
- Client Certificate Text
575
- </ Typography >
576
- < TextArea
577
- fullWidth
578
- variant = "filled"
579
- value = { certText }
580
- multiline
581
- required = { ! ! keyText }
582
- rows = { 5 }
583
- placeholder = "e.g. copy/paste the cert in PEM format"
584
- onChange = { ( evt ) : void =>
585
- saveCertText ( evt . target . value )
586
- }
587
- spellCheck = { false }
588
- />
589
- < FormHelperText sx = { { pl : 2 } } >
590
- Add a Client Certificate with the File Selector or
591
- Copy/Paste to the Text Area. Key is required if the
592
- Certificate is present.
593
- </ FormHelperText >
594
- </ Grid >
595
- ) }
596
- { showCertInput && (
597
- < Grid item xs = { 12 } >
598
- < label htmlFor = "key-file" >
599
- < input
600
- style = { { display : 'none' } }
601
- id = "key-file"
602
- ref = { keyRef }
603
- type = "file"
604
- onChange = { handleKeyFile }
605
- />
606
- < Button
607
- variant = "contained"
608
- color = "primary"
609
- component = "span"
610
- >
611
- Client Certificate Key from File
612
- </ Button >
613
- </ label >
614
- </ Grid >
615
- ) }
616
- { showCertInput && (
617
- < Grid item xs = { 12 } >
618
- < Typography variant = "body2" >
619
- Client Certificate Key Text
620
- </ Typography >
621
- < TextArea
622
- fullWidth
623
- variant = "filled"
624
- value = { keyText }
625
- required = { ! ! certText }
626
- multiline
627
- rows = { 5 }
628
- placeholder = "e.g. copy/paste the key in PEM format"
629
- onChange = { ( evt ) : void =>
630
- saveKeyText ( evt . target . value )
631
- }
632
- />
633
- < FormHelperText sx = { { pl : 2 } } >
634
- Add a Client Certificate Key with the File Selector or
635
- Copy/Paste to the Text Area. Certificate is required
636
- if the Key is present.
637
- </ FormHelperText >
638
- </ Grid >
639
- ) }
640
-
641
- { ! showCertInput && (
642
- < Grid item xs = { 12 } >
643
- < CertDetails
644
- open = { showDetail }
645
- onClose = { ( ) => setShowDetail ( false ) }
646
- certInfo = { connection ?. clientCert ?. info }
647
- />
648
- < Typography variant = "body2" >
649
- Client Certificate
650
- </ Typography >
651
- < Chip
652
- label = "Details"
653
- color = "primary"
654
- onClick = { ( ) => setShowDetail ( true ) }
655
- />
656
- < IconButton
657
- aria-label = "delete"
658
- onClick = { handleDeleteCert }
659
- color = "primary"
660
- size = "large"
661
- >
662
- < Trash />
663
- </ IconButton >
664
- </ Grid >
665
- ) }
666
- </ Grid >
667
- </ NestedAccordionDetails >
668
- </ NestedAccordion >
661
+ { clientCertSection }
669
662
</ Grid >
670
663
</ AccordionDetails >
671
664
</ Accordion >
0 commit comments