@gugananuvem/aws-local-simulator 1.0.35 → 1.0.39
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 +662 -658
- package/package.json +10 -3
- package/src/config/default-config.js +71 -0
- package/src/config/env-loader.js +4 -2
- package/src/middleware/authorization.js +271 -0
- package/src/middleware/cloudtrail-logger.js +333 -0
- package/src/middleware/error-handler.js +138 -0
- package/src/middleware/index.js +79 -0
- package/src/middleware/policy-enforcement.js +407 -0
- package/src/server.js +74 -4
- package/src/services/acm/index.js +66 -0
- package/src/services/acm/models/certificate.js +202 -0
- package/src/services/acm/server.js +224 -0
- package/src/services/acm/simulator.js +293 -0
- package/src/services/alb/index.js +104 -0
- package/src/services/alb/models/loadBalancer.js +88 -0
- package/src/services/alb/models/targetGroup.js +128 -0
- package/src/services/alb/server.js +160 -0
- package/src/services/alb/simulator.js +262 -0
- package/src/services/apigateway/index.js +22 -0
- package/src/services/apigateway/server.js +247 -35
- package/src/services/apigateway/simulator.js +780 -26
- package/src/services/asg/index.js +100 -0
- package/src/services/asg/models/autoScalingGroup.js +110 -0
- package/src/services/asg/models/launchTemplate.js +41 -0
- package/src/services/asg/models/scalingPolicy.js +51 -0
- package/src/services/asg/server.js +236 -0
- package/src/services/asg/simulator.js +410 -0
- package/src/services/aurora/cluster-manager.js +731 -0
- package/src/services/aurora/data-api.js +514 -0
- package/src/services/aurora/db-engine.js +270 -0
- package/src/services/aurora/index.js +159 -0
- package/src/services/aurora/rds-api.js +189 -0
- package/src/services/aurora/server.js +213 -0
- package/src/services/aurora/sql-translator.js +334 -0
- package/src/services/cloudformation/index.js +2 -2
- package/src/services/cloudformation/server.js +1 -0
- package/src/services/cloudfront/cache-engine.js +225 -0
- package/src/services/cloudfront/geo-restrictions.js +377 -0
- package/src/services/cloudfront/index.js +220 -0
- package/src/services/cloudfront/models/behavior.js +158 -0
- package/src/services/cloudfront/models/distribution.js +284 -0
- package/src/services/cloudfront/models/index.js +99 -0
- package/src/services/cloudfront/models/invalidation.js +109 -0
- package/src/services/cloudfront/models/origin.js +155 -0
- package/src/services/cloudfront/origin-router.js +552 -0
- package/src/services/cloudfront/origin-validator.js +398 -0
- package/src/services/cloudfront/server.js +512 -0
- package/src/services/cloudfront/signed-url-generator.js +377 -0
- package/src/services/cloudfront/simulator.js +425 -0
- package/src/services/cloudfront/store.js +326 -0
- package/src/services/cloudshell/env-builder.js +27 -0
- package/src/services/cloudshell/index.js +48 -0
- package/src/services/cloudshell/routes.js +60 -0
- package/src/services/cloudshell/session-manager.js +226 -0
- package/src/services/cloudshell/static/.gitkeep +0 -0
- package/src/services/cloudshell/static/index.html +406 -0
- package/src/services/cloudshell/websocket-handler.js +107 -0
- package/src/services/cloudtrail/index.js +2 -3
- package/src/services/cloudtrail/server.js +68 -0
- package/src/services/cognito/server.js +4 -1
- package/src/services/dynamodb/server.js +4 -1
- package/src/services/dynamodb/simulator.js +2 -1
- package/src/services/ec2/index.js +101 -0
- package/src/services/ec2/instanceServer.js +311 -0
- package/src/services/ec2/models/ami.js +39 -0
- package/src/services/ec2/models/instance.js +98 -0
- package/src/services/ec2/models/networkInterface.js +74 -0
- package/src/services/ec2/models/securityGroup.js +71 -0
- package/src/services/ec2/server.js +350 -0
- package/src/services/ec2/simulator.js +436 -0
- package/src/services/eventbridge/server.js +36 -0
- package/src/services/eventbridge/simulator.js +230 -45
- package/src/services/iam/index.js +65 -0
- package/src/services/iam/middleware.js +99 -0
- package/src/services/iam/server.js +331 -0
- package/src/services/iam/simulator.js +1432 -0
- package/src/services/index.js +28 -0
- package/src/services/kinesis-analytics/index.js +105 -0
- package/src/services/kinesis-analytics/models/application.js +325 -0
- package/src/services/kinesis-analytics/models/index.js +12 -0
- package/src/services/kinesis-analytics/server.js +250 -0
- package/src/services/kinesis-analytics/simulator.js +407 -0
- package/src/services/kinesis-analytics/store.js +176 -0
- package/src/services/kinesis-data-streams/index.js +106 -0
- package/src/services/kinesis-data-streams/models/index.js +12 -0
- package/src/services/kinesis-data-streams/models/record.js +70 -0
- package/src/services/kinesis-data-streams/models/stream.js +280 -0
- package/src/services/kinesis-data-streams/server.js +255 -0
- package/src/services/kinesis-data-streams/simulator.js +514 -0
- package/src/services/kinesis-data-streams/store.js +163 -0
- package/src/services/kinesis-firehose/index.js +106 -0
- package/src/services/kinesis-firehose/models/delivery-stream.js +265 -0
- package/src/services/kinesis-firehose/models/index.js +10 -0
- package/src/services/kinesis-firehose/server.js +215 -0
- package/src/services/kinesis-firehose/simulator.js +388 -0
- package/src/services/kinesis-firehose/store.js +163 -0
- package/src/services/kms/server.js +4 -1
- package/src/services/lambda/index.js +26 -0
- package/src/services/lambda/server.js +12 -1
- package/src/services/lambda/simulator.js +4 -0
- package/src/services/opensearch/index.js +105 -0
- package/src/services/opensearch/models/document.js +115 -0
- package/src/services/opensearch/models/index.js +73 -0
- package/src/services/opensearch/server.js +310 -0
- package/src/services/opensearch/simulator.js +605 -0
- package/src/services/opensearch/store.js +162 -0
- package/src/services/organizations/control-tower-simulator.js +321 -0
- package/src/services/organizations/control-tower-store.js +182 -0
- package/src/services/organizations/iam-integration.js +413 -0
- package/src/services/organizations/index.js +172 -0
- package/src/services/organizations/models/index.js +13 -0
- package/src/services/organizations/models/invitation.js +48 -0
- package/src/services/organizations/models/organization.js +566 -0
- package/src/services/organizations/models/role.js +244 -0
- package/src/services/organizations/models/scp.js +131 -0
- package/src/services/organizations/server.js +736 -0
- package/src/services/organizations/simulator.js +593 -0
- package/src/services/organizations/store.js +235 -0
- package/src/services/organizations/vpc-integration.js +453 -0
- package/src/services/route53/index.js +67 -0
- package/src/services/route53/models/healthCheck.js +101 -0
- package/src/services/route53/models/hostedZone.js +37 -0
- package/src/services/route53/models/resourceRecord.js +106 -0
- package/src/services/route53/server.js +841 -0
- package/src/services/route53/simulator.js +350 -0
- package/src/services/s3/index.js +62 -0
- package/src/services/s3/presigned-url-generator.js +337 -0
- package/src/services/s3/server.js +231 -0
- package/src/services/s3/simulator.js +551 -4
- package/src/services/sns/index.js +31 -0
- package/src/services/sns/server.js +9 -0
- package/src/services/sqs/index.js +38 -0
- package/src/services/sqs/server.js +57 -4
- package/src/services/sqs/simulator.js +423 -33
- package/src/services/sts/simulator.js +209 -17
- package/src/services/vpc/README.md +459 -0
- package/src/services/vpc/ec2ResponseFormatter.js +431 -0
- package/src/services/vpc/index.js +90 -0
- package/src/services/vpc/models/internetGateway.js +71 -0
- package/src/services/vpc/models/routeTable.js +160 -0
- package/src/services/vpc/models/subnet.js +48 -0
- package/src/services/vpc/models/vpc.js +37 -0
- package/src/services/vpc/models/vpcEndpoint.js +100 -0
- package/src/services/vpc/models/vpcGateway.js +134 -0
- package/src/services/vpc/server.js +836 -0
- package/src/services/vpc/simulator.js +613 -0
- package/src/utils/policy-cache.js +215 -0
- package/aws-config +0 -154
|
@@ -0,0 +1,398 @@
|
|
|
1
|
+
const crypto = require('crypto');
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Origin Validator and Restriction Checker for CloudFront
|
|
5
|
+
* Validates origin accessibility, enforces origin restrictions, and manages Origin Custom Headers
|
|
6
|
+
*/
|
|
7
|
+
class OriginValidator {
|
|
8
|
+
constructor() {
|
|
9
|
+
this.validationCache = new Map();
|
|
10
|
+
this.cacheExpiry = 5 * 60 * 1000; // 5 minutes
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Validate that an origin is reachable and compatible
|
|
15
|
+
* @param {object} origin - Origin object from Distribution
|
|
16
|
+
* @returns {Promise<object>} Validation result
|
|
17
|
+
*/
|
|
18
|
+
async validateOrigin(origin) {
|
|
19
|
+
const cacheKey = `${origin.domainName}-${origin.id}`;
|
|
20
|
+
|
|
21
|
+
// Check cache
|
|
22
|
+
const cached = this.validationCache.get(cacheKey);
|
|
23
|
+
if (cached && Date.now() - cached.timestamp < this.cacheExpiry) {
|
|
24
|
+
return cached.result;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
try {
|
|
28
|
+
const result = await this._performValidation(origin);
|
|
29
|
+
|
|
30
|
+
// Cache result
|
|
31
|
+
this.validationCache.set(cacheKey, {
|
|
32
|
+
result,
|
|
33
|
+
timestamp: Date.now()
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
return result;
|
|
37
|
+
} catch (error) {
|
|
38
|
+
return {
|
|
39
|
+
isValid: false,
|
|
40
|
+
error: error.message,
|
|
41
|
+
originId: origin.id
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Check if a request should be allowed based on origin restrictions
|
|
48
|
+
* @param {object} origin - Origin object
|
|
49
|
+
* @param {object} request - Request object with headers, ip, etc.
|
|
50
|
+
* @returns {object} Restriction check result
|
|
51
|
+
*/
|
|
52
|
+
checkOriginRestrictions(origin, request = {}) {
|
|
53
|
+
const violations = [];
|
|
54
|
+
|
|
55
|
+
// Check origin custom headers
|
|
56
|
+
if (origin.customHeaders && origin.customHeaders.length > 0) {
|
|
57
|
+
for (const header of origin.customHeaders) {
|
|
58
|
+
const requestValue = request.headers?.[header.headerName];
|
|
59
|
+
if (requestValue !== header.headerValue) {
|
|
60
|
+
violations.push({
|
|
61
|
+
type: 'CUSTOM_HEADER_MISMATCH',
|
|
62
|
+
header: header.headerName,
|
|
63
|
+
expected: header.headerValue,
|
|
64
|
+
received: requestValue
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Check origin SSL/TLS requirements
|
|
71
|
+
if (origin.originSslProtocols && request.protocol) {
|
|
72
|
+
const allowedProtocols = origin.originSslProtocols;
|
|
73
|
+
if (!allowedProtocols.includes(request.protocol)) {
|
|
74
|
+
violations.push({
|
|
75
|
+
type: 'SSL_PROTOCOL_NOT_ALLOWED',
|
|
76
|
+
allowed: allowedProtocols,
|
|
77
|
+
requested: request.protocol
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Check keep-alive timeout
|
|
83
|
+
if (origin.originKeepAliveTimeout !== undefined) {
|
|
84
|
+
// This is more of a configuration that affects how long connections stay open
|
|
85
|
+
// Not a restriction per se, but recorded for monitoring
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return {
|
|
89
|
+
isAllowed: violations.length === 0,
|
|
90
|
+
violations: violations,
|
|
91
|
+
originId: origin.id
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Get origin-specific headers that should be forwarded to the origin
|
|
97
|
+
* @param {object} origin - Origin object
|
|
98
|
+
* @param {object} behavior - Behavior object (may have header policies)
|
|
99
|
+
* @returns {object} Headers to forward to origin
|
|
100
|
+
*/
|
|
101
|
+
getOriginHeaders(origin, behavior = {}) {
|
|
102
|
+
const headers = {};
|
|
103
|
+
|
|
104
|
+
// Add custom headers from origin
|
|
105
|
+
if (origin.customHeaders && origin.customHeaders.length > 0) {
|
|
106
|
+
for (const header of origin.customHeaders) {
|
|
107
|
+
headers[header.headerName] = header.headerValue;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Add origin path if specified
|
|
112
|
+
if (origin.originPath) {
|
|
113
|
+
// This is typically handled at request routing level, not as a header
|
|
114
|
+
// But we include it for reference
|
|
115
|
+
headers['X-Origin-Path'] = origin.originPath;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Add Host header (for HTTP/S origins)
|
|
119
|
+
if (origin.domainName) {
|
|
120
|
+
headers['Host'] = origin.domainName;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return headers;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Validate origin group failover configuration
|
|
128
|
+
* @param {object} originGroup - OriginGroup object
|
|
129
|
+
* @param {object} distribution - Distribution object (contains origins)
|
|
130
|
+
* @returns {object} Validation result
|
|
131
|
+
*/
|
|
132
|
+
validateOriginGroup(originGroup, distribution = {}) {
|
|
133
|
+
const errors = [];
|
|
134
|
+
|
|
135
|
+
// Check primary member
|
|
136
|
+
if (!originGroup.members || originGroup.members.length === 0) {
|
|
137
|
+
errors.push('OriginGroup must have at least one member');
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Validate all members exist in distribution
|
|
141
|
+
const originIds = distribution.origins?.map(o => o.id) || [];
|
|
142
|
+
for (const member of originGroup.members || []) {
|
|
143
|
+
if (!originIds.includes(member.originId)) {
|
|
144
|
+
errors.push(`Origin '${member.originId}' not found in distribution`);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// Check failover criteria
|
|
149
|
+
if (originGroup.failoverCriteria) {
|
|
150
|
+
const { statusCodes } = originGroup.failoverCriteria;
|
|
151
|
+
if (statusCodes && statusCodes.length === 0) {
|
|
152
|
+
errors.push('Failover status codes cannot be empty');
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Validate status codes
|
|
156
|
+
if (statusCodes) {
|
|
157
|
+
for (const code of statusCodes) {
|
|
158
|
+
if (!Number.isInteger(code) || code < 100 || code > 599) {
|
|
159
|
+
errors.push(`Invalid HTTP status code: ${code}`);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
return {
|
|
166
|
+
isValid: errors.length === 0,
|
|
167
|
+
errors: errors,
|
|
168
|
+
originGroupId: originGroup.id
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Check if origin should be used based on failover criteria
|
|
174
|
+
* @param {object} originGroup - OriginGroup object
|
|
175
|
+
* @param {number} statusCode - HTTP status code from origin
|
|
176
|
+
* @param {number} [failureCount] - Number of consecutive failures
|
|
177
|
+
* @returns {boolean} True if should failover to next origin
|
|
178
|
+
*/
|
|
179
|
+
shouldFailover(originGroup, statusCode, failureCount = 1) {
|
|
180
|
+
if (!originGroup.failoverCriteria) {
|
|
181
|
+
return false;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
const { statusCodes, quantity } = originGroup.failoverCriteria;
|
|
185
|
+
|
|
186
|
+
// Check if status code matches failover criteria
|
|
187
|
+
if (statusCodes && statusCodes.includes(statusCode)) {
|
|
188
|
+
return true;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// Check if we've hit failure threshold
|
|
192
|
+
if (quantity && failureCount >= quantity) {
|
|
193
|
+
return true;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
return false;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Get the next origin in failover sequence
|
|
201
|
+
* @param {object} originGroup - OriginGroup object
|
|
202
|
+
* @param {object} currentOrigin - Current origin being used
|
|
203
|
+
* @returns {object|null} Next origin member or null if no more failovers
|
|
204
|
+
*/
|
|
205
|
+
getFailoverOrigin(originGroup, currentOrigin) {
|
|
206
|
+
if (!originGroup.members || originGroup.members.length === 0) {
|
|
207
|
+
return null;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
const currentIndex = originGroup.members.findIndex(
|
|
211
|
+
m => m.originId === currentOrigin.id
|
|
212
|
+
);
|
|
213
|
+
|
|
214
|
+
if (currentIndex === -1 || currentIndex >= originGroup.members.length - 1) {
|
|
215
|
+
return null; // No more origins to failover to
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
return originGroup.members[currentIndex + 1];
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Validate S3 origin specific requirements
|
|
223
|
+
* @param {object} origin - Origin object
|
|
224
|
+
* @returns {object} Validation result
|
|
225
|
+
*/
|
|
226
|
+
validateS3Origin(origin) {
|
|
227
|
+
const errors = [];
|
|
228
|
+
const warnings = [];
|
|
229
|
+
|
|
230
|
+
// S3 domain should end with .s3.amazonaws.com or regional variant
|
|
231
|
+
const domainPattern = /\.s3[.-]([a-z0-9-]+)?\.amazonaws\.com$/i;
|
|
232
|
+
if (!domainPattern.test(origin.domainName)) {
|
|
233
|
+
errors.push(
|
|
234
|
+
`S3 origin domain '${origin.domainName}' does not match expected S3 format`
|
|
235
|
+
);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// Check for origin access identity configuration
|
|
239
|
+
if (!origin.s3OriginConfig?.originAccessIdentity) {
|
|
240
|
+
warnings.push(
|
|
241
|
+
'S3 origin does not use Origin Access Identity (OAI); bucket must be public or have bucket policy'
|
|
242
|
+
);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// Warn if using website endpoint instead of REST endpoint
|
|
246
|
+
if (origin.domainName.includes('.s3-website-')) {
|
|
247
|
+
warnings.push(
|
|
248
|
+
'S3 website endpoint detected; use REST endpoint for better CloudFront compatibility'
|
|
249
|
+
);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
return {
|
|
253
|
+
isValid: errors.length === 0,
|
|
254
|
+
errors: errors,
|
|
255
|
+
warnings: warnings,
|
|
256
|
+
originType: 'S3'
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Validate HTTP origin specific requirements
|
|
262
|
+
* @param {object} origin - Origin object
|
|
263
|
+
* @returns {object} Validation result
|
|
264
|
+
*/
|
|
265
|
+
validateHttpOrigin(origin) {
|
|
266
|
+
const errors = [];
|
|
267
|
+
const warnings = [];
|
|
268
|
+
|
|
269
|
+
// Validate domain format
|
|
270
|
+
try {
|
|
271
|
+
new URL(`https://${origin.domainName}`);
|
|
272
|
+
} catch (e) {
|
|
273
|
+
errors.push(`Invalid domain name: ${origin.domainName}`);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// Check port
|
|
277
|
+
if (origin.customOriginConfig?.httpPort) {
|
|
278
|
+
const port = origin.customOriginConfig.httpPort;
|
|
279
|
+
if (!Number.isInteger(port) || port < 1 || port > 65535) {
|
|
280
|
+
errors.push(`Invalid HTTP port: ${port}`);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
if (origin.customOriginConfig?.httpsPort) {
|
|
285
|
+
const port = origin.customOriginConfig.httpsPort;
|
|
286
|
+
if (!Number.isInteger(port) || port < 1 || port > 65535) {
|
|
287
|
+
errors.push(`Invalid HTTPS port: ${port}`);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// Validate origin protocol policy
|
|
292
|
+
const validPolicies = [
|
|
293
|
+
'http-only',
|
|
294
|
+
'https-only',
|
|
295
|
+
'match-viewer'
|
|
296
|
+
];
|
|
297
|
+
if (
|
|
298
|
+
origin.customOriginConfig?.originProtocolPolicy &&
|
|
299
|
+
!validPolicies.includes(origin.customOriginConfig.originProtocolPolicy)
|
|
300
|
+
) {
|
|
301
|
+
errors.push(
|
|
302
|
+
`Invalid origin protocol policy: ${origin.customOriginConfig.originProtocolPolicy}`
|
|
303
|
+
);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
return {
|
|
307
|
+
isValid: errors.length === 0,
|
|
308
|
+
errors: errors,
|
|
309
|
+
warnings: warnings,
|
|
310
|
+
originType: 'HTTP'
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Validate Lambda@Edge origin
|
|
316
|
+
* @param {object} origin - Origin object
|
|
317
|
+
* @returns {object} Validation result
|
|
318
|
+
*/
|
|
319
|
+
validateLambdaEdgeOrigin(origin) {
|
|
320
|
+
const errors = [];
|
|
321
|
+
|
|
322
|
+
// Lambda@Edge functions should have ARN format
|
|
323
|
+
const arnPattern = /^arn:aws:lambda:[a-z0-9-]+:\d{12}:function:[a-zA-Z0-9_-]+$/;
|
|
324
|
+
if (!arnPattern.test(origin.domainName)) {
|
|
325
|
+
errors.push(`Invalid Lambda@Edge ARN format: ${origin.domainName}`);
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
return {
|
|
329
|
+
isValid: errors.length === 0,
|
|
330
|
+
errors: errors,
|
|
331
|
+
originType: 'Lambda@Edge'
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* Clear validation cache
|
|
337
|
+
*/
|
|
338
|
+
clearCache() {
|
|
339
|
+
this.validationCache.clear();
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* Get validation cache stats
|
|
344
|
+
*/
|
|
345
|
+
getCacheStats() {
|
|
346
|
+
return {
|
|
347
|
+
entries: this.validationCache.size,
|
|
348
|
+
cacheExpiry: this.cacheExpiry
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
/**
|
|
353
|
+
* Private Methods
|
|
354
|
+
*/
|
|
355
|
+
|
|
356
|
+
async _performValidation(origin) {
|
|
357
|
+
const validations = [];
|
|
358
|
+
|
|
359
|
+
// Basic structure validation
|
|
360
|
+
if (!origin.id || !origin.domainName) {
|
|
361
|
+
return {
|
|
362
|
+
isValid: false,
|
|
363
|
+
error: 'Origin must have id and domainName'
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
// Type-specific validation
|
|
368
|
+
if (origin.s3OriginConfig) {
|
|
369
|
+
validations.push(this.validateS3Origin(origin));
|
|
370
|
+
} else if (origin.customOriginConfig) {
|
|
371
|
+
validations.push(this.validateHttpOrigin(origin));
|
|
372
|
+
} else if (this._isLambdaEdgeOrigin(origin)) {
|
|
373
|
+
validations.push(this.validateLambdaEdgeOrigin(origin));
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
// Check if any validation failed
|
|
377
|
+
const failedValidation = validations.find(v => !v.isValid);
|
|
378
|
+
if (failedValidation) {
|
|
379
|
+
return {
|
|
380
|
+
isValid: false,
|
|
381
|
+
...failedValidation
|
|
382
|
+
};
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
return {
|
|
386
|
+
isValid: true,
|
|
387
|
+
validations: validations,
|
|
388
|
+
originId: origin.id,
|
|
389
|
+
timestamp: new Date().toISOString()
|
|
390
|
+
};
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
_isLambdaEdgeOrigin(origin) {
|
|
394
|
+
return origin.domainName?.startsWith('arn:aws:lambda:');
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
module.exports = OriginValidator;
|