@factiii/stack 0.1.34 → 0.1.35
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/README.md +441 -441
- package/bin/stack +46 -0
- package/dist/cli/fix.js +10 -10
- package/dist/cli/fix.js.map +1 -1
- package/dist/cli/init.d.ts.map +1 -1
- package/dist/cli/init.js +20 -7
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/scan.d.ts.map +1 -1
- package/dist/cli/scan.js +14 -22
- package/dist/cli/scan.js.map +1 -1
- package/dist/generators/generate-stack-yml.d.ts +1 -1
- package/dist/generators/generate-stack-yml.d.ts.map +1 -1
- package/dist/generators/generate-stack-yml.js +96 -69
- package/dist/generators/generate-stack-yml.js.map +1 -1
- package/dist/plugins/addons/openclaw/index.d.ts +45 -0
- package/dist/plugins/addons/openclaw/index.d.ts.map +1 -0
- package/dist/plugins/addons/openclaw/index.js +107 -0
- package/dist/plugins/addons/openclaw/index.js.map +1 -0
- package/dist/plugins/addons/openclaw/scanfix/setup.d.ts +19 -0
- package/dist/plugins/addons/openclaw/scanfix/setup.d.ts.map +1 -0
- package/dist/plugins/addons/openclaw/scanfix/setup.js +441 -0
- package/dist/plugins/addons/openclaw/scanfix/setup.js.map +1 -0
- package/dist/plugins/index.d.ts.map +1 -1
- package/dist/plugins/index.js +8 -0
- package/dist/plugins/index.js.map +1 -1
- package/dist/plugins/pipelines/aws/index.js +15 -15
- package/dist/plugins/pipelines/aws/prod.js +7 -7
- package/dist/plugins/pipelines/aws/scanfix/aws-cli.d.ts +3 -1
- package/dist/plugins/pipelines/aws/scanfix/aws-cli.d.ts.map +1 -1
- package/dist/plugins/pipelines/aws/scanfix/aws-cli.js +17 -7
- package/dist/plugins/pipelines/aws/scanfix/aws-cli.js.map +1 -1
- package/dist/plugins/pipelines/aws/scanfix/credentials.d.ts +1 -1
- package/dist/plugins/pipelines/aws/scanfix/credentials.d.ts.map +1 -1
- package/dist/plugins/pipelines/aws/scanfix/credentials.js +27 -73
- package/dist/plugins/pipelines/aws/scanfix/credentials.js.map +1 -1
- package/dist/plugins/pipelines/aws/scanfix/db-replication.d.ts +1 -4
- package/dist/plugins/pipelines/aws/scanfix/db-replication.d.ts.map +1 -1
- package/dist/plugins/pipelines/aws/scanfix/db-replication.js +9 -39
- package/dist/plugins/pipelines/aws/scanfix/db-replication.js.map +1 -1
- package/dist/plugins/pipelines/aws/scanfix/ec2.d.ts +1 -0
- package/dist/plugins/pipelines/aws/scanfix/ec2.d.ts.map +1 -1
- package/dist/plugins/pipelines/aws/scanfix/ec2.js +61 -110
- package/dist/plugins/pipelines/aws/scanfix/ec2.js.map +1 -1
- package/dist/plugins/pipelines/aws/scanfix/ecr.d.ts +1 -0
- package/dist/plugins/pipelines/aws/scanfix/ecr.d.ts.map +1 -1
- package/dist/plugins/pipelines/aws/scanfix/ecr.js +25 -34
- package/dist/plugins/pipelines/aws/scanfix/ecr.js.map +1 -1
- package/dist/plugins/pipelines/aws/scanfix/iam.d.ts +1 -0
- package/dist/plugins/pipelines/aws/scanfix/iam.d.ts.map +1 -1
- package/dist/plugins/pipelines/aws/scanfix/iam.js +35 -44
- package/dist/plugins/pipelines/aws/scanfix/iam.js.map +1 -1
- package/dist/plugins/pipelines/aws/scanfix/rds.d.ts +1 -0
- package/dist/plugins/pipelines/aws/scanfix/rds.d.ts.map +1 -1
- package/dist/plugins/pipelines/aws/scanfix/rds.js +39 -104
- package/dist/plugins/pipelines/aws/scanfix/rds.js.map +1 -1
- package/dist/plugins/pipelines/aws/scanfix/s3.d.ts +1 -0
- package/dist/plugins/pipelines/aws/scanfix/s3.d.ts.map +1 -1
- package/dist/plugins/pipelines/aws/scanfix/s3.js +44 -53
- package/dist/plugins/pipelines/aws/scanfix/s3.js.map +1 -1
- package/dist/plugins/pipelines/aws/scanfix/security-groups.d.ts +1 -0
- package/dist/plugins/pipelines/aws/scanfix/security-groups.d.ts.map +1 -1
- package/dist/plugins/pipelines/aws/scanfix/security-groups.js +80 -79
- package/dist/plugins/pipelines/aws/scanfix/security-groups.js.map +1 -1
- package/dist/plugins/pipelines/aws/scanfix/ses.d.ts +1 -0
- package/dist/plugins/pipelines/aws/scanfix/ses.d.ts.map +1 -1
- package/dist/plugins/pipelines/aws/scanfix/ses.js +28 -50
- package/dist/plugins/pipelines/aws/scanfix/ses.js.map +1 -1
- package/dist/plugins/pipelines/aws/scanfix/ssh-bridge.d.ts +17 -0
- package/dist/plugins/pipelines/aws/scanfix/ssh-bridge.d.ts.map +1 -0
- package/dist/plugins/pipelines/aws/scanfix/ssh-bridge.js +180 -0
- package/dist/plugins/pipelines/aws/scanfix/ssh-bridge.js.map +1 -0
- package/dist/plugins/pipelines/aws/scanfix/vpc.d.ts +1 -0
- package/dist/plugins/pipelines/aws/scanfix/vpc.d.ts.map +1 -1
- package/dist/plugins/pipelines/aws/scanfix/vpc.js +93 -94
- package/dist/plugins/pipelines/aws/scanfix/vpc.js.map +1 -1
- package/dist/plugins/pipelines/aws/utils/aws-helpers.d.ts +101 -28
- package/dist/plugins/pipelines/aws/utils/aws-helpers.d.ts.map +1 -1
- package/dist/plugins/pipelines/aws/utils/aws-helpers.js +428 -76
- package/dist/plugins/pipelines/aws/utils/aws-helpers.js.map +1 -1
- package/dist/plugins/pipelines/factiii/index.d.ts +11 -1
- package/dist/plugins/pipelines/factiii/index.d.ts.map +1 -1
- package/dist/plugins/pipelines/factiii/index.js +183 -33
- package/dist/plugins/pipelines/factiii/index.js.map +1 -1
- package/dist/plugins/pipelines/factiii/scanfix/config.d.ts +1 -1
- package/dist/plugins/pipelines/factiii/scanfix/config.js +4 -4
- package/dist/plugins/pipelines/factiii/scanfix/secrets.d.ts.map +1 -1
- package/dist/plugins/pipelines/factiii/scanfix/secrets.js +68 -8
- package/dist/plugins/pipelines/factiii/scanfix/secrets.js.map +1 -1
- package/dist/plugins/servers/mac/index.js +13 -13
- package/dist/plugins/servers/mac/staging.js +4 -4
- package/dist/scanfix/fixes/certbot.js +1 -1
- package/dist/scripts/validate-example-values.d.ts +1 -1
- package/dist/scripts/validate-example-values.js +6 -6
- package/dist/utils/config-helpers.d.ts +3 -0
- package/dist/utils/config-helpers.d.ts.map +1 -1
- package/dist/utils/config-helpers.js.map +1 -1
- package/dist/utils/secret-prompts.d.ts +5 -2
- package/dist/utils/secret-prompts.d.ts.map +1 -1
- package/dist/utils/secret-prompts.js +55 -32
- package/dist/utils/secret-prompts.js.map +1 -1
- package/dist/utils/template-generator.js +71 -71
- package/package.json +8 -1
|
@@ -5,41 +5,11 @@
|
|
|
5
5
|
* Provisions security groups for EC2 and RDS.
|
|
6
6
|
* EC2 SG: SSH(22), HTTP(80), HTTPS(443)
|
|
7
7
|
* RDS SG: PostgreSQL(5432) from EC2 SG only
|
|
8
|
+
* Uses AWS SDK v3.
|
|
8
9
|
*/
|
|
9
10
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
11
|
exports.securityGroupFixes = void 0;
|
|
11
12
|
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 ((0, aws_helpers_js_1.isOnServer)())
|
|
35
|
-
return false;
|
|
36
|
-
if (config.aws)
|
|
37
|
-
return true;
|
|
38
|
-
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
39
|
-
const { extractEnvironments } = require('../../../../utils/config-helpers.js');
|
|
40
|
-
const environments = extractEnvironments(config);
|
|
41
|
-
return Object.values(environments).some((e) => e.pipeline === 'aws');
|
|
42
|
-
}
|
|
43
13
|
exports.securityGroupFixes = [
|
|
44
14
|
{
|
|
45
15
|
id: 'aws-sg-ec2-missing',
|
|
@@ -47,41 +17,59 @@ exports.securityGroupFixes = [
|
|
|
47
17
|
severity: 'critical',
|
|
48
18
|
description: '🛡️ EC2 security group not created (SSH, HTTP, HTTPS)',
|
|
49
19
|
scan: async (config) => {
|
|
50
|
-
if (!isAwsConfigured(config))
|
|
20
|
+
if (!(0, aws_helpers_js_1.isAwsConfigured)(config))
|
|
51
21
|
return false;
|
|
52
22
|
const { region } = (0, aws_helpers_js_1.getAwsConfig)(config);
|
|
53
23
|
const projectName = (0, aws_helpers_js_1.getProjectName)(config);
|
|
54
|
-
const vpcId = findVpc(projectName, region);
|
|
24
|
+
const vpcId = await (0, aws_helpers_js_1.findVpc)(projectName, region);
|
|
55
25
|
if (!vpcId)
|
|
56
|
-
return false;
|
|
57
|
-
return !findSecurityGroup('factiii-' + projectName + '-ec2', vpcId, region);
|
|
26
|
+
return false;
|
|
27
|
+
return !(await (0, aws_helpers_js_1.findSecurityGroup)('factiii-' + projectName + '-ec2', vpcId, region));
|
|
58
28
|
},
|
|
59
29
|
fix: async (config) => {
|
|
60
30
|
const { region } = (0, aws_helpers_js_1.getAwsConfig)(config);
|
|
61
31
|
const projectName = (0, aws_helpers_js_1.getProjectName)(config);
|
|
62
|
-
const vpcId = findVpc(projectName, region);
|
|
32
|
+
const vpcId = await (0, aws_helpers_js_1.findVpc)(projectName, region);
|
|
63
33
|
if (!vpcId) {
|
|
64
34
|
console.log(' VPC must be created first');
|
|
65
35
|
return false;
|
|
66
36
|
}
|
|
67
37
|
try {
|
|
38
|
+
const ec2 = (0, aws_helpers_js_1.getEC2Client)(region);
|
|
68
39
|
const groupName = 'factiii-' + projectName + '-ec2';
|
|
69
40
|
// Create security group
|
|
70
|
-
const sgResult = (
|
|
71
|
-
|
|
72
|
-
'
|
|
73
|
-
|
|
74
|
-
|
|
41
|
+
const sgResult = await ec2.send(new aws_helpers_js_1.CreateSecurityGroupCommand({
|
|
42
|
+
GroupName: groupName,
|
|
43
|
+
Description: 'EC2 security group for ' + projectName,
|
|
44
|
+
VpcId: vpcId,
|
|
45
|
+
TagSpecifications: [(0, aws_helpers_js_1.tagSpec)('security-group', projectName)],
|
|
46
|
+
}));
|
|
47
|
+
const sgId = sgResult.GroupId;
|
|
75
48
|
console.log(' Created EC2 security group: ' + sgId);
|
|
76
49
|
// Allow SSH (port 22)
|
|
77
|
-
(
|
|
78
|
-
|
|
50
|
+
await ec2.send(new aws_helpers_js_1.AuthorizeSecurityGroupIngressCommand({
|
|
51
|
+
GroupId: sgId,
|
|
52
|
+
IpProtocol: 'tcp',
|
|
53
|
+
FromPort: 22,
|
|
54
|
+
ToPort: 22,
|
|
55
|
+
CidrIp: '0.0.0.0/0',
|
|
56
|
+
}));
|
|
79
57
|
// Allow HTTP (port 80)
|
|
80
|
-
(
|
|
81
|
-
|
|
58
|
+
await ec2.send(new aws_helpers_js_1.AuthorizeSecurityGroupIngressCommand({
|
|
59
|
+
GroupId: sgId,
|
|
60
|
+
IpProtocol: 'tcp',
|
|
61
|
+
FromPort: 80,
|
|
62
|
+
ToPort: 80,
|
|
63
|
+
CidrIp: '0.0.0.0/0',
|
|
64
|
+
}));
|
|
82
65
|
// Allow HTTPS (port 443)
|
|
83
|
-
(
|
|
84
|
-
|
|
66
|
+
await ec2.send(new aws_helpers_js_1.AuthorizeSecurityGroupIngressCommand({
|
|
67
|
+
GroupId: sgId,
|
|
68
|
+
IpProtocol: 'tcp',
|
|
69
|
+
FromPort: 443,
|
|
70
|
+
ToPort: 443,
|
|
71
|
+
CidrIp: '0.0.0.0/0',
|
|
72
|
+
}));
|
|
85
73
|
console.log(' Allowed inbound: SSH(22), HTTP(80), HTTPS(443)');
|
|
86
74
|
return true;
|
|
87
75
|
}
|
|
@@ -98,41 +86,50 @@ exports.securityGroupFixes = [
|
|
|
98
86
|
severity: 'critical',
|
|
99
87
|
description: '🛡️ RDS security group not created (PostgreSQL from EC2 only)',
|
|
100
88
|
scan: async (config) => {
|
|
101
|
-
if (!isAwsConfigured(config))
|
|
89
|
+
if (!(0, aws_helpers_js_1.isAwsConfigured)(config))
|
|
102
90
|
return false;
|
|
103
91
|
const { region } = (0, aws_helpers_js_1.getAwsConfig)(config);
|
|
104
92
|
const projectName = (0, aws_helpers_js_1.getProjectName)(config);
|
|
105
|
-
const vpcId = findVpc(projectName, region);
|
|
93
|
+
const vpcId = await (0, aws_helpers_js_1.findVpc)(projectName, region);
|
|
106
94
|
if (!vpcId)
|
|
107
95
|
return false;
|
|
108
|
-
return !findSecurityGroup('factiii-' + projectName + '-rds', vpcId, region);
|
|
96
|
+
return !(await (0, aws_helpers_js_1.findSecurityGroup)('factiii-' + projectName + '-rds', vpcId, region));
|
|
109
97
|
},
|
|
110
98
|
fix: async (config) => {
|
|
111
99
|
const { region } = (0, aws_helpers_js_1.getAwsConfig)(config);
|
|
112
100
|
const projectName = (0, aws_helpers_js_1.getProjectName)(config);
|
|
113
|
-
const vpcId = findVpc(projectName, region);
|
|
101
|
+
const vpcId = await (0, aws_helpers_js_1.findVpc)(projectName, region);
|
|
114
102
|
if (!vpcId) {
|
|
115
103
|
console.log(' VPC must be created first');
|
|
116
104
|
return false;
|
|
117
105
|
}
|
|
118
|
-
|
|
119
|
-
const ec2SgId = findSecurityGroup('factiii-' + projectName + '-ec2', vpcId, region);
|
|
106
|
+
const ec2SgId = await (0, aws_helpers_js_1.findSecurityGroup)('factiii-' + projectName + '-ec2', vpcId, region);
|
|
120
107
|
if (!ec2SgId) {
|
|
121
108
|
console.log(' EC2 security group must be created first');
|
|
122
109
|
return false;
|
|
123
110
|
}
|
|
124
111
|
try {
|
|
112
|
+
const ec2 = (0, aws_helpers_js_1.getEC2Client)(region);
|
|
125
113
|
const groupName = 'factiii-' + projectName + '-rds';
|
|
126
114
|
// Create RDS security group
|
|
127
|
-
const sgResult = (
|
|
128
|
-
|
|
129
|
-
'
|
|
130
|
-
|
|
131
|
-
|
|
115
|
+
const sgResult = await ec2.send(new aws_helpers_js_1.CreateSecurityGroupCommand({
|
|
116
|
+
GroupName: groupName,
|
|
117
|
+
Description: 'RDS security group for ' + projectName,
|
|
118
|
+
VpcId: vpcId,
|
|
119
|
+
TagSpecifications: [(0, aws_helpers_js_1.tagSpec)('security-group', projectName)],
|
|
120
|
+
}));
|
|
121
|
+
const sgId = sgResult.GroupId;
|
|
132
122
|
console.log(' Created RDS security group: ' + sgId);
|
|
133
123
|
// Allow PostgreSQL (port 5432) from EC2 security group ONLY
|
|
134
|
-
(
|
|
135
|
-
|
|
124
|
+
await ec2.send(new aws_helpers_js_1.AuthorizeSecurityGroupIngressCommand({
|
|
125
|
+
GroupId: sgId,
|
|
126
|
+
IpPermissions: [{
|
|
127
|
+
IpProtocol: 'tcp',
|
|
128
|
+
FromPort: 5432,
|
|
129
|
+
ToPort: 5432,
|
|
130
|
+
UserIdGroupPairs: [{ GroupId: ec2SgId }],
|
|
131
|
+
}],
|
|
132
|
+
}));
|
|
136
133
|
console.log(' Allowed inbound: PostgreSQL(5432) from EC2 SG only');
|
|
137
134
|
return true;
|
|
138
135
|
}
|
|
@@ -149,41 +146,40 @@ exports.securityGroupFixes = [
|
|
|
149
146
|
severity: 'info',
|
|
150
147
|
description: '🛡️ RDS security group does not allow Mac Mini staging access',
|
|
151
148
|
scan: async (config) => {
|
|
152
|
-
if (!isAwsConfigured(config))
|
|
149
|
+
if (!(0, aws_helpers_js_1.isAwsConfigured)(config))
|
|
153
150
|
return false;
|
|
154
151
|
const { region } = (0, aws_helpers_js_1.getAwsConfig)(config);
|
|
155
152
|
const projectName = (0, aws_helpers_js_1.getProjectName)(config);
|
|
156
|
-
const vpcId = findVpc(projectName, region);
|
|
153
|
+
const vpcId = await (0, aws_helpers_js_1.findVpc)(projectName, region);
|
|
157
154
|
if (!vpcId)
|
|
158
155
|
return false;
|
|
159
|
-
const rdsSgId = findSecurityGroup('factiii-' + projectName + '-rds', vpcId, region);
|
|
156
|
+
const rdsSgId = await (0, aws_helpers_js_1.findSecurityGroup)('factiii-' + projectName + '-rds', vpcId, region);
|
|
160
157
|
if (!rdsSgId)
|
|
161
|
-
return false;
|
|
162
|
-
// Check if staging domain is configured
|
|
158
|
+
return false;
|
|
163
159
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
164
160
|
const { extractEnvironments } = require('../../../../utils/config-helpers.js');
|
|
165
161
|
const environments = extractEnvironments(config);
|
|
166
162
|
const stagingEnv = environments.staging;
|
|
167
163
|
if (!stagingEnv?.domain)
|
|
168
|
-
return false; // No staging configured
|
|
169
|
-
// Check if RDS SG has an inbound rule for the staging IP
|
|
170
|
-
const rulesResult = (0, aws_helpers_js_1.awsExecSafe)('aws ec2 describe-security-groups --group-ids ' + rdsSgId + ' --query "SecurityGroups[0].IpPermissions" --output json', region);
|
|
171
|
-
if (!rulesResult)
|
|
172
164
|
return false;
|
|
165
|
+
// Check if RDS SG has an inbound rule for the staging IP
|
|
173
166
|
try {
|
|
174
|
-
const
|
|
167
|
+
const ec2 = (0, aws_helpers_js_1.getEC2Client)(region);
|
|
168
|
+
const rulesResult = await ec2.send(new aws_helpers_js_1.DescribeSecurityGroupsCommand({
|
|
169
|
+
GroupIds: [rdsSgId],
|
|
170
|
+
}));
|
|
171
|
+
const rules = rulesResult.SecurityGroups?.[0]?.IpPermissions ?? [];
|
|
175
172
|
const stagingIp = stagingEnv.domain;
|
|
176
|
-
// Check if any rule allows the staging IP on port 5432
|
|
177
173
|
for (const rule of rules) {
|
|
178
174
|
if (rule.FromPort === 5432 && rule.ToPort === 5432) {
|
|
179
|
-
for (const ipRange of (rule.IpRanges
|
|
175
|
+
for (const ipRange of (rule.IpRanges ?? [])) {
|
|
180
176
|
if (ipRange.CidrIp === stagingIp + '/32') {
|
|
181
|
-
return false;
|
|
177
|
+
return false;
|
|
182
178
|
}
|
|
183
179
|
}
|
|
184
180
|
}
|
|
185
181
|
}
|
|
186
|
-
return true;
|
|
182
|
+
return true;
|
|
187
183
|
}
|
|
188
184
|
catch {
|
|
189
185
|
return false;
|
|
@@ -192,10 +188,10 @@ exports.securityGroupFixes = [
|
|
|
192
188
|
fix: async (config) => {
|
|
193
189
|
const { region } = (0, aws_helpers_js_1.getAwsConfig)(config);
|
|
194
190
|
const projectName = (0, aws_helpers_js_1.getProjectName)(config);
|
|
195
|
-
const vpcId = findVpc(projectName, region);
|
|
191
|
+
const vpcId = await (0, aws_helpers_js_1.findVpc)(projectName, region);
|
|
196
192
|
if (!vpcId)
|
|
197
193
|
return false;
|
|
198
|
-
const rdsSgId = findSecurityGroup('factiii-' + projectName + '-rds', vpcId, region);
|
|
194
|
+
const rdsSgId = await (0, aws_helpers_js_1.findSecurityGroup)('factiii-' + projectName + '-rds', vpcId, region);
|
|
199
195
|
if (!rdsSgId) {
|
|
200
196
|
console.log(' RDS security group must be created first');
|
|
201
197
|
return false;
|
|
@@ -209,10 +205,15 @@ exports.securityGroupFixes = [
|
|
|
209
205
|
return false;
|
|
210
206
|
}
|
|
211
207
|
try {
|
|
208
|
+
const ec2 = (0, aws_helpers_js_1.getEC2Client)(region);
|
|
212
209
|
const stagingIp = stagingEnv.domain;
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
'
|
|
210
|
+
await ec2.send(new aws_helpers_js_1.AuthorizeSecurityGroupIngressCommand({
|
|
211
|
+
GroupId: rdsSgId,
|
|
212
|
+
IpProtocol: 'tcp',
|
|
213
|
+
FromPort: 5432,
|
|
214
|
+
ToPort: 5432,
|
|
215
|
+
CidrIp: stagingIp + '/32',
|
|
216
|
+
}));
|
|
216
217
|
console.log(' Allowed Mac Mini (' + stagingIp + ') access to RDS on port 5432');
|
|
217
218
|
return true;
|
|
218
219
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"security-groups.js","sourceRoot":"","sources":["../../../../../src/plugins/pipelines/aws/scanfix/security-groups.ts"],"names":[],"mappings":";AAAA
|
|
1
|
+
{"version":3,"file":"security-groups.js","sourceRoot":"","sources":["../../../../../src/plugins/pipelines/aws/scanfix/security-groups.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ses.d.ts","sourceRoot":"","sources":["../../../../../src/plugins/pipelines/aws/scanfix/ses.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"ses.d.ts","sourceRoot":"","sources":["../../../../../src/plugins/pipelines/aws/scanfix/ses.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAiB,GAAG,EAAE,MAAM,4BAA4B,CAAC;AA0BrE,eAAO,MAAM,QAAQ,EAAE,GAAG,EA8HzB,CAAC"}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*
|
|
5
5
|
* Configures Simple Email Service for transactional email.
|
|
6
6
|
* Handles domain verification, DKIM setup, and sandbox status.
|
|
7
|
+
* Uses AWS SDK v3.
|
|
7
8
|
*/
|
|
8
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
10
|
exports.sesFixes = void 0;
|
|
@@ -17,39 +18,10 @@ function getProdDomain(config) {
|
|
|
17
18
|
const environments = extractEnvironments(config);
|
|
18
19
|
const prodEnv = environments.prod ?? environments.production;
|
|
19
20
|
const domain = prodEnv?.domain;
|
|
20
|
-
if (!domain || domain.startsWith('
|
|
21
|
+
if (!domain || domain.startsWith('EXAMPLE_'))
|
|
21
22
|
return null;
|
|
22
23
|
return domain;
|
|
23
24
|
}
|
|
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 ((0, aws_helpers_js_1.isOnServer)())
|
|
45
|
-
return false;
|
|
46
|
-
if (config.aws)
|
|
47
|
-
return true;
|
|
48
|
-
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
49
|
-
const { extractEnvironments } = require('../../../../utils/config-helpers.js');
|
|
50
|
-
const environments = extractEnvironments(config);
|
|
51
|
-
return Object.values(environments).some((e) => e.pipeline === 'aws');
|
|
52
|
-
}
|
|
53
25
|
exports.sesFixes = [
|
|
54
26
|
{
|
|
55
27
|
id: 'aws-ses-domain-missing',
|
|
@@ -57,13 +29,13 @@ exports.sesFixes = [
|
|
|
57
29
|
severity: 'warning',
|
|
58
30
|
description: '📧 SES domain identity not verified for email',
|
|
59
31
|
scan: async (config) => {
|
|
60
|
-
if (!isAwsConfigured(config))
|
|
32
|
+
if (!(0, aws_helpers_js_1.isAwsConfigured)(config))
|
|
61
33
|
return false;
|
|
62
34
|
const { region } = (0, aws_helpers_js_1.getAwsConfig)(config);
|
|
63
35
|
const domain = getProdDomain(config);
|
|
64
36
|
if (!domain)
|
|
65
37
|
return false;
|
|
66
|
-
return !isDomainVerified(domain, region);
|
|
38
|
+
return !(await (0, aws_helpers_js_1.isDomainVerified)(domain, region));
|
|
67
39
|
},
|
|
68
40
|
fix: async (config) => {
|
|
69
41
|
const { region } = (0, aws_helpers_js_1.getAwsConfig)(config);
|
|
@@ -73,12 +45,14 @@ exports.sesFixes = [
|
|
|
73
45
|
return false;
|
|
74
46
|
}
|
|
75
47
|
try {
|
|
48
|
+
const ses = (0, aws_helpers_js_1.getSESClient)(region);
|
|
76
49
|
// Start domain verification
|
|
77
|
-
(
|
|
50
|
+
await ses.send(new aws_helpers_js_1.VerifyDomainIdentityCommand({ Domain: domain }));
|
|
78
51
|
// Get the verification token
|
|
79
|
-
const tokenResult = (
|
|
80
|
-
|
|
81
|
-
|
|
52
|
+
const tokenResult = await ses.send(new aws_helpers_js_1.GetIdentityVerificationAttributesCommand({
|
|
53
|
+
Identities: [domain],
|
|
54
|
+
}));
|
|
55
|
+
const token = tokenResult.VerificationAttributes?.[domain]?.VerificationToken ?? '';
|
|
82
56
|
console.log(' Started domain verification for: ' + domain);
|
|
83
57
|
console.log('');
|
|
84
58
|
console.log(' Add this TXT record to your DNS:');
|
|
@@ -102,15 +76,15 @@ exports.sesFixes = [
|
|
|
102
76
|
severity: 'info',
|
|
103
77
|
description: '📧 SES DKIM not configured (improves email deliverability)',
|
|
104
78
|
scan: async (config) => {
|
|
105
|
-
if (!isAwsConfigured(config))
|
|
79
|
+
if (!(0, aws_helpers_js_1.isAwsConfigured)(config))
|
|
106
80
|
return false;
|
|
107
81
|
const { region } = (0, aws_helpers_js_1.getAwsConfig)(config);
|
|
108
82
|
const domain = getProdDomain(config);
|
|
109
83
|
if (!domain)
|
|
110
84
|
return false;
|
|
111
|
-
if (!isDomainVerified(domain, region))
|
|
112
|
-
return false;
|
|
113
|
-
return !hasDkim(domain, region);
|
|
85
|
+
if (!(await (0, aws_helpers_js_1.isDomainVerified)(domain, region)))
|
|
86
|
+
return false;
|
|
87
|
+
return !(await (0, aws_helpers_js_1.hasDkim)(domain, region));
|
|
114
88
|
},
|
|
115
89
|
fix: async (config) => {
|
|
116
90
|
const { region } = (0, aws_helpers_js_1.getAwsConfig)(config);
|
|
@@ -118,10 +92,10 @@ exports.sesFixes = [
|
|
|
118
92
|
if (!domain)
|
|
119
93
|
return false;
|
|
120
94
|
try {
|
|
95
|
+
const ses = (0, aws_helpers_js_1.getSESClient)(region);
|
|
121
96
|
// Generate DKIM tokens
|
|
122
|
-
const result = (
|
|
123
|
-
const
|
|
124
|
-
const tokens = parsed.DkimTokens ?? [];
|
|
97
|
+
const result = await ses.send(new aws_helpers_js_1.VerifyDomainDkimCommand({ Domain: domain }));
|
|
98
|
+
const tokens = result.DkimTokens ?? [];
|
|
125
99
|
console.log(' Generated DKIM tokens for: ' + domain);
|
|
126
100
|
console.log('');
|
|
127
101
|
console.log(' Add these CNAME records to your DNS:');
|
|
@@ -147,26 +121,30 @@ exports.sesFixes = [
|
|
|
147
121
|
severity: 'info',
|
|
148
122
|
description: '📧 SES is in sandbox mode (can only send to verified emails)',
|
|
149
123
|
scan: async (config) => {
|
|
150
|
-
if (!isAwsConfigured(config))
|
|
124
|
+
if (!(0, aws_helpers_js_1.isAwsConfigured)(config))
|
|
151
125
|
return false;
|
|
152
126
|
const { region } = (0, aws_helpers_js_1.getAwsConfig)(config);
|
|
153
127
|
const domain = getProdDomain(config);
|
|
154
128
|
if (!domain)
|
|
155
129
|
return false;
|
|
156
|
-
if (!isDomainVerified(domain, region))
|
|
130
|
+
if (!(await (0, aws_helpers_js_1.isDomainVerified)(domain, region)))
|
|
157
131
|
return false;
|
|
158
132
|
// Check sending quota — sandbox has max 200/day
|
|
159
|
-
|
|
160
|
-
|
|
133
|
+
try {
|
|
134
|
+
const ses = (0, aws_helpers_js_1.getSESClient)(region);
|
|
135
|
+
const result = await ses.send(new aws_helpers_js_1.GetSendQuotaCommand({}));
|
|
136
|
+
const maxSend = result.Max24HourSend ?? 0;
|
|
137
|
+
return maxSend <= 200;
|
|
138
|
+
}
|
|
139
|
+
catch {
|
|
161
140
|
return false;
|
|
162
|
-
|
|
163
|
-
return maxSend <= 200; // Sandbox limit
|
|
141
|
+
}
|
|
164
142
|
},
|
|
165
143
|
fix: null,
|
|
166
144
|
manualFix: [
|
|
167
145
|
'SES is in sandbox mode. To send to unverified emails:',
|
|
168
146
|
'',
|
|
169
|
-
'1. Go to AWS Console
|
|
147
|
+
'1. Go to AWS Console > SES > Account dashboard',
|
|
170
148
|
'2. Click "Request production access"',
|
|
171
149
|
'3. Fill in the form with your use case',
|
|
172
150
|
'4. AWS typically approves within 24 hours',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ses.js","sourceRoot":"","sources":["../../../../../src/plugins/pipelines/aws/scanfix/ses.ts"],"names":[],"mappings":";AAAA
|
|
1
|
+
{"version":3,"file":"ses.js","sourceRoot":"","sources":["../../../../../src/plugins/pipelines/aws/scanfix/ses.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AWS SSH Bridge Fixes
|
|
3
|
+
*
|
|
4
|
+
* Bridges the gap between AWS EC2 key pair creation and the factiii
|
|
5
|
+
* SSH key convention (Ansible Vault PROD_SSH + ~/.ssh/prod_deploy_key).
|
|
6
|
+
*
|
|
7
|
+
* After EC2 provisions a key pair and saves it to ~/.ssh/prod_deploy_key,
|
|
8
|
+
* this fix automatically stores it in Ansible Vault as PROD_SSH so that:
|
|
9
|
+
* - Other dev machines can pull the key via `npx stack secrets write-ssh-keys`
|
|
10
|
+
* - The `missing-prod-ssh` secrets check passes
|
|
11
|
+
* - canReach('prod') returns via: 'ssh' on subsequent runs
|
|
12
|
+
*
|
|
13
|
+
* Uses AWS SDK v3 for Elastic IP lookup.
|
|
14
|
+
*/
|
|
15
|
+
import type { Fix } from '../../../../types/index.js';
|
|
16
|
+
export declare const sshBridgeFixes: Fix[];
|
|
17
|
+
//# sourceMappingURL=ssh-bridge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ssh-bridge.d.ts","sourceRoot":"","sources":["../../../../../src/plugins/pipelines/aws/scanfix/ssh-bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAKH,OAAO,KAAK,EAAiB,GAAG,EAAE,MAAM,4BAA4B,CAAC;AAuBrE,eAAO,MAAM,cAAc,EAAE,GAAG,EA8G/B,CAAC"}
|