@friggframework/core 2.0.0--canary.427.bd07d1c.0 → 2.0.0--canary.427.972de91.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.
- package/handlers/routers/health.js +91 -44
- package/package.json +5 -5
|
@@ -346,7 +346,10 @@ const checkKMSAccess = async () => {
|
|
|
346
346
|
|
|
347
347
|
try {
|
|
348
348
|
// eslint-disable-next-line no-console
|
|
349
|
-
console.log(
|
|
349
|
+
console.log(
|
|
350
|
+
'Testing KMS key access with key:',
|
|
351
|
+
KMS_KEY_ARN.substring(0, 50) + '...'
|
|
352
|
+
);
|
|
350
353
|
|
|
351
354
|
const AWS = require('aws-sdk');
|
|
352
355
|
const kms = new AWS.KMS();
|
|
@@ -375,7 +378,10 @@ const checkKMSAccess = async () => {
|
|
|
375
378
|
});
|
|
376
379
|
} catch (describeError) {
|
|
377
380
|
// eslint-disable-next-line no-console
|
|
378
|
-
console.error(
|
|
381
|
+
console.error(
|
|
382
|
+
'KMS master key does not exist or is not accessible:',
|
|
383
|
+
describeError.message
|
|
384
|
+
);
|
|
379
385
|
|
|
380
386
|
if (describeError.code === 'NotFoundException') {
|
|
381
387
|
return {
|
|
@@ -403,7 +409,9 @@ const checkKMSAccess = async () => {
|
|
|
403
409
|
// Only 'Enabled' state allows cryptographic operations
|
|
404
410
|
if (keyMetadata.KeyState !== 'Enabled') {
|
|
405
411
|
// eslint-disable-next-line no-console
|
|
406
|
-
console.error(
|
|
412
|
+
console.error(
|
|
413
|
+
`KMS master key exists but is in state: ${keyMetadata.KeyState}`
|
|
414
|
+
);
|
|
407
415
|
|
|
408
416
|
let testResult = '';
|
|
409
417
|
switch (keyMetadata.KeyState) {
|
|
@@ -417,7 +425,8 @@ const checkKMSAccess = async () => {
|
|
|
417
425
|
testResult = 'KMS master key is pending import';
|
|
418
426
|
break;
|
|
419
427
|
case 'Unavailable':
|
|
420
|
-
testResult =
|
|
428
|
+
testResult =
|
|
429
|
+
'KMS master key is unavailable (custom key store disconnected)';
|
|
421
430
|
break;
|
|
422
431
|
case 'Creating':
|
|
423
432
|
testResult = 'KMS master key is still being created';
|
|
@@ -444,10 +453,12 @@ const checkKMSAccess = async () => {
|
|
|
444
453
|
console.log('Attempting to generate data key...');
|
|
445
454
|
const startTime = Date.now();
|
|
446
455
|
const result = await withTimeout(
|
|
447
|
-
kms
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
456
|
+
kms
|
|
457
|
+
.generateDataKey({
|
|
458
|
+
KeyId: KMS_KEY_ARN,
|
|
459
|
+
KeySpec: 'AES_256',
|
|
460
|
+
})
|
|
461
|
+
.promise(),
|
|
451
462
|
10000,
|
|
452
463
|
'KMS generateDataKey operation timed out after 10 seconds'
|
|
453
464
|
);
|
|
@@ -457,10 +468,13 @@ const checkKMSAccess = async () => {
|
|
|
457
468
|
// If we got a result with plaintext key, KMS access works
|
|
458
469
|
if (result && result.Plaintext) {
|
|
459
470
|
// eslint-disable-next-line no-console
|
|
460
|
-
console.log(
|
|
471
|
+
console.log(
|
|
472
|
+
`KMS key access successful, response time: ${responseTime}ms`
|
|
473
|
+
);
|
|
461
474
|
return {
|
|
462
475
|
status: 'healthy',
|
|
463
|
-
testResult:
|
|
476
|
+
testResult:
|
|
477
|
+
'Successfully requested and received decrypt key from KMS',
|
|
464
478
|
canAccessKey: true,
|
|
465
479
|
responseTime,
|
|
466
480
|
keyExists: true,
|
|
@@ -486,7 +500,8 @@ const checkKMSAccess = async () => {
|
|
|
486
500
|
// eslint-disable-next-line no-console
|
|
487
501
|
console.error('Master key does not exist in KMS');
|
|
488
502
|
} else if (error.code === 'AccessDeniedException') {
|
|
489
|
-
testResult =
|
|
503
|
+
testResult =
|
|
504
|
+
'Access denied - check IAM permissions for kms:GenerateDataKey';
|
|
490
505
|
// eslint-disable-next-line no-console
|
|
491
506
|
console.error('IAM permissions insufficient for KMS operations');
|
|
492
507
|
} else if (error.code === 'InvalidKeyId.NotFound') {
|
|
@@ -638,81 +653,113 @@ router.get('/health/detailed', async (_req, res) => {
|
|
|
638
653
|
const startTime = Date.now();
|
|
639
654
|
const response = buildHealthCheckResponse(startTime);
|
|
640
655
|
|
|
641
|
-
|
|
642
|
-
|
|
656
|
+
// Run all health checks in parallel for faster response
|
|
657
|
+
// eslint-disable-next-line no-console
|
|
658
|
+
console.log('Running all health checks in parallel...');
|
|
659
|
+
|
|
660
|
+
const [
|
|
661
|
+
kmsResult,
|
|
662
|
+
databaseResult,
|
|
663
|
+
encryptionResult,
|
|
664
|
+
externalApisResult,
|
|
665
|
+
integrationsResult,
|
|
666
|
+
] = await Promise.allSettled([
|
|
667
|
+
checkKMSAccess(),
|
|
668
|
+
checkDatabaseHealth(),
|
|
669
|
+
checkEncryptionHealth(),
|
|
670
|
+
checkExternalAPIs(),
|
|
671
|
+
Promise.resolve(checkIntegrations()), // Wrap sync function in Promise
|
|
672
|
+
]);
|
|
673
|
+
|
|
674
|
+
// Process KMS check result
|
|
675
|
+
if (kmsResult.status === 'fulfilled') {
|
|
676
|
+
response.checks.kmsAccess = kmsResult.value;
|
|
677
|
+
if (kmsResult.value.status === 'unhealthy') {
|
|
678
|
+
response.status = 'unhealthy';
|
|
679
|
+
}
|
|
680
|
+
// eslint-disable-next-line no-console
|
|
681
|
+
console.log('KMS access check completed:', response.checks.kmsAccess);
|
|
682
|
+
} else {
|
|
683
|
+
response.checks.kmsAccess = {
|
|
684
|
+
status: 'unhealthy',
|
|
685
|
+
error: kmsResult.reason?.message || 'KMS check failed',
|
|
686
|
+
};
|
|
687
|
+
response.status = 'unhealthy';
|
|
688
|
+
// eslint-disable-next-line no-console
|
|
689
|
+
console.log('KMS access check error:', kmsResult.reason?.message);
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
// Process database check result
|
|
693
|
+
if (databaseResult.status === 'fulfilled') {
|
|
694
|
+
response.checks.database = databaseResult.value;
|
|
643
695
|
const dbState = getDatabaseState();
|
|
644
696
|
if (!dbState.isConnected) {
|
|
645
697
|
response.status = 'unhealthy';
|
|
646
698
|
}
|
|
647
699
|
// eslint-disable-next-line no-console
|
|
648
700
|
console.log('Database check completed:', response.checks.database);
|
|
649
|
-
}
|
|
701
|
+
} else {
|
|
650
702
|
response.checks.database = {
|
|
651
703
|
status: 'unhealthy',
|
|
652
|
-
error:
|
|
704
|
+
error: databaseResult.reason?.message || 'Database check failed',
|
|
653
705
|
};
|
|
654
706
|
response.status = 'unhealthy';
|
|
655
707
|
// eslint-disable-next-line no-console
|
|
656
|
-
console.log('Database check error:',
|
|
708
|
+
console.log('Database check error:', databaseResult.reason?.message);
|
|
657
709
|
}
|
|
658
710
|
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
711
|
+
// Process encryption check result
|
|
712
|
+
if (encryptionResult.status === 'fulfilled') {
|
|
713
|
+
response.checks.encryption = encryptionResult.value;
|
|
714
|
+
if (encryptionResult.value.status === 'unhealthy') {
|
|
662
715
|
response.status = 'unhealthy';
|
|
663
716
|
}
|
|
664
717
|
// eslint-disable-next-line no-console
|
|
665
718
|
console.log('Encryption check completed:', response.checks.encryption);
|
|
666
|
-
}
|
|
719
|
+
} else {
|
|
667
720
|
response.checks.encryption = {
|
|
668
721
|
status: 'unhealthy',
|
|
669
|
-
error:
|
|
722
|
+
error: encryptionResult.reason?.message || 'Encryption check failed',
|
|
670
723
|
};
|
|
671
724
|
response.status = 'unhealthy';
|
|
672
725
|
// eslint-disable-next-line no-console
|
|
673
|
-
console.log('Encryption check error:',
|
|
726
|
+
console.log('Encryption check error:', encryptionResult.reason?.message);
|
|
674
727
|
}
|
|
675
728
|
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
729
|
+
// Process external APIs check result
|
|
730
|
+
if (externalApisResult.status === 'fulfilled') {
|
|
731
|
+
const { apiStatuses, allReachable } = externalApisResult.value;
|
|
732
|
+
response.checks.externalApis = apiStatuses;
|
|
733
|
+
if (!allReachable) {
|
|
679
734
|
response.status = 'unhealthy';
|
|
680
735
|
}
|
|
681
736
|
// eslint-disable-next-line no-console
|
|
682
|
-
console.log('
|
|
683
|
-
}
|
|
684
|
-
response.checks.
|
|
685
|
-
|
|
686
|
-
error: error.message,
|
|
737
|
+
console.log('External APIs check completed:', response.checks.externalApis);
|
|
738
|
+
} else {
|
|
739
|
+
response.checks.externalApis = {
|
|
740
|
+
error: externalApisResult.reason?.message || 'External APIs check failed',
|
|
687
741
|
};
|
|
688
742
|
response.status = 'unhealthy';
|
|
689
743
|
// eslint-disable-next-line no-console
|
|
690
|
-
console.log('
|
|
744
|
+
console.log('External APIs check error:', externalApisResult.reason?.message);
|
|
691
745
|
}
|
|
692
746
|
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
response.status = 'unhealthy';
|
|
697
|
-
}
|
|
698
|
-
// eslint-disable-next-line no-console
|
|
699
|
-
console.log('External APIs check completed:', response.checks.externalApis);
|
|
700
|
-
|
|
701
|
-
try {
|
|
702
|
-
response.checks.integrations = checkIntegrations();
|
|
747
|
+
// Process integrations check result
|
|
748
|
+
if (integrationsResult.status === 'fulfilled') {
|
|
749
|
+
response.checks.integrations = integrationsResult.value;
|
|
703
750
|
// eslint-disable-next-line no-console
|
|
704
751
|
console.log(
|
|
705
752
|
'Integrations check completed:',
|
|
706
753
|
response.checks.integrations
|
|
707
754
|
);
|
|
708
|
-
}
|
|
755
|
+
} else {
|
|
709
756
|
response.checks.integrations = {
|
|
710
757
|
status: 'unhealthy',
|
|
711
|
-
error:
|
|
758
|
+
error: integrationsResult.reason?.message || 'Integrations check failed',
|
|
712
759
|
};
|
|
713
760
|
response.status = 'unhealthy';
|
|
714
761
|
// eslint-disable-next-line no-console
|
|
715
|
-
console.log('Integrations check error:',
|
|
762
|
+
console.log('Integrations check error:', integrationsResult.reason?.message);
|
|
716
763
|
}
|
|
717
764
|
|
|
718
765
|
response.responseTime = response.calculateResponseTime();
|
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.427.
|
|
4
|
+
"version": "2.0.0--canary.427.972de91.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.427.
|
|
26
|
-
"@friggframework/prettier-config": "2.0.0--canary.427.
|
|
27
|
-
"@friggframework/test": "2.0.0--canary.427.
|
|
25
|
+
"@friggframework/eslint-config": "2.0.0--canary.427.972de91.0",
|
|
26
|
+
"@friggframework/prettier-config": "2.0.0--canary.427.972de91.0",
|
|
27
|
+
"@friggframework/test": "2.0.0--canary.427.972de91.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": "
|
|
59
|
+
"gitHead": "972de918c8273da9f1ffb85e1eedfc088f880f54"
|
|
60
60
|
}
|