@friggframework/core 2.0.0--canary.428.49aae81.0 → 2.0.0--canary.428.ade056e.0

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.
@@ -425,7 +425,9 @@ const detectVpcConfiguration = async () => {
425
425
  try {
426
426
  await Promise.race([
427
427
  dns.resolve4('www.google.com'),
428
- new Promise((_, reject) => setTimeout(() => reject(new Error('timeout')), 2000))
428
+ new Promise((_, reject) =>
429
+ setTimeout(() => reject(new Error('timeout')), 2000)
430
+ ),
429
431
  ]);
430
432
  results.canResolvePublicDns = true;
431
433
  } catch (e) {
@@ -436,10 +438,14 @@ const detectVpcConfiguration = async () => {
436
438
  try {
437
439
  const https = require('https');
438
440
  await new Promise((resolve, reject) => {
439
- const req = https.get('https://www.google.com', { timeout: 2000 }, (res) => {
440
- res.destroy();
441
- resolve(true);
442
- });
441
+ const req = https.get(
442
+ 'https://www.google.com',
443
+ { timeout: 2000 },
444
+ (res) => {
445
+ res.destroy();
446
+ resolve(true);
447
+ }
448
+ );
443
449
  req.on('error', reject);
444
450
  req.on('timeout', () => {
445
451
  req.destroy();
@@ -452,7 +458,7 @@ const detectVpcConfiguration = async () => {
452
458
  }
453
459
 
454
460
  // Test 3: Check for VPC endpoints by trying to resolve internal AWS endpoints
455
- const region = process.env.AWS_REGION || process.env.AWS_DEFAULT_REGION || 'eu-central-1';
461
+ const region = process.env.AWS_REGION; // Lambda always provides this
456
462
  const vpcEndpointDomains = [
457
463
  `com.amazonaws.${region}.kms`,
458
464
  `com.amazonaws.vpce.${region}`,
@@ -463,14 +469,17 @@ const detectVpcConfiguration = async () => {
463
469
  try {
464
470
  const addresses = await Promise.race([
465
471
  dns.resolve4(domain).catch(() => dns.resolve6(domain)),
466
- new Promise((_, reject) => setTimeout(() => reject(new Error('timeout')), 1000))
472
+ new Promise((_, reject) =>
473
+ setTimeout(() => reject(new Error('timeout')), 1000)
474
+ ),
467
475
  ]);
468
476
  if (addresses && addresses.length > 0) {
469
477
  // Check if it's a private IP (VPC endpoint indicator)
470
- const isPrivateIp = addresses.some(ip =>
471
- ip.startsWith('10.') ||
472
- ip.startsWith('172.') ||
473
- ip.startsWith('192.168.')
478
+ const isPrivateIp = addresses.some(
479
+ (ip) =>
480
+ ip.startsWith('10.') ||
481
+ ip.startsWith('172.') ||
482
+ ip.startsWith('192.168.')
474
483
  );
475
484
  if (isPrivateIp) {
476
485
  results.vpcEndpoints.push(domain);
@@ -481,9 +490,10 @@ const detectVpcConfiguration = async () => {
481
490
  }
482
491
  }
483
492
 
484
- results.isInVpc = !results.hasInternetAccess || results.vpcEndpoints.length > 0;
485
- results.canConnectToAws = results.hasInternetAccess || results.vpcEndpoints.length > 0;
486
-
493
+ results.isInVpc =
494
+ !results.hasInternetAccess || results.vpcEndpoints.length > 0;
495
+ results.canConnectToAws =
496
+ results.hasInternetAccess || results.vpcEndpoints.length > 0;
487
497
  } catch (error) {
488
498
  console.error('VPC detection error:', error.message);
489
499
  }
@@ -507,7 +517,6 @@ const checkKmsDecryptCapability = async () => {
507
517
  hasKmsKeyArn: !!KMS_KEY_ARN,
508
518
  kmsKeyArnPrefix: KMS_KEY_ARN?.substring(0, 30),
509
519
  awsRegion: process.env.AWS_REGION,
510
- awsDefaultRegion: process.env.AWS_DEFAULT_REGION,
511
520
  hasDiscoveryKey: !!process.env.AWS_DISCOVERY_KMS_KEY_ID,
512
521
  });
513
522
 
@@ -518,7 +527,7 @@ const checkKmsDecryptCapability = async () => {
518
527
  // Test DNS resolution for KMS endpoint
519
528
  try {
520
529
  const dns = require('dns').promises;
521
- const region = process.env.AWS_REGION || process.env.AWS_DEFAULT_REGION || 'eu-central-1';
530
+ const region = process.env.AWS_REGION; // Lambda always provides this
522
531
  const kmsEndpoint = `kms.${region}.amazonaws.com`;
523
532
  console.log('Testing DNS resolution for:', kmsEndpoint);
524
533
 
@@ -532,39 +541,43 @@ const checkKmsDecryptCapability = async () => {
532
541
  console.log('KMS endpoint resolved to:', addresses);
533
542
 
534
543
  // Check if resolved to private IP (VPC endpoint)
535
- const isVpcEndpoint = addresses.some(ip =>
536
- ip.startsWith('10.') ||
537
- ip.startsWith('172.') ||
538
- ip.startsWith('192.168.')
544
+ const isVpcEndpoint = addresses.some(
545
+ (ip) =>
546
+ ip.startsWith('10.') ||
547
+ ip.startsWith('172.') ||
548
+ ip.startsWith('192.168.')
539
549
  );
540
550
 
541
551
  if (isVpcEndpoint) {
542
- console.log('KMS VPC Endpoint detected - using private connectivity');
552
+ console.log(
553
+ 'KMS VPC Endpoint detected - using private connectivity'
554
+ );
543
555
  }
544
556
 
545
557
  // Test TCP connectivity to KMS (port 443)
546
558
  const net = require('net');
547
- const testConnection = () => new Promise((resolve) => {
548
- const socket = new net.Socket();
549
- const connectionTimeout = setTimeout(() => {
550
- socket.destroy();
551
- resolve({ connected: false, error: 'Connection timeout' });
552
- }, 3000);
553
-
554
- socket.on('connect', () => {
555
- clearTimeout(connectionTimeout);
556
- socket.destroy();
557
- resolve({ connected: true });
558
- });
559
+ const testConnection = () =>
560
+ new Promise((resolve) => {
561
+ const socket = new net.Socket();
562
+ const connectionTimeout = setTimeout(() => {
563
+ socket.destroy();
564
+ resolve({ connected: false, error: 'Connection timeout' });
565
+ }, 3000);
566
+
567
+ socket.on('connect', () => {
568
+ clearTimeout(connectionTimeout);
569
+ socket.destroy();
570
+ resolve({ connected: true });
571
+ });
559
572
 
560
- socket.on('error', (err) => {
561
- clearTimeout(connectionTimeout);
562
- resolve({ connected: false, error: err.message });
563
- });
573
+ socket.on('error', (err) => {
574
+ clearTimeout(connectionTimeout);
575
+ resolve({ connected: false, error: err.message });
576
+ });
564
577
 
565
- // Try connecting to first resolved address on HTTPS port
566
- socket.connect(443, addresses[0]);
567
- });
578
+ // Try connecting to first resolved address on HTTPS port
579
+ socket.connect(443, addresses[0]);
580
+ });
568
581
 
569
582
  const connResult = await testConnection();
570
583
  console.log('TCP connectivity test:', connResult);
@@ -591,36 +604,36 @@ const checkKmsDecryptCapability = async () => {
591
604
  }
592
605
 
593
606
  try {
594
- // Lazy load to avoid cost if unused in some environments
607
+ // Use AWS SDK v3 for consistency with the rest of the codebase
595
608
  // eslint-disable-next-line global-require
596
- const AWS = require('aws-sdk');
609
+ const {
610
+ KMSClient,
611
+ GenerateDataKeyCommand,
612
+ DecryptCommand,
613
+ } = require('@aws-sdk/client-kms');
597
614
 
598
- // Ensure AWS SDK has proper configuration
599
- const region = process.env.AWS_REGION || process.env.AWS_DEFAULT_REGION;
600
- if (!region) {
601
- return {
602
- status: 'unhealthy',
603
- error: 'AWS_REGION not configured',
604
- latencyMs: Date.now() - start,
605
- };
606
- }
615
+ // Lambda always provides AWS_REGION
616
+ const region = process.env.AWS_REGION;
607
617
 
608
- const kms = new AWS.KMS({
618
+ const kms = new KMSClient({
609
619
  region,
610
- httpOptions: {
611
- timeout: 25000, // 25 second timeout for slow VPC connections
612
- connectTimeout: 10000, // 10 second connection timeout
620
+ requestHandler: {
621
+ connectionTimeout: 10000, // 10 second connection timeout
622
+ requestTimeout: 25000, // 25 second timeout for slow VPC connections
613
623
  },
614
- maxRetries: 0, // No retries on health checks
624
+ maxAttempts: 1, // No retries on health checks
615
625
  });
616
626
 
617
627
  // Generate a data key (without plaintext logging) then immediately decrypt ciphertext to ensure decrypt perms.
618
- const dataKeyResp = await kms
619
- .generateDataKey({ KeyId: KMS_KEY_ARN, KeySpec: 'AES_256' })
620
- .promise();
621
- const decryptResp = await kms
622
- .decrypt({ CiphertextBlob: dataKeyResp.CiphertextBlob })
623
- .promise();
628
+ const dataKeyResp = await kms.send(
629
+ new GenerateDataKeyCommand({
630
+ KeyId: KMS_KEY_ARN,
631
+ KeySpec: 'AES_256',
632
+ })
633
+ );
634
+ const decryptResp = await kms.send(
635
+ new DecryptCommand({ CiphertextBlob: dataKeyResp.CiphertextBlob })
636
+ );
624
637
 
625
638
  const success = Boolean(
626
639
  dataKeyResp.CiphertextBlob && decryptResp.Plaintext
@@ -674,8 +687,11 @@ router.get('/health/detailed', async (_req, res) => {
674
687
  response.checks.network = await Promise.race([
675
688
  detectVpcConfiguration(),
676
689
  new Promise((_, reject) =>
677
- setTimeout(() => reject(new Error('Network diagnostics timeout')), 5000)
678
- )
690
+ setTimeout(
691
+ () => reject(new Error('Network diagnostics timeout')),
692
+ 5000
693
+ )
694
+ ),
679
695
  ]);
680
696
  response.checks.network.latencyMs = Date.now() - networkStart;
681
697
  console.log('Network diagnostics completed:', response.checks.network);
@@ -693,10 +709,16 @@ router.get('/health/detailed', async (_req, res) => {
693
709
  // Wrap the entire KMS check in a timeout (allow up to 25 seconds for slow VPC)
694
710
  const kmsCheckPromise = checkKmsDecryptCapability();
695
711
  const kmsTimeoutPromise = new Promise((_, reject) =>
696
- setTimeout(() => reject(new Error('KMS check timeout after 25 seconds')), 25000)
712
+ setTimeout(
713
+ () => reject(new Error('KMS check timeout after 25 seconds')),
714
+ 25000
715
+ )
697
716
  );
698
717
 
699
- response.checks.kms = await Promise.race([kmsCheckPromise, kmsTimeoutPromise]);
718
+ response.checks.kms = await Promise.race([
719
+ kmsCheckPromise,
720
+ kmsTimeoutPromise,
721
+ ]);
700
722
  if (response.checks.kms.status === 'unhealthy') {
701
723
  response.status = 'unhealthy';
702
724
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@friggframework/core",
3
3
  "prettier": "@friggframework/prettier-config",
4
- "version": "2.0.0--canary.428.49aae81.0",
4
+ "version": "2.0.0--canary.428.ade056e.0",
5
5
  "dependencies": {
6
6
  "@hapi/boom": "^10.0.1",
7
7
  "aws-sdk": "^2.1200.0",
@@ -22,9 +22,9 @@
22
22
  "uuid": "^9.0.1"
23
23
  },
24
24
  "devDependencies": {
25
- "@friggframework/eslint-config": "2.0.0--canary.428.49aae81.0",
26
- "@friggframework/prettier-config": "2.0.0--canary.428.49aae81.0",
27
- "@friggframework/test": "2.0.0--canary.428.49aae81.0",
25
+ "@friggframework/eslint-config": "2.0.0--canary.428.ade056e.0",
26
+ "@friggframework/prettier-config": "2.0.0--canary.428.ade056e.0",
27
+ "@friggframework/test": "2.0.0--canary.428.ade056e.0",
28
28
  "@types/lodash": "4.17.15",
29
29
  "@typescript-eslint/eslint-plugin": "^8.0.0",
30
30
  "chai": "^4.3.6",
@@ -56,5 +56,5 @@
56
56
  "publishConfig": {
57
57
  "access": "public"
58
58
  },
59
- "gitHead": "49aae81fe3bcaa900ee17e46e8d34413a830832b"
59
+ "gitHead": "ade056ef7772afeb2d7eae1b90e698feae9cb4c9"
60
60
  }