ante-erp-cli 1.11.55 → 1.11.56

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin/ante-cli.js CHANGED
@@ -334,6 +334,7 @@ program
334
334
  .option('--backend-client <url>', 'Backend Client API domain/URL (non-interactive mode)')
335
335
  .option('--detect', 'Auto-detect public IP address')
336
336
  .option('--ssl, --enable-ssl', 'Enable SSL certificate (Let\'s Encrypt)')
337
+ .option('--cloudflare-ssl', 'Enable Cloudflare SSL mode (self-signed cert for Full mode)')
337
338
  .option('--email <email>', 'Email for SSL certificate notifications')
338
339
  .option('--ssl-staging', 'Use Let\'s Encrypt staging environment (for testing)')
339
340
  .option('--no-interactive', 'Non-interactive mode')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ante-erp-cli",
3
- "version": "1.11.55",
3
+ "version": "1.11.56",
4
4
  "description": "Comprehensive CLI tool for managing ANTE ERP self-hosted installations",
5
5
  "type": "module",
6
6
  "bin": {
@@ -5,7 +5,7 @@ import { readFileSync, writeFileSync } from 'fs';
5
5
  import { join } from 'path';
6
6
  import { getInstallDir } from '../utils/config.js';
7
7
  import { detectPublicIPWithFeedback, buildURL, isValidIPv4 } from '../utils/network.js';
8
- import { configureNginx, requiresNginx } from '../utils/nginx.js';
8
+ import { configureNginx, requiresNginx, generateCloudflareCert } from '../utils/nginx.js';
9
9
  import { pullImages, stopServices, startServices, waitForServiceHealthy } from '../utils/docker.js';
10
10
  import { obtainSSLCertificate, updateNginxForSSL, setupAutoRenewal, extractDomain } from '../utils/ssl.js';
11
11
 
@@ -753,11 +753,22 @@ export async function setDomain(options) {
753
753
  console.log(chalk.gray('\nšŸ”§ Setting up reverse proxy...\n'));
754
754
 
755
755
  try {
756
+ // Check if Cloudflare SSL mode is enabled
757
+ const cloudflareSsl = options.cloudflareSsl || false;
758
+
759
+ // Generate self-signed certificate for Cloudflare if needed
760
+ if (cloudflareSsl) {
761
+ console.log(chalk.gray('Generating self-signed certificate for Cloudflare Full mode...'));
762
+ await generateCloudflareCert();
763
+ console.log(chalk.green('āœ“ Self-signed certificate ready'));
764
+ }
765
+
756
766
  const nginxConfig = {
757
767
  frontendDomain: frontendUrl,
758
768
  apiDomain: apiUrl,
759
769
  frontendPort: 8080,
760
- apiPort: 3001
770
+ apiPort: 3001,
771
+ cloudflareSsl
761
772
  };
762
773
 
763
774
  if (hasGateApp && gateAppUrl) {
@@ -62,7 +62,8 @@ export async function installNginx(spinner) {
62
62
  * @param {number} [config.posAppPort] - POS app Docker port (default: 8084)
63
63
  * @param {number} [config.clientAppPort] - Client app Docker port (default: 9005)
64
64
  * @param {number} [config.backendClientPort] - Backend client API Docker port (default: 4001)
65
- * @param {boolean} config.ssl - Enable SSL configuration (default: false)
65
+ * @param {boolean} config.ssl - Enable SSL configuration with Let's Encrypt (default: false)
66
+ * @param {boolean} config.cloudflareSsl - Enable Cloudflare SSL mode with self-signed certs (default: false)
66
67
  * @returns {string} NGINX configuration content
67
68
  */
68
69
  export function generateNginxConfig(config) {
@@ -83,7 +84,8 @@ export function generateNginxConfig(config) {
83
84
  posAppPort = 8084,
84
85
  clientAppPort = 9005,
85
86
  backendClientPort = 4001,
86
- ssl = false
87
+ ssl = false,
88
+ cloudflareSsl = false
87
89
  } = config;
88
90
 
89
91
  // Extract domain without protocol
@@ -96,6 +98,29 @@ export function generateNginxConfig(config) {
96
98
  const clientAppHost = clientAppDomain ? clientAppDomain.replace(/^https?:\/\//, '').replace(/:\d+$/, '') : null;
97
99
  const backendClientHost = backendClientDomain ? backendClientDomain.replace(/^https?:\/\//, '').replace(/:\d+$/, '') : null;
98
100
 
101
+ // Cloudflare SSL mode - uses self-signed certs for Cloudflare "Full" mode
102
+ if (cloudflareSsl) {
103
+ return generateCloudflareNginxConfig({
104
+ frontendHost,
105
+ apiHost,
106
+ gateAppHost,
107
+ guardianAppHost,
108
+ facialAppHost,
109
+ posAppHost,
110
+ clientAppHost,
111
+ backendClientHost,
112
+ frontendPort,
113
+ apiPort,
114
+ gateAppPort,
115
+ guardianAppPort,
116
+ facialWebPort,
117
+ posAppPort,
118
+ clientAppPort,
119
+ backendClientPort
120
+ });
121
+ }
122
+
123
+ // Let's Encrypt SSL mode
99
124
  if (ssl) {
100
125
  return generateSslNginxConfig({
101
126
  frontendHost,
@@ -371,6 +396,373 @@ server {
371
396
  ` : ''}`;
372
397
  }
373
398
 
399
+ /**
400
+ * Generate NGINX configuration for Cloudflare SSL (Full mode)
401
+ * Uses self-signed certificates at /etc/nginx/ssl/cloudflare.crt and .key
402
+ * Cloudflare terminates SSL and re-encrypts to origin with these certs
403
+ * @param {Object} config - Configuration object
404
+ * @returns {string} NGINX configuration with Cloudflare SSL
405
+ */
406
+ function generateCloudflareNginxConfig(config) {
407
+ const {
408
+ frontendHost,
409
+ apiHost,
410
+ gateAppHost,
411
+ guardianAppHost,
412
+ facialAppHost,
413
+ posAppHost,
414
+ clientAppHost,
415
+ backendClientHost,
416
+ frontendPort,
417
+ apiPort,
418
+ gateAppPort = 8081,
419
+ guardianAppPort = 8082,
420
+ facialWebPort = 8083,
421
+ posAppPort = 8084,
422
+ clientAppPort = 9005,
423
+ backendClientPort = 4001
424
+ } = config;
425
+
426
+ // SSL certificate paths for Cloudflare self-signed certs
427
+ const sslCert = '/etc/nginx/ssl/cloudflare.crt';
428
+ const sslKey = '/etc/nginx/ssl/cloudflare.key';
429
+
430
+ return `# ANTE Frontend Configuration (Cloudflare SSL)
431
+ server {
432
+ listen 80;
433
+ listen 443 ssl;
434
+ listen [::]:80;
435
+ listen [::]:443 ssl;
436
+ server_name ${frontendHost};
437
+
438
+ # SSL Certificate (self-signed for Cloudflare Full mode)
439
+ ssl_certificate ${sslCert};
440
+ ssl_certificate_key ${sslKey};
441
+
442
+ # Increase buffer sizes for large headers
443
+ client_header_buffer_size 16k;
444
+ large_client_header_buffers 4 16k;
445
+
446
+ # Increase body size for file uploads
447
+ client_max_body_size 100M;
448
+
449
+ location / {
450
+ proxy_pass http://localhost:${frontendPort};
451
+ proxy_http_version 1.1;
452
+ proxy_set_header Upgrade $http_upgrade;
453
+ proxy_set_header Connection 'upgrade';
454
+ proxy_set_header Host $host;
455
+ proxy_set_header X-Real-IP $remote_addr;
456
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
457
+ proxy_set_header X-Forwarded-Proto $scheme;
458
+ proxy_cache_bypass $http_upgrade;
459
+
460
+ # Timeout settings
461
+ proxy_connect_timeout 60s;
462
+ proxy_send_timeout 60s;
463
+ proxy_read_timeout 60s;
464
+ }
465
+ }
466
+
467
+ # ANTE API Configuration (Cloudflare SSL)
468
+ server {
469
+ listen 80;
470
+ listen 443 ssl;
471
+ listen [::]:80;
472
+ listen [::]:443 ssl;
473
+ server_name ${apiHost};
474
+
475
+ # SSL Certificate (self-signed for Cloudflare Full mode)
476
+ ssl_certificate ${sslCert};
477
+ ssl_certificate_key ${sslKey};
478
+
479
+ # Increase buffer sizes for large headers
480
+ client_header_buffer_size 16k;
481
+ large_client_header_buffers 4 16k;
482
+
483
+ # Increase body size for file uploads
484
+ client_max_body_size 100M;
485
+
486
+ location / {
487
+ proxy_pass http://localhost:${apiPort};
488
+ proxy_http_version 1.1;
489
+ proxy_set_header Upgrade $http_upgrade;
490
+ proxy_set_header Connection 'upgrade';
491
+ proxy_set_header Host $host;
492
+ proxy_set_header X-Real-IP $remote_addr;
493
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
494
+ proxy_set_header X-Forwarded-Proto $scheme;
495
+ proxy_cache_bypass $http_upgrade;
496
+
497
+ # Timeout settings
498
+ proxy_connect_timeout 60s;
499
+ proxy_send_timeout 60s;
500
+ proxy_read_timeout 60s;
501
+
502
+ # WebSocket support
503
+ proxy_set_header X-Forwarded-Host $host;
504
+ proxy_set_header X-Forwarded-Server $host;
505
+ }
506
+ }
507
+ ${gateAppHost ? `
508
+ # ANTE Gate App Configuration (Cloudflare SSL)
509
+ server {
510
+ listen 80;
511
+ listen 443 ssl;
512
+ listen [::]:80;
513
+ listen [::]:443 ssl;
514
+ server_name ${gateAppHost};
515
+
516
+ # SSL Certificate (self-signed for Cloudflare Full mode)
517
+ ssl_certificate ${sslCert};
518
+ ssl_certificate_key ${sslKey};
519
+
520
+ # Increase buffer sizes for large headers
521
+ client_header_buffer_size 16k;
522
+ large_client_header_buffers 4 16k;
523
+
524
+ # Increase body size for file uploads
525
+ client_max_body_size 100M;
526
+
527
+ location / {
528
+ proxy_pass http://localhost:${gateAppPort};
529
+ proxy_http_version 1.1;
530
+ proxy_set_header Upgrade $http_upgrade;
531
+ proxy_set_header Connection 'upgrade';
532
+ proxy_set_header Host $host;
533
+ proxy_set_header X-Real-IP $remote_addr;
534
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
535
+ proxy_set_header X-Forwarded-Proto $scheme;
536
+ proxy_cache_bypass $http_upgrade;
537
+
538
+ # Timeout settings
539
+ proxy_connect_timeout 60s;
540
+ proxy_send_timeout 60s;
541
+ proxy_read_timeout 60s;
542
+ }
543
+ }
544
+ ` : ''}${guardianAppHost ? `
545
+ # ANTE Guardian App Configuration (Cloudflare SSL)
546
+ server {
547
+ listen 80;
548
+ listen 443 ssl;
549
+ listen [::]:80;
550
+ listen [::]:443 ssl;
551
+ server_name ${guardianAppHost};
552
+
553
+ # SSL Certificate (self-signed for Cloudflare Full mode)
554
+ ssl_certificate ${sslCert};
555
+ ssl_certificate_key ${sslKey};
556
+
557
+ # Increase buffer sizes for large headers
558
+ client_header_buffer_size 16k;
559
+ large_client_header_buffers 4 16k;
560
+
561
+ # Increase body size for file uploads
562
+ client_max_body_size 100M;
563
+
564
+ location / {
565
+ proxy_pass http://localhost:${guardianAppPort};
566
+ proxy_http_version 1.1;
567
+ proxy_set_header Upgrade $http_upgrade;
568
+ proxy_set_header Connection 'upgrade';
569
+ proxy_set_header Host $host;
570
+ proxy_set_header X-Real-IP $remote_addr;
571
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
572
+ proxy_set_header X-Forwarded-Proto $scheme;
573
+ proxy_cache_bypass $http_upgrade;
574
+
575
+ # Timeout settings
576
+ proxy_connect_timeout 60s;
577
+ proxy_send_timeout 60s;
578
+ proxy_read_timeout 60s;
579
+ }
580
+ }
581
+ ` : ''}${facialAppHost ? `
582
+ # ANTE Facial Web App Configuration (Cloudflare SSL)
583
+ server {
584
+ listen 80;
585
+ listen 443 ssl;
586
+ listen [::]:80;
587
+ listen [::]:443 ssl;
588
+ server_name ${facialAppHost};
589
+
590
+ # SSL Certificate (self-signed for Cloudflare Full mode)
591
+ ssl_certificate ${sslCert};
592
+ ssl_certificate_key ${sslKey};
593
+
594
+ # Increase buffer sizes for large headers
595
+ client_header_buffer_size 16k;
596
+ large_client_header_buffers 4 16k;
597
+
598
+ # Increase body size for image uploads
599
+ client_max_body_size 50M;
600
+
601
+ location / {
602
+ proxy_pass http://localhost:${facialWebPort};
603
+ proxy_http_version 1.1;
604
+ proxy_set_header Upgrade $http_upgrade;
605
+ proxy_set_header Connection 'upgrade';
606
+ proxy_set_header Host $host;
607
+ proxy_set_header X-Real-IP $remote_addr;
608
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
609
+ proxy_set_header X-Forwarded-Proto $scheme;
610
+ proxy_cache_bypass $http_upgrade;
611
+
612
+ # Timeout settings
613
+ proxy_connect_timeout 60s;
614
+ proxy_send_timeout 60s;
615
+ proxy_read_timeout 60s;
616
+ }
617
+ }
618
+ ` : ''}${posAppHost ? `
619
+ # ANTE POS App Configuration (Cloudflare SSL)
620
+ server {
621
+ listen 80;
622
+ listen 443 ssl;
623
+ listen [::]:80;
624
+ listen [::]:443 ssl;
625
+ server_name ${posAppHost};
626
+
627
+ # SSL Certificate (self-signed for Cloudflare Full mode)
628
+ ssl_certificate ${sslCert};
629
+ ssl_certificate_key ${sslKey};
630
+
631
+ # Increase buffer sizes for large headers
632
+ client_header_buffer_size 16k;
633
+ large_client_header_buffers 4 16k;
634
+
635
+ # Increase body size for file uploads
636
+ client_max_body_size 100M;
637
+
638
+ location / {
639
+ proxy_pass http://localhost:${posAppPort};
640
+ proxy_http_version 1.1;
641
+ proxy_set_header Upgrade $http_upgrade;
642
+ proxy_set_header Connection 'upgrade';
643
+ proxy_set_header Host $host;
644
+ proxy_set_header X-Real-IP $remote_addr;
645
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
646
+ proxy_set_header X-Forwarded-Proto $scheme;
647
+ proxy_cache_bypass $http_upgrade;
648
+
649
+ # Timeout settings
650
+ proxy_connect_timeout 60s;
651
+ proxy_send_timeout 60s;
652
+ proxy_read_timeout 60s;
653
+ }
654
+ }
655
+ ` : ''}${clientAppHost ? `
656
+ # ANTE Client App Configuration (Cloudflare SSL)
657
+ server {
658
+ listen 80;
659
+ listen 443 ssl;
660
+ listen [::]:80;
661
+ listen [::]:443 ssl;
662
+ server_name ${clientAppHost};
663
+
664
+ # SSL Certificate (self-signed for Cloudflare Full mode)
665
+ ssl_certificate ${sslCert};
666
+ ssl_certificate_key ${sslKey};
667
+
668
+ # Increase buffer sizes for large headers
669
+ client_header_buffer_size 16k;
670
+ large_client_header_buffers 4 16k;
671
+
672
+ # Increase body size for file uploads
673
+ client_max_body_size 100M;
674
+
675
+ location / {
676
+ proxy_pass http://localhost:${clientAppPort};
677
+ proxy_http_version 1.1;
678
+ proxy_set_header Upgrade $http_upgrade;
679
+ proxy_set_header Connection 'upgrade';
680
+ proxy_set_header Host $host;
681
+ proxy_set_header X-Real-IP $remote_addr;
682
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
683
+ proxy_set_header X-Forwarded-Proto $scheme;
684
+ proxy_cache_bypass $http_upgrade;
685
+
686
+ # Timeout settings
687
+ proxy_connect_timeout 60s;
688
+ proxy_send_timeout 60s;
689
+ proxy_read_timeout 60s;
690
+ }
691
+ }
692
+ ` : ''}${backendClientHost ? `
693
+ # ANTE Backend Client API Configuration (Cloudflare SSL)
694
+ server {
695
+ listen 80;
696
+ listen 443 ssl;
697
+ listen [::]:80;
698
+ listen [::]:443 ssl;
699
+ server_name ${backendClientHost};
700
+
701
+ # SSL Certificate (self-signed for Cloudflare Full mode)
702
+ ssl_certificate ${sslCert};
703
+ ssl_certificate_key ${sslKey};
704
+
705
+ # Increase buffer sizes for large headers
706
+ client_header_buffer_size 16k;
707
+ large_client_header_buffers 4 16k;
708
+
709
+ # Increase body size for file uploads
710
+ client_max_body_size 100M;
711
+
712
+ location / {
713
+ proxy_pass http://localhost:${backendClientPort};
714
+ proxy_http_version 1.1;
715
+ proxy_set_header Upgrade $http_upgrade;
716
+ proxy_set_header Connection 'upgrade';
717
+ proxy_set_header Host $host;
718
+ proxy_set_header X-Real-IP $remote_addr;
719
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
720
+ proxy_set_header X-Forwarded-Proto $scheme;
721
+ proxy_cache_bypass $http_upgrade;
722
+
723
+ # Timeout settings
724
+ proxy_connect_timeout 60s;
725
+ proxy_send_timeout 60s;
726
+ proxy_read_timeout 60s;
727
+ }
728
+ }
729
+ ` : ''}`;
730
+ }
731
+
732
+ /**
733
+ * Generate self-signed SSL certificate for Cloudflare Full mode
734
+ * @returns {Promise<void>}
735
+ */
736
+ export async function generateCloudflareCert() {
737
+ const sslDir = '/etc/nginx/ssl';
738
+ const certPath = join(sslDir, 'cloudflare.crt');
739
+ const keyPath = join(sslDir, 'cloudflare.key');
740
+
741
+ // Check if certs already exist
742
+ if (existsSync(certPath) && existsSync(keyPath)) {
743
+ return; // Certs already exist
744
+ }
745
+
746
+ // Create SSL directory if it doesn't exist
747
+ if (!existsSync(sslDir)) {
748
+ mkdirSync(sslDir, { recursive: true });
749
+ }
750
+
751
+ // Generate self-signed certificate (valid for 10 years)
752
+ await execa('openssl', [
753
+ 'req', '-x509', '-nodes',
754
+ '-days', '3650',
755
+ '-newkey', 'rsa:2048',
756
+ '-keyout', keyPath,
757
+ '-out', certPath,
758
+ '-subj', '/CN=cloudflare-origin/O=ANTE/C=PH'
759
+ ], { stdio: 'pipe' });
760
+
761
+ // Set proper permissions
762
+ await execa('chmod', ['600', keyPath], { stdio: 'pipe' });
763
+ await execa('chmod', ['644', certPath], { stdio: 'pipe' });
764
+ }
765
+
374
766
  /**
375
767
  * Generate NGINX configuration with SSL support
376
768
  * @param {Object} config - Configuration object