Skip to content

Commit c5db6f7

Browse files
author
@tomnight
committed
Update to version v5.2.0
1 parent 1930e37 commit c5db6f7

File tree

14 files changed

+1149
-74
lines changed

14 files changed

+1149
-74
lines changed

CHANGELOG.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,26 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

7+
## [5.2.0] - 2021-01-29
8+
### Added
9+
- Support for ap-east-1 and me-south-1 regions: [#192](https://github.com/awslabs/serverless-image-handler/issues/192), [#228](https://github.com/awslabs/serverless-image-handler/issues/228), [#232](https://github.com/awslabs/serverless-image-handler/issues/232)
10+
- Unit tests for custom-resource: `100%` coverage
11+
- Cloudfront cache policy and origin request policy: [#229](https://github.com/awslabs/serverless-image-handler/issues/229)
12+
- Circular cropping feature: [#214](https://github.com/awslabs/serverless-image-handler/issues/214), [#216](https://github.com/awslabs/serverless-image-handler/issues/216)
13+
- Unit tests for image-handler: `100%` coverage
14+
- Support for files without extension on thumbor requests: [#169](https://github.com/awslabs/serverless-image-handler/issues/169), [#188](https://github.com/awslabs/serverless-image-handler/issues/188)
15+
- Inappropriate content detection feature: [#243](https://github.com/awslabs/serverless-image-handler/issues/243)
16+
- Unit tests for image-request: `100%` coverage
17+
18+
### Fixed
19+
- Graceful failure when no faces are detected using smartCrop and fail on resizing before smartCrop: [#132](https://github.com/awslabs/serverless-image-handler/issues/132), [#133](https://github.com/awslabs/serverless-image-handler/issues/133)
20+
- Broken SVG returned if no edits specified and Auto-WebP enabled: [#247](https://github.com/awslabs/serverless-image-handler/issues/247)
21+
- Removed "--recursive" from README.md: [#255](https://github.com/awslabs/serverless-image-handler/pull/255)
22+
- fixed issue with failure on resize if width or height is float: [#254](https://github.com/awslabs/serverless-image-handler/issues/254)
23+
24+
### Changed
25+
- Constructs test template for constructs unit test: `100%` coverage
26+
727
## [5.1.0] - 2020-11-19
828
### ⚠ BREAKING CHANGES
929
- **Image URL Signature**: When image URL signature is enabled, all URLs including existing URLs should have `signature` query parameter.

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,8 @@ chmod +x ./build-s3-dist.sh
6464

6565
Deploy the distributable to the Amazon S3 bucket in your account:
6666
```bash
67-
aws s3 sync ./regional-s3-assets/ s3://$DIST_OUTPUT_BUCKET-$REGION/$SOLUTION_NAME/$VERSION/ --recursive --acl bucket-owner-full-control
68-
aws s3 sync ./global-s3-assets/ s3://$DIST_OUTPUT_BUCKET-$REGION/$SOLUTION_NAME/$VERSION/ --recursive --acl bucket-owner-full-control
67+
aws s3 sync ./regional-s3-assets/ s3://$DIST_OUTPUT_BUCKET-$REGION/$SOLUTION_NAME/$VERSION/ --acl bucket-owner-full-control
68+
aws s3 sync ./global-s3-assets/ s3://$DIST_OUTPUT_BUCKET-$REGION/$SOLUTION_NAME/$VERSION/ --acl bucket-owner-full-control
6969
```
7070

7171
### 6. Launch the CloudFormation template.
@@ -84,6 +84,7 @@ aws s3 sync ./global-s3-assets/ s3://$DIST_OUTPUT_BUCKET-$REGION/$SOLUTION_NAME/
8484
- [@pch](https://github.com/pch) for [#227](https://github.com/awslabs/serverless-image-handler/pull/227)
8585
- [@atrope](https://github.com/atrope) for [#201](https://github.com/awslabs/serverless-image-handler/pull/201)
8686
- [@bretto36](https://github.com/bretto36) for [#182](https://github.com/awslabs/serverless-image-handler/pull/182)
87+
- [@makoncline](https://github.com/makoncline) for [#255](https://github.com/awslabs/serverless-image-handler/pull/255)
8788

8889
***
8990
## License

architecture.png

-39.1 KB
Loading

source/constructs/lib/serverless-image-handler.ts

Lines changed: 131 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,21 @@ export class ServerlessImageHandler extends Construct {
8181
});
8282
enableDefaultFallbackImageCondition.overrideLogicalId('EnableDefaultFallbackImageCondition');
8383

84+
const isOptInRegion = new cdk.CfnCondition(this, 'IsOptInRegion', {
85+
expression: cdk.Fn.conditionOr(
86+
cdk.Fn.conditionEquals("af-south-1", cdk.Aws.REGION),
87+
cdk.Fn.conditionEquals("ap-east-1", cdk.Aws.REGION),
88+
cdk.Fn.conditionEquals("eu-south-1" , cdk.Aws.REGION),
89+
cdk.Fn.conditionEquals("me-south-1" , cdk.Aws.REGION)
90+
)
91+
});
92+
isOptInRegion.overrideLogicalId('IsOptInRegion');
93+
94+
const isNotOptInRegion = new cdk.CfnCondition(this, 'IsNotOptInRegion', {
95+
expression: cdk.Fn.conditionNot(isOptInRegion)
96+
});
97+
isNotOptInRegion.overrideLogicalId('IsNotOptInRegion')
98+
8499
// ImageHandlerFunctionRole
85100
const imageHandlerFunctionRole = new cdkIam.Role(this, 'ImageHandlerFunctionRole', {
86101
assumedBy: new cdkIam.ServicePrincipal('lambda.amazonaws.com'),
@@ -122,7 +137,8 @@ export class ServerlessImageHandler extends Construct {
122137
}),
123138
new cdkIam.PolicyStatement({
124139
actions: [
125-
'rekognition:DetectFaces'
140+
'rekognition:DetectFaces',
141+
'rekognition:DetectModerationLabels'
126142
],
127143
resources: [
128144
'*'
@@ -182,6 +198,12 @@ export class ServerlessImageHandler extends Construct {
182198
});
183199
const cfnLambdaFunctionLogs = lambdaFunctionLogs.node.defaultChild as cdkLogs.CfnLogGroup;
184200
cfnLambdaFunctionLogs.retentionInDays = props.logRetentionPeriodParameter.valueAsNumber;
201+
this.addCfnNagSuppressRules(cfnLambdaFunctionLogs, [
202+
{
203+
"id": "W84",
204+
"reason": "Used to store store function info"
205+
}
206+
]);
185207
cfnLambdaFunctionLogs.overrideLogicalId('ImageHandlerLogGroup');
186208

187209
// CloudFrontToApiGatewayToLambda pattern
@@ -193,6 +215,16 @@ export class ServerlessImageHandler extends Construct {
193215

194216
// ApiLogs
195217
const cfnApiGatewayLogGroup = apiGatewayLogGroup.node.defaultChild as cdkLogs.CfnLogGroup;
218+
this.addCfnNagSuppressRules(cfnApiGatewayLogGroup, [
219+
{
220+
"id": "W84",
221+
"reason": "Used to store store api log info, not using kms"
222+
},
223+
{
224+
"id": "W86",
225+
"reason": "Log retention specified in CloudFromation parameters."
226+
}
227+
]);
196228
cfnApiGatewayLogGroup.overrideLogicalId('ApiLogs');
197229

198230
// ImageHandlerApi
@@ -242,6 +274,7 @@ export class ServerlessImageHandler extends Construct {
242274
const cloudFrontToApiGateway = cloudFrontApiGatewayLambda.node.findChild('CloudFrontToApiGateway');
243275
const accessLogBucket = cloudFrontToApiGateway.node.findChild('CloudfrontLoggingBucket') as cdkS3.Bucket;
244276
const cfnAccessLogBucket = accessLogBucket.node.defaultChild as cdkS3.CfnBucket;
277+
cfnAccessLogBucket.cfnOptions.condition = isNotOptInRegion;
245278
this.addCfnNagSuppressRules(cfnAccessLogBucket, [
246279
{
247280
"id": "W35",
@@ -252,8 +285,76 @@ export class ServerlessImageHandler extends Construct {
252285

253286
// LogsBucketPolicy
254287
const accessLogBucketPolicy = accessLogBucket.node.findChild('Policy') as cdkS3.BucketPolicy;
288+
const cfnAccessLogBucketPolicy = accessLogBucketPolicy.node.defaultChild as cdkS3.CfnBucketPolicy;
289+
(accessLogBucketPolicy.node.defaultChild as cdkS3.CfnBucketPolicy).cfnOptions.condition = isNotOptInRegion;
255290
(accessLogBucketPolicy.node.defaultChild as cdkS3.CfnBucketPolicy).overrideLogicalId('LogsBucketPolicy');
256291

292+
//OptInRegionLogBucket
293+
const optInRegionAccessLogBucket = cdkS3.Bucket.fromBucketAttributes(this, 'CloudFrontLoggingBucket', {
294+
bucketName:
295+
cdk.Fn.getAtt(
296+
cdk.Lazy.stringValue({
297+
produce(context) {
298+
return cfLoggingBucket.logicalId}
299+
}),
300+
'bucketName').toString(),
301+
region: 'us-east-1'
302+
});
303+
304+
//OptInRegionLogBucketPolicy
305+
const optInRegionPolicyStatement = cfnAccessLogBucketPolicy.policyDocument.toJSON().Statement[0];
306+
optInRegionPolicyStatement.Resource = "";
307+
308+
//Choose Log Bucket
309+
const cloudFrontLogsBucket = cdk.Fn.conditionIf(isOptInRegion.logicalId, optInRegionAccessLogBucket.bucketRegionalDomainName, accessLogBucket.bucketRegionalDomainName).toString();
310+
311+
312+
//ImagehandlerCachePolicy
313+
const cfnCachePolicy = new cdkCloudFront.CfnCachePolicy(
314+
this,
315+
'CachePolicy',
316+
{
317+
cachePolicyConfig: {
318+
name: `${cdk.Aws.STACK_NAME}-${cdk.Aws.REGION}-ImageHandlerCachePolicy`,
319+
defaultTtl: 86400,
320+
minTtl: 1,
321+
maxTtl: 31536000,
322+
parametersInCacheKeyAndForwardedToOrigin: {
323+
cookiesConfig: {cookieBehavior: "none"},
324+
enableAcceptEncodingGzip: true,
325+
headersConfig: {
326+
headerBehavior: "whitelist",
327+
headers:['origin', 'accept']
328+
},
329+
queryStringsConfig: {
330+
queryStringBehavior: "whitelist",
331+
queryStrings: ["signature"]
332+
},
333+
}
334+
}
335+
});
336+
cfnCachePolicy.overrideLogicalId("ImageHandlerCachePolicy");
337+
338+
//ImageHandlerOriginRequestPolicy
339+
const cfnOriginRequestPolicy = new cdkCloudFront.CfnOriginRequestPolicy(
340+
this,
341+
"OriginRequestPolicy",
342+
{
343+
originRequestPolicyConfig: {
344+
cookiesConfig: {cookieBehavior: "none"},
345+
headersConfig: {
346+
headerBehavior: "whitelist",
347+
headers: ['origin', 'accept']
348+
},
349+
name: `${cdk.Aws.STACK_NAME}-${cdk.Aws.REGION}-ImageHandlerOriginRequestPolicy`,
350+
queryStringsConfig: {
351+
queryStringBehavior: "whitelist",
352+
queryStrings: ["signature"]
353+
},
354+
}
355+
});
356+
cfnOriginRequestPolicy.overrideLogicalId("ImageHandlerOriginRequestPolicy");
357+
257358
// ImageHandlerDistribution
258359
const cfnCloudFrontDistribution = cloudFrontWebDistribution.node.defaultChild as cdkCloudFront.CfnDistribution;
259360
cfnCloudFrontDistribution.distributionConfig = {
@@ -273,13 +374,10 @@ export class ServerlessImageHandler extends Construct {
273374
defaultCacheBehavior: {
274375
allowedMethods: [ 'GET', 'HEAD' ],
275376
targetOriginId: apiGateway.restApiId,
276-
forwardedValues: {
277-
queryString: true,
278-
queryStringCacheKeys: [ 'signature' ],
279-
headers: [ 'Origin', 'Accept' ],
280-
cookies: { forward: 'none' }
281-
},
282-
viewerProtocolPolicy: 'https-only'
377+
viewerProtocolPolicy: 'https-only',
378+
cachePolicyId: cfnCachePolicy.ref,
379+
originRequestPolicyId: cfnOriginRequestPolicy.ref
380+
283381
},
284382
customErrorResponses: [
285383
{ errorCode: 500, errorCachingMinTtl: 10 },
@@ -291,7 +389,7 @@ export class ServerlessImageHandler extends Construct {
291389
priceClass: 'PriceClass_All',
292390
logging: {
293391
includeCookies: false,
294-
bucket: accessLogBucket.bucketRegionalDomainName,
392+
bucket: cloudFrontLogsBucket,
295393
prefix: 'image-handler-cf-logs/'
296394
}
297395
};
@@ -378,7 +476,7 @@ export class ServerlessImageHandler extends Construct {
378476
httpVersion: 'http2',
379477
logging: {
380478
includeCookies: false,
381-
bucket: accessLogBucket.bucketRegionalDomainName,
479+
bucket: cloudFrontLogsBucket,
382480
prefix: 'demo-cf-logs/'
383481
}
384482
};
@@ -416,6 +514,10 @@ export class ServerlessImageHandler extends Construct {
416514
}),
417515
new cdkIam.PolicyStatement({
418516
actions: [
517+
's3:putBucketAcl',
518+
's3:putEncryptionConfiguration',
519+
's3:putBucketPolicy',
520+
's3:CreateBucket',
419521
's3:GetObject',
420522
's3:PutObject',
421523
's3:ListBucket'
@@ -461,6 +563,12 @@ export class ServerlessImageHandler extends Construct {
461563
});
462564
const cfnCustomResourceLogGroup = customResourceLogGroup.node.defaultChild as cdkLogs.CfnLogGroup;
463565
cfnCustomResourceLogGroup.retentionInDays = props.logRetentionPeriodParameter.valueAsNumber;
566+
this.addCfnNagSuppressRules(cfnCustomResourceLogGroup, [
567+
{
568+
"id": "W84",
569+
"reason": "Used to store store function info, no kms used"
570+
}
571+
]);
464572
cfnCustomResourceLogGroup.overrideLogicalId('CustomResourceLogGroup');
465573

466574
// CustomResourceCopyS3
@@ -565,6 +673,19 @@ export class ServerlessImageHandler extends Construct {
565673
condition: enableDefaultFallbackImageCondition,
566674
dependencies: [ cfnCustomResourceRole, cfnCustomResourcePolicy ]
567675
});
676+
677+
const bucketSuffix = cdk.Aws.STACK_NAME + cdk.Aws.REGION + cdk.Aws.ACCOUNT_ID;
678+
const cfLoggingBucket = this.createCustomResource('CustomCFLoggingBucket', customResourceFunction, {
679+
properties: [
680+
{ path: 'customAction', value: 'createCFLoggingBucket' },
681+
{ path: 'stackName', value: cdk.Aws.STACK_NAME },
682+
{ path: 'bucketSuffix', value: bucketSuffix },
683+
{ path: 'policy', value: optInRegionPolicyStatement }
684+
],
685+
condition: isOptInRegion,
686+
dependencies: [ cfnCustomResourceRole, cfnCustomResourcePolicy ]
687+
688+
});
568689
} catch (error) {
569690
console.error(error);
570691
}

source/constructs/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "constructs",
33
"description": "Serverless Image Handler Constructs",
4-
"version": "5.1.0",
4+
"version": "5.2.0",
55
"license": "Apache-2.0",
66
"bin": {
77
"constructs": "bin/constructs.js"

0 commit comments

Comments
 (0)