@factiii/stack 0.1.2 → 0.1.8

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.
Files changed (89) hide show
  1. package/bin/factiii +13 -0
  2. package/dist/cli/pr-check.d.ts +24 -0
  3. package/dist/cli/pr-check.d.ts.map +1 -0
  4. package/dist/cli/pr-check.js +153 -0
  5. package/dist/cli/pr-check.js.map +1 -0
  6. package/dist/plugins/addons/server-mode/index.d.ts.map +1 -1
  7. package/dist/plugins/addons/server-mode/index.js +3 -0
  8. package/dist/plugins/addons/server-mode/index.js.map +1 -1
  9. package/dist/plugins/addons/server-mode/scanfix/mac.d.ts +20 -3
  10. package/dist/plugins/addons/server-mode/scanfix/mac.d.ts.map +1 -1
  11. package/dist/plugins/addons/server-mode/scanfix/mac.js +304 -177
  12. package/dist/plugins/addons/server-mode/scanfix/mac.js.map +1 -1
  13. package/dist/plugins/addons/server-mode/scanfix/tart.d.ts +19 -0
  14. package/dist/plugins/addons/server-mode/scanfix/tart.d.ts.map +1 -0
  15. package/dist/plugins/addons/server-mode/scanfix/tart.js +350 -0
  16. package/dist/plugins/addons/server-mode/scanfix/tart.js.map +1 -0
  17. package/dist/plugins/pipelines/aws/configs/free-tier.d.ts.map +1 -1
  18. package/dist/plugins/pipelines/aws/configs/free-tier.js +3 -38
  19. package/dist/plugins/pipelines/aws/configs/free-tier.js.map +1 -1
  20. package/dist/plugins/pipelines/aws/index.d.ts +4 -1
  21. package/dist/plugins/pipelines/aws/index.d.ts.map +1 -1
  22. package/dist/plugins/pipelines/aws/index.js +101 -29
  23. package/dist/plugins/pipelines/aws/index.js.map +1 -1
  24. package/dist/plugins/pipelines/aws/scanfix/credentials.d.ts +9 -0
  25. package/dist/plugins/pipelines/aws/scanfix/credentials.d.ts.map +1 -0
  26. package/dist/plugins/pipelines/aws/scanfix/credentials.js +196 -0
  27. package/dist/plugins/pipelines/aws/scanfix/credentials.js.map +1 -0
  28. package/dist/plugins/pipelines/aws/scanfix/db-replication.d.ts +13 -0
  29. package/dist/plugins/pipelines/aws/scanfix/db-replication.d.ts.map +1 -0
  30. package/dist/plugins/pipelines/aws/scanfix/db-replication.js +136 -0
  31. package/dist/plugins/pipelines/aws/scanfix/db-replication.js.map +1 -0
  32. package/dist/plugins/pipelines/aws/scanfix/ec2.d.ts +10 -0
  33. package/dist/plugins/pipelines/aws/scanfix/ec2.d.ts.map +1 -0
  34. package/dist/plugins/pipelines/aws/scanfix/ec2.js +279 -0
  35. package/dist/plugins/pipelines/aws/scanfix/ec2.js.map +1 -0
  36. package/dist/plugins/pipelines/aws/scanfix/ecr.d.ts +9 -0
  37. package/dist/plugins/pipelines/aws/scanfix/ecr.d.ts.map +1 -0
  38. package/dist/plugins/pipelines/aws/scanfix/ecr.js +100 -0
  39. package/dist/plugins/pipelines/aws/scanfix/ecr.js.map +1 -0
  40. package/dist/plugins/pipelines/aws/scanfix/iam.d.ts +10 -0
  41. package/dist/plugins/pipelines/aws/scanfix/iam.d.ts.map +1 -0
  42. package/dist/plugins/pipelines/aws/scanfix/iam.js +255 -0
  43. package/dist/plugins/pipelines/aws/scanfix/iam.js.map +1 -0
  44. package/dist/plugins/pipelines/aws/scanfix/rds.d.ts +10 -0
  45. package/dist/plugins/pipelines/aws/scanfix/rds.d.ts.map +1 -0
  46. package/dist/plugins/pipelines/aws/scanfix/rds.js +261 -0
  47. package/dist/plugins/pipelines/aws/scanfix/rds.js.map +1 -0
  48. package/dist/plugins/pipelines/aws/scanfix/s3.d.ts +9 -0
  49. package/dist/plugins/pipelines/aws/scanfix/s3.d.ts.map +1 -0
  50. package/dist/plugins/pipelines/aws/scanfix/s3.js +134 -0
  51. package/dist/plugins/pipelines/aws/scanfix/s3.js.map +1 -0
  52. package/dist/plugins/pipelines/aws/scanfix/security-groups.d.ts +10 -0
  53. package/dist/plugins/pipelines/aws/scanfix/security-groups.d.ts.map +1 -0
  54. package/dist/plugins/pipelines/aws/scanfix/security-groups.js +225 -0
  55. package/dist/plugins/pipelines/aws/scanfix/security-groups.js.map +1 -0
  56. package/dist/plugins/pipelines/aws/scanfix/ses.d.ts +9 -0
  57. package/dist/plugins/pipelines/aws/scanfix/ses.d.ts.map +1 -0
  58. package/dist/plugins/pipelines/aws/scanfix/ses.js +174 -0
  59. package/dist/plugins/pipelines/aws/scanfix/ses.js.map +1 -0
  60. package/dist/plugins/pipelines/aws/scanfix/vpc.d.ts +9 -0
  61. package/dist/plugins/pipelines/aws/scanfix/vpc.d.ts.map +1 -0
  62. package/dist/plugins/pipelines/aws/scanfix/vpc.js +237 -0
  63. package/dist/plugins/pipelines/aws/scanfix/vpc.js.map +1 -0
  64. package/dist/plugins/pipelines/aws/utils/aws-helpers.d.ts +50 -0
  65. package/dist/plugins/pipelines/aws/utils/aws-helpers.d.ts.map +1 -0
  66. package/dist/plugins/pipelines/aws/utils/aws-helpers.js +137 -0
  67. package/dist/plugins/pipelines/aws/utils/aws-helpers.js.map +1 -0
  68. package/dist/plugins/pipelines/factiii/index.d.ts.map +1 -1
  69. package/dist/plugins/pipelines/factiii/index.js +11 -0
  70. package/dist/plugins/pipelines/factiii/index.js.map +1 -1
  71. package/dist/plugins/pipelines/factiii/pr-check.d.ts +35 -0
  72. package/dist/plugins/pipelines/factiii/pr-check.d.ts.map +1 -0
  73. package/dist/plugins/pipelines/factiii/pr-check.js +202 -0
  74. package/dist/plugins/pipelines/factiii/pr-check.js.map +1 -0
  75. package/dist/plugins/pipelines/factiii/utils/workflows.d.ts.map +1 -1
  76. package/dist/plugins/pipelines/factiii/utils/workflows.js +1 -0
  77. package/dist/plugins/pipelines/factiii/utils/workflows.js.map +1 -1
  78. package/dist/plugins/pipelines/factiii/workflows/factiii-cicd-staging.yml +8 -3
  79. package/dist/plugins/pipelines/factiii/workflows/factiii-pr-check.yml +103 -0
  80. package/dist/plugins/servers/mac/staging.d.ts.map +1 -1
  81. package/dist/plugins/servers/mac/staging.js +304 -52
  82. package/dist/plugins/servers/mac/staging.js.map +1 -1
  83. package/dist/types/config.d.ts +11 -0
  84. package/dist/types/config.d.ts.map +1 -1
  85. package/dist/utils/github-status.d.ts +39 -0
  86. package/dist/utils/github-status.d.ts.map +1 -0
  87. package/dist/utils/github-status.js +172 -0
  88. package/dist/utils/github-status.js.map +1 -0
  89. package/package.json +3 -3
@@ -0,0 +1,134 @@
1
+ "use strict";
2
+ /**
3
+ * AWS S3 Fixes
4
+ *
5
+ * Provisions S3 bucket with encryption and blocked public access.
6
+ * Configures CORS for the production domain.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.s3Fixes = void 0;
10
+ const aws_helpers_js_1 = require("../utils/aws-helpers.js");
11
+ /**
12
+ * Check if S3 bucket exists
13
+ */
14
+ function findBucket(bucketName, region) {
15
+ const result = (0, aws_helpers_js_1.awsExecSafe)('aws s3api head-bucket --bucket ' + bucketName, region);
16
+ // head-bucket returns empty on success, throws on failure
17
+ return result !== null;
18
+ }
19
+ /**
20
+ * Check if CORS is configured on bucket
21
+ */
22
+ function hasCors(bucketName, region) {
23
+ const result = (0, aws_helpers_js_1.awsExecSafe)('aws s3api get-bucket-cors --bucket ' + bucketName, region);
24
+ return !!result && result !== 'null';
25
+ }
26
+ /**
27
+ * Check if AWS is configured for this project
28
+ */
29
+ function isAwsConfigured(config) {
30
+ if (config.aws)
31
+ return true;
32
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
33
+ const { extractEnvironments } = require('../../../../utils/config-helpers.js');
34
+ const environments = extractEnvironments(config);
35
+ return Object.values(environments).some((e) => e.pipeline === 'aws');
36
+ }
37
+ exports.s3Fixes = [
38
+ {
39
+ id: 'aws-s3-bucket-missing',
40
+ stage: 'prod',
41
+ severity: 'warning',
42
+ description: 'S3 bucket not created for file storage',
43
+ scan: async (config) => {
44
+ if (!isAwsConfigured(config))
45
+ return false;
46
+ const { region } = (0, aws_helpers_js_1.getAwsConfig)(config);
47
+ const projectName = (0, aws_helpers_js_1.getProjectName)(config);
48
+ const bucketName = 'factiii-' + projectName;
49
+ return !findBucket(bucketName, region);
50
+ },
51
+ fix: async (config) => {
52
+ const { region } = (0, aws_helpers_js_1.getAwsConfig)(config);
53
+ const projectName = (0, aws_helpers_js_1.getProjectName)(config);
54
+ const bucketName = 'factiii-' + projectName;
55
+ try {
56
+ // Create bucket (us-east-1 doesn't need LocationConstraint)
57
+ if (region === 'us-east-1') {
58
+ (0, aws_helpers_js_1.awsExec)('aws s3api create-bucket --bucket ' + bucketName, region);
59
+ }
60
+ else {
61
+ (0, aws_helpers_js_1.awsExec)('aws s3api create-bucket --bucket ' + bucketName +
62
+ ' --create-bucket-configuration LocationConstraint=' + region, region);
63
+ }
64
+ console.log(' Created S3 bucket: ' + bucketName);
65
+ // Block all public access
66
+ (0, aws_helpers_js_1.awsExec)('aws s3api put-public-access-block --bucket ' + bucketName +
67
+ ' --public-access-block-configuration BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true', region);
68
+ console.log(' Blocked all public access');
69
+ // Enable server-side encryption (AES-256)
70
+ (0, aws_helpers_js_1.awsExec)('aws s3api put-bucket-encryption --bucket ' + bucketName +
71
+ ' --server-side-encryption-configuration ' +
72
+ '"{\\\"Rules\\\":[{\\\"ApplyServerSideEncryptionByDefault\\\":{\\\"SSEAlgorithm\\\":\\\"AES256\\\"}}]}"', region);
73
+ console.log(' Enabled AES-256 encryption');
74
+ return true;
75
+ }
76
+ catch (e) {
77
+ console.log(' Failed to create S3 bucket: ' + (e instanceof Error ? e.message : String(e)));
78
+ return false;
79
+ }
80
+ },
81
+ manualFix: 'Create S3 bucket with encryption and blocked public access',
82
+ },
83
+ {
84
+ id: 'aws-s3-cors-missing',
85
+ stage: 'prod',
86
+ severity: 'info',
87
+ description: 'S3 bucket CORS not configured for production domain',
88
+ scan: async (config) => {
89
+ if (!isAwsConfigured(config))
90
+ return false;
91
+ const { region } = (0, aws_helpers_js_1.getAwsConfig)(config);
92
+ const projectName = (0, aws_helpers_js_1.getProjectName)(config);
93
+ const bucketName = 'factiii-' + projectName;
94
+ if (!findBucket(bucketName, region))
95
+ return false;
96
+ return !hasCors(bucketName, region);
97
+ },
98
+ fix: async (config) => {
99
+ const { region } = (0, aws_helpers_js_1.getAwsConfig)(config);
100
+ const projectName = (0, aws_helpers_js_1.getProjectName)(config);
101
+ const bucketName = 'factiii-' + projectName;
102
+ // Get production domain for CORS
103
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
104
+ const { extractEnvironments } = require('../../../../utils/config-helpers.js');
105
+ const environments = extractEnvironments(config);
106
+ const prodEnv = environments.prod ?? environments.production;
107
+ const domain = prodEnv?.domain;
108
+ if (!domain || domain.startsWith('EXAMPLE-')) {
109
+ console.log(' Set production domain in factiii.yml first');
110
+ return false;
111
+ }
112
+ try {
113
+ const corsConfig = JSON.stringify({
114
+ CORSRules: [{
115
+ AllowedHeaders: ['*'],
116
+ AllowedMethods: ['GET', 'PUT', 'POST', 'DELETE'],
117
+ AllowedOrigins: ['https://' + domain],
118
+ MaxAgeSeconds: 3600,
119
+ }],
120
+ });
121
+ (0, aws_helpers_js_1.awsExec)('aws s3api put-bucket-cors --bucket ' + bucketName +
122
+ " --cors-configuration '" + corsConfig + "'", region);
123
+ console.log(' Configured CORS for https://' + domain);
124
+ return true;
125
+ }
126
+ catch (e) {
127
+ console.log(' Failed to configure CORS: ' + (e instanceof Error ? e.message : String(e)));
128
+ return false;
129
+ }
130
+ },
131
+ manualFix: 'Configure S3 CORS to allow requests from your production domain',
132
+ },
133
+ ];
134
+ //# sourceMappingURL=s3.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"s3.js","sourceRoot":"","sources":["../../../../../src/plugins/pipelines/aws/scanfix/s3.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * AWS Security Group Fixes
3
+ *
4
+ * Provisions security groups for EC2 and RDS.
5
+ * EC2 SG: SSH(22), HTTP(80), HTTPS(443)
6
+ * RDS SG: PostgreSQL(5432) from EC2 SG only
7
+ */
8
+ import type { Fix } from '../../../../types/index.js';
9
+ export declare const securityGroupFixes: Fix[];
10
+ //# sourceMappingURL=security-groups.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security-groups.d.ts","sourceRoot":"","sources":["../../../../../src/plugins/pipelines/aws/scanfix/security-groups.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAiB,GAAG,EAAE,MAAM,4BAA4B,CAAC;AAwCrE,eAAO,MAAM,kBAAkB,EAAE,GAAG,EAqNnC,CAAC"}
@@ -0,0 +1,225 @@
1
+ "use strict";
2
+ /**
3
+ * AWS Security Group Fixes
4
+ *
5
+ * Provisions security groups for EC2 and RDS.
6
+ * EC2 SG: SSH(22), HTTP(80), HTTPS(443)
7
+ * RDS SG: PostgreSQL(5432) from EC2 SG only
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.securityGroupFixes = void 0;
11
+ const aws_helpers_js_1 = require("../utils/aws-helpers.js");
12
+ /**
13
+ * Find security group by name and VPC
14
+ */
15
+ function findSecurityGroup(groupName, vpcId, region) {
16
+ const result = (0, aws_helpers_js_1.awsExecSafe)('aws ec2 describe-security-groups --filters "Name=group-name,Values=' + groupName + '" "Name=vpc-id,Values=' + vpcId + '" --query "SecurityGroups[0].GroupId" --output text', region);
17
+ if (!result || result === 'None' || result === 'null')
18
+ return null;
19
+ return result.replace(/"/g, '');
20
+ }
21
+ /**
22
+ * Find VPC by factiii:project tag (shared with vpc.ts)
23
+ */
24
+ function findVpc(projectName, region) {
25
+ const result = (0, aws_helpers_js_1.awsExecSafe)('aws ec2 describe-vpcs --filters "Name=tag:factiii:project,Values=' + projectName + '" --query "Vpcs[0].VpcId" --output text', region);
26
+ if (!result || result === 'None' || result === 'null')
27
+ return null;
28
+ return result.replace(/"/g, '');
29
+ }
30
+ /**
31
+ * Check if AWS is configured for this project
32
+ */
33
+ function isAwsConfigured(config) {
34
+ if (config.aws)
35
+ return true;
36
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
37
+ const { extractEnvironments } = require('../../../../utils/config-helpers.js');
38
+ const environments = extractEnvironments(config);
39
+ return Object.values(environments).some((e) => e.pipeline === 'aws');
40
+ }
41
+ exports.securityGroupFixes = [
42
+ {
43
+ id: 'aws-sg-ec2-missing',
44
+ stage: 'prod',
45
+ severity: 'critical',
46
+ description: 'EC2 security group not created (SSH, HTTP, HTTPS)',
47
+ scan: async (config) => {
48
+ if (!isAwsConfigured(config))
49
+ return false;
50
+ const { region } = (0, aws_helpers_js_1.getAwsConfig)(config);
51
+ const projectName = (0, aws_helpers_js_1.getProjectName)(config);
52
+ const vpcId = findVpc(projectName, region);
53
+ if (!vpcId)
54
+ return false; // VPC must exist first
55
+ return !findSecurityGroup('factiii-' + projectName + '-ec2', vpcId, region);
56
+ },
57
+ fix: async (config) => {
58
+ const { region } = (0, aws_helpers_js_1.getAwsConfig)(config);
59
+ const projectName = (0, aws_helpers_js_1.getProjectName)(config);
60
+ const vpcId = findVpc(projectName, region);
61
+ if (!vpcId) {
62
+ console.log(' VPC must be created first');
63
+ return false;
64
+ }
65
+ try {
66
+ const groupName = 'factiii-' + projectName + '-ec2';
67
+ // Create security group
68
+ const sgResult = (0, aws_helpers_js_1.awsExec)('aws ec2 create-security-group --group-name ' + groupName +
69
+ ' --description "EC2 security group for ' + projectName + '"' +
70
+ ' --vpc-id ' + vpcId +
71
+ ' ' + (0, aws_helpers_js_1.tagSpec)('security-group', projectName), region);
72
+ const sgId = JSON.parse(sgResult).GroupId;
73
+ console.log(' Created EC2 security group: ' + sgId);
74
+ // Allow SSH (port 22)
75
+ (0, aws_helpers_js_1.awsExec)('aws ec2 authorize-security-group-ingress --group-id ' + sgId +
76
+ ' --protocol tcp --port 22 --cidr 0.0.0.0/0', region);
77
+ // Allow HTTP (port 80)
78
+ (0, aws_helpers_js_1.awsExec)('aws ec2 authorize-security-group-ingress --group-id ' + sgId +
79
+ ' --protocol tcp --port 80 --cidr 0.0.0.0/0', region);
80
+ // Allow HTTPS (port 443)
81
+ (0, aws_helpers_js_1.awsExec)('aws ec2 authorize-security-group-ingress --group-id ' + sgId +
82
+ ' --protocol tcp --port 443 --cidr 0.0.0.0/0', region);
83
+ console.log(' Allowed inbound: SSH(22), HTTP(80), HTTPS(443)');
84
+ return true;
85
+ }
86
+ catch (e) {
87
+ console.log(' Failed to create EC2 security group: ' + (e instanceof Error ? e.message : String(e)));
88
+ return false;
89
+ }
90
+ },
91
+ manualFix: 'Create EC2 security group with inbound rules for SSH(22), HTTP(80), HTTPS(443)',
92
+ },
93
+ {
94
+ id: 'aws-sg-rds-missing',
95
+ stage: 'prod',
96
+ severity: 'critical',
97
+ description: 'RDS security group not created (PostgreSQL from EC2 only)',
98
+ scan: async (config) => {
99
+ if (!isAwsConfigured(config))
100
+ return false;
101
+ const { region } = (0, aws_helpers_js_1.getAwsConfig)(config);
102
+ const projectName = (0, aws_helpers_js_1.getProjectName)(config);
103
+ const vpcId = findVpc(projectName, region);
104
+ if (!vpcId)
105
+ return false;
106
+ return !findSecurityGroup('factiii-' + projectName + '-rds', vpcId, region);
107
+ },
108
+ fix: async (config) => {
109
+ const { region } = (0, aws_helpers_js_1.getAwsConfig)(config);
110
+ const projectName = (0, aws_helpers_js_1.getProjectName)(config);
111
+ const vpcId = findVpc(projectName, region);
112
+ if (!vpcId) {
113
+ console.log(' VPC must be created first');
114
+ return false;
115
+ }
116
+ // Need EC2 security group to reference
117
+ const ec2SgId = findSecurityGroup('factiii-' + projectName + '-ec2', vpcId, region);
118
+ if (!ec2SgId) {
119
+ console.log(' EC2 security group must be created first');
120
+ return false;
121
+ }
122
+ try {
123
+ const groupName = 'factiii-' + projectName + '-rds';
124
+ // Create RDS security group
125
+ const sgResult = (0, aws_helpers_js_1.awsExec)('aws ec2 create-security-group --group-name ' + groupName +
126
+ ' --description "RDS security group for ' + projectName + '"' +
127
+ ' --vpc-id ' + vpcId +
128
+ ' ' + (0, aws_helpers_js_1.tagSpec)('security-group', projectName), region);
129
+ const sgId = JSON.parse(sgResult).GroupId;
130
+ console.log(' Created RDS security group: ' + sgId);
131
+ // Allow PostgreSQL (port 5432) from EC2 security group ONLY
132
+ (0, aws_helpers_js_1.awsExec)('aws ec2 authorize-security-group-ingress --group-id ' + sgId +
133
+ ' --protocol tcp --port 5432 --source-group ' + ec2SgId, region);
134
+ console.log(' Allowed inbound: PostgreSQL(5432) from EC2 SG only');
135
+ return true;
136
+ }
137
+ catch (e) {
138
+ console.log(' Failed to create RDS security group: ' + (e instanceof Error ? e.message : String(e)));
139
+ return false;
140
+ }
141
+ },
142
+ manualFix: 'Create RDS security group allowing PostgreSQL(5432) from EC2 security group only',
143
+ },
144
+ {
145
+ id: 'aws-sg-rds-mac-access',
146
+ stage: 'prod',
147
+ severity: 'info',
148
+ description: 'RDS security group does not allow Mac Mini staging access',
149
+ scan: async (config) => {
150
+ if (!isAwsConfigured(config))
151
+ return false;
152
+ const { region } = (0, aws_helpers_js_1.getAwsConfig)(config);
153
+ const projectName = (0, aws_helpers_js_1.getProjectName)(config);
154
+ const vpcId = findVpc(projectName, region);
155
+ if (!vpcId)
156
+ return false;
157
+ const rdsSgId = findSecurityGroup('factiii-' + projectName + '-rds', vpcId, region);
158
+ if (!rdsSgId)
159
+ return false; // RDS SG must exist first
160
+ // Check if staging domain is configured
161
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
162
+ const { extractEnvironments } = require('../../../../utils/config-helpers.js');
163
+ const environments = extractEnvironments(config);
164
+ const stagingEnv = environments.staging;
165
+ if (!stagingEnv?.domain)
166
+ return false; // No staging configured
167
+ // Check if RDS SG has an inbound rule for the staging IP
168
+ const rulesResult = (0, aws_helpers_js_1.awsExecSafe)('aws ec2 describe-security-groups --group-ids ' + rdsSgId + ' --query "SecurityGroups[0].IpPermissions" --output json', region);
169
+ if (!rulesResult)
170
+ return false;
171
+ try {
172
+ const rules = JSON.parse(rulesResult);
173
+ const stagingIp = stagingEnv.domain;
174
+ // Check if any rule allows the staging IP on port 5432
175
+ for (const rule of rules) {
176
+ if (rule.FromPort === 5432 && rule.ToPort === 5432) {
177
+ for (const ipRange of (rule.IpRanges || [])) {
178
+ if (ipRange.CidrIp === stagingIp + '/32') {
179
+ return false; // Already has access
180
+ }
181
+ }
182
+ }
183
+ }
184
+ return true; // No rule found for staging IP
185
+ }
186
+ catch {
187
+ return false;
188
+ }
189
+ },
190
+ fix: async (config) => {
191
+ const { region } = (0, aws_helpers_js_1.getAwsConfig)(config);
192
+ const projectName = (0, aws_helpers_js_1.getProjectName)(config);
193
+ const vpcId = findVpc(projectName, region);
194
+ if (!vpcId)
195
+ return false;
196
+ const rdsSgId = findSecurityGroup('factiii-' + projectName + '-rds', vpcId, region);
197
+ if (!rdsSgId) {
198
+ console.log(' RDS security group must be created first');
199
+ return false;
200
+ }
201
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
202
+ const { extractEnvironments } = require('../../../../utils/config-helpers.js');
203
+ const environments = extractEnvironments(config);
204
+ const stagingEnv = environments.staging;
205
+ if (!stagingEnv?.domain) {
206
+ console.log(' No staging domain configured');
207
+ return false;
208
+ }
209
+ try {
210
+ const stagingIp = stagingEnv.domain;
211
+ // Add inbound rule for Mac Mini IP on PostgreSQL port
212
+ (0, aws_helpers_js_1.awsExec)('aws ec2 authorize-security-group-ingress --group-id ' + rdsSgId +
213
+ ' --protocol tcp --port 5432 --cidr ' + stagingIp + '/32', region);
214
+ console.log(' Allowed Mac Mini (' + stagingIp + ') access to RDS on port 5432');
215
+ return true;
216
+ }
217
+ catch (e) {
218
+ console.log(' Failed to add Mac Mini access: ' + (e instanceof Error ? e.message : String(e)));
219
+ return false;
220
+ }
221
+ },
222
+ manualFix: 'Add inbound rule to RDS security group for staging server IP on port 5432',
223
+ },
224
+ ];
225
+ //# sourceMappingURL=security-groups.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security-groups.js","sourceRoot":"","sources":["../../../../../src/plugins/pipelines/aws/scanfix/security-groups.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * AWS SES Fixes
3
+ *
4
+ * Configures Simple Email Service for transactional email.
5
+ * Handles domain verification, DKIM setup, and sandbox status.
6
+ */
7
+ import type { Fix } from '../../../../types/index.js';
8
+ export declare const sesFixes: Fix[];
9
+ //# sourceMappingURL=ses.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ses.d.ts","sourceRoot":"","sources":["../../../../../src/plugins/pipelines/aws/scanfix/ses.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAiB,GAAG,EAAE,MAAM,4BAA4B,CAAC;AAqDrE,eAAO,MAAM,QAAQ,EAAE,GAAG,EAkIzB,CAAC"}
@@ -0,0 +1,174 @@
1
+ "use strict";
2
+ /**
3
+ * AWS SES Fixes
4
+ *
5
+ * Configures Simple Email Service for transactional email.
6
+ * Handles domain verification, DKIM setup, and sandbox status.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.sesFixes = void 0;
10
+ const aws_helpers_js_1 = require("../utils/aws-helpers.js");
11
+ /**
12
+ * Get the production domain from config
13
+ */
14
+ function getProdDomain(config) {
15
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
16
+ const { extractEnvironments } = require('../../../../utils/config-helpers.js');
17
+ const environments = extractEnvironments(config);
18
+ const prodEnv = environments.prod ?? environments.production;
19
+ const domain = prodEnv?.domain;
20
+ if (!domain || domain.startsWith('EXAMPLE-'))
21
+ return null;
22
+ return domain;
23
+ }
24
+ /**
25
+ * Check if domain is verified in SES
26
+ */
27
+ function isDomainVerified(domain, region) {
28
+ const result = (0, aws_helpers_js_1.awsExecSafe)('aws ses get-identity-verification-attributes --identities ' + domain +
29
+ ' --query "VerificationAttributes.' + domain + '.VerificationStatus" --output text', region);
30
+ return result === 'Success';
31
+ }
32
+ /**
33
+ * Check if DKIM is configured for domain
34
+ */
35
+ function hasDkim(domain, region) {
36
+ const result = (0, aws_helpers_js_1.awsExecSafe)('aws ses get-identity-dkim-attributes --identities ' + domain +
37
+ ' --query "DkimAttributes.' + domain + '.DkimEnabled" --output text', region);
38
+ return result === 'true' || result === 'True';
39
+ }
40
+ /**
41
+ * Check if AWS is configured for this project
42
+ */
43
+ function isAwsConfigured(config) {
44
+ if (config.aws)
45
+ return true;
46
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
47
+ const { extractEnvironments } = require('../../../../utils/config-helpers.js');
48
+ const environments = extractEnvironments(config);
49
+ return Object.values(environments).some((e) => e.pipeline === 'aws');
50
+ }
51
+ exports.sesFixes = [
52
+ {
53
+ id: 'aws-ses-domain-missing',
54
+ stage: 'prod',
55
+ severity: 'warning',
56
+ description: 'SES domain identity not verified for email',
57
+ scan: async (config) => {
58
+ if (!isAwsConfigured(config))
59
+ return false;
60
+ const { region } = (0, aws_helpers_js_1.getAwsConfig)(config);
61
+ const domain = getProdDomain(config);
62
+ if (!domain)
63
+ return false;
64
+ return !isDomainVerified(domain, region);
65
+ },
66
+ fix: async (config) => {
67
+ const { region } = (0, aws_helpers_js_1.getAwsConfig)(config);
68
+ const domain = getProdDomain(config);
69
+ if (!domain) {
70
+ console.log(' Set production domain in factiii.yml first');
71
+ return false;
72
+ }
73
+ try {
74
+ // Start domain verification
75
+ (0, aws_helpers_js_1.awsExec)('aws ses verify-domain-identity --domain ' + domain, region);
76
+ // Get the verification token
77
+ const tokenResult = (0, aws_helpers_js_1.awsExec)('aws ses get-identity-verification-attributes --identities ' + domain +
78
+ ' --query "VerificationAttributes.' + domain + '.VerificationToken" --output text', region);
79
+ const token = tokenResult.replace(/"/g, '');
80
+ console.log(' Started domain verification for: ' + domain);
81
+ console.log('');
82
+ console.log(' Add this TXT record to your DNS:');
83
+ console.log(' Name: _amazonses.' + domain);
84
+ console.log(' Type: TXT');
85
+ console.log(' Value: ' + token);
86
+ console.log('');
87
+ console.log(' Verification may take a few minutes after DNS propagation.');
88
+ return true;
89
+ }
90
+ catch (e) {
91
+ console.log(' Failed to start domain verification: ' + (e instanceof Error ? e.message : String(e)));
92
+ return false;
93
+ }
94
+ },
95
+ manualFix: 'Verify domain in SES: aws ses verify-domain-identity --domain <domain>\nThen add the TXT record to DNS',
96
+ },
97
+ {
98
+ id: 'aws-ses-dkim-missing',
99
+ stage: 'prod',
100
+ severity: 'info',
101
+ description: 'SES DKIM not configured (improves email deliverability)',
102
+ scan: async (config) => {
103
+ if (!isAwsConfigured(config))
104
+ return false;
105
+ const { region } = (0, aws_helpers_js_1.getAwsConfig)(config);
106
+ const domain = getProdDomain(config);
107
+ if (!domain)
108
+ return false;
109
+ if (!isDomainVerified(domain, region))
110
+ return false; // Domain must be verified first
111
+ return !hasDkim(domain, region);
112
+ },
113
+ fix: async (config) => {
114
+ const { region } = (0, aws_helpers_js_1.getAwsConfig)(config);
115
+ const domain = getProdDomain(config);
116
+ if (!domain)
117
+ return false;
118
+ try {
119
+ // Generate DKIM tokens
120
+ const result = (0, aws_helpers_js_1.awsExec)('aws ses verify-domain-dkim --domain ' + domain, region);
121
+ const parsed = JSON.parse(result);
122
+ const tokens = parsed.DkimTokens ?? [];
123
+ console.log(' Generated DKIM tokens for: ' + domain);
124
+ console.log('');
125
+ console.log(' Add these CNAME records to your DNS:');
126
+ for (const token of tokens) {
127
+ console.log(' Name: ' + token + '._domainkey.' + domain);
128
+ console.log(' Type: CNAME');
129
+ console.log(' Value: ' + token + '.dkim.amazonses.com');
130
+ console.log('');
131
+ }
132
+ console.log(' DKIM verification may take a few minutes after DNS propagation.');
133
+ return true;
134
+ }
135
+ catch (e) {
136
+ console.log(' Failed to configure DKIM: ' + (e instanceof Error ? e.message : String(e)));
137
+ return false;
138
+ }
139
+ },
140
+ manualFix: 'Configure DKIM: aws ses verify-domain-dkim --domain <domain>\nThen add CNAME records to DNS',
141
+ },
142
+ {
143
+ id: 'aws-ses-sandbox',
144
+ stage: 'prod',
145
+ severity: 'info',
146
+ description: 'SES is in sandbox mode (can only send to verified emails)',
147
+ scan: async (config) => {
148
+ if (!isAwsConfigured(config))
149
+ return false;
150
+ const { region } = (0, aws_helpers_js_1.getAwsConfig)(config);
151
+ const domain = getProdDomain(config);
152
+ if (!domain)
153
+ return false;
154
+ if (!isDomainVerified(domain, region))
155
+ return false;
156
+ // Check sending quota — sandbox has max 200/day
157
+ const result = (0, aws_helpers_js_1.awsExecSafe)('aws ses get-send-quota --query "Max24HourSend" --output text', region);
158
+ if (!result)
159
+ return false;
160
+ const maxSend = parseFloat(result);
161
+ return maxSend <= 200; // Sandbox limit
162
+ },
163
+ fix: null,
164
+ manualFix: [
165
+ 'SES is in sandbox mode. To send to unverified emails:',
166
+ '',
167
+ '1. Go to AWS Console → SES → Account dashboard',
168
+ '2. Click "Request production access"',
169
+ '3. Fill in the form with your use case',
170
+ '4. AWS typically approves within 24 hours',
171
+ ].join('\n'),
172
+ },
173
+ ];
174
+ //# sourceMappingURL=ses.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ses.js","sourceRoot":"","sources":["../../../../../src/plugins/pipelines/aws/scanfix/ses.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * AWS VPC Fixes
3
+ *
4
+ * Provisions VPC, subnets, and internet gateway for AWS infrastructure.
5
+ * All resources are tagged with factiii:project={name} for identification.
6
+ */
7
+ import type { Fix } from '../../../../types/index.js';
8
+ export declare const vpcFixes: Fix[];
9
+ //# sourceMappingURL=vpc.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vpc.d.ts","sourceRoot":"","sources":["../../../../../src/plugins/pipelines/aws/scanfix/vpc.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAiB,GAAG,EAAE,MAAM,4BAA4B,CAAC;AAgErE,eAAO,MAAM,QAAQ,EAAE,GAAG,EAmOzB,CAAC"}