diff --git a/infrastructure/lib/auth.ts b/infrastructure/lib/auth.ts index d2a2d44..10b7737 100644 --- a/infrastructure/lib/auth.ts +++ b/infrastructure/lib/auth.ts @@ -19,9 +19,13 @@ export class CognitoAuthConstruct extends Construct { super(scope, id); const userPool = new CfnUserPool(this, "UserPool", { userPoolName: "S3MediaPlayerUserPool-" + id, + deletionProtection: "INACTIVE", + userPoolAddOns: { + advancedSecurityMode: "ENFORCED" + }, adminCreateUserConfig: { allowAdminCreateUserOnly: true, - unusedAccountValidityDays: 30, + unusedAccountValidityDays: 7, inviteMessageTemplate: { emailSubject: `S3 Media Player ${props.domain} - Invitation`, emailMessage: `Hi {username}! @@ -42,9 +46,10 @@ If you have any questions, please contact ${props.contactEmailAddress}` }, emailVerificationSubject: `S3 Media Player ${props.domain} - Email verification`, emailVerificationMessage: `Hi! -To verify your email address at ${props.domain} please enter this code: {####}. -If you have any questions, please contact ${props.contactEmailAddress}`, + To verify your email address at ${props.domain} please enter this code: {####}. + If you have any questions, please contact ${props.contactEmailAddress}`, mfaConfiguration: "OFF", + enabledMfas: [], policies: { passwordPolicy: { minimumLength: 6, @@ -58,8 +63,21 @@ If you have any questions, please contact ${props.contactEmailAddress}`, const webClient = new CfnUserPoolClient(this, "Client", { generateSecret: false, + userPoolId: userPool.ref, + allowedOAuthFlowsUserPoolClient: false, refreshTokenValidity: 30, // days - userPoolId: userPool.ref + accessTokenValidity: 2, // hours + idTokenValidity: 2, // hours + tokenValidityUnits: { + refreshToken: "days", + accessToken: "hours", + idToken: "hours" + }, + preventUserExistenceErrors: "ENABLED", + supportedIdentityProviders: ["COGNITO"], + authSessionValidity: 15, // minutes + readAttributes: ["preferred_username"], + writeAttributes: [] }); const identityPool = new CfnIdentityPool(this, "IdentityPool", { @@ -72,7 +90,7 @@ If you have any questions, please contact ${props.contactEmailAddress}`, }); this.userRole = new Role(this, "UserRole", { - maxSessionDuration: Duration.hours(1), + maxSessionDuration: Duration.hours(3), assumedBy: new FederatedPrincipal("cognito-identity.amazonaws.com", { "StringEquals": { "cognito-identity.amazonaws.com:aud": identityPool.ref }, "ForAnyValue:StringLike": { "cognito-identity.amazonaws.com:amr": "authenticated" } @@ -83,7 +101,8 @@ If you have any questions, please contact ${props.contactEmailAddress}`, groupName: "Users", description: "Group for users", roleArn: this.userRole.roleArn, - userPoolId: userPool.ref + userPoolId: userPool.ref, + precedence: 10 }); new CfnIdentityPoolRoleAttachment(this, "RoleAttachment", { diff --git a/infrastructure/lib/static-content.ts b/infrastructure/lib/static-content.ts index ef4fa56..fc90f9b 100644 --- a/infrastructure/lib/static-content.ts +++ b/infrastructure/lib/static-content.ts @@ -1,6 +1,6 @@ import { CfnOutput, RemovalPolicy } from 'aws-cdk-lib'; import { Certificate } from 'aws-cdk-lib/aws-certificatemanager'; -import { CloudFrontWebDistribution, OriginAccessIdentity, PriceClass, SecurityPolicyProtocol, SSLMethod, ViewerCertificate, ViewerProtocolPolicy } from 'aws-cdk-lib/aws-cloudfront'; +import { CloudFrontWebDistribution, HttpVersion, OriginAccessIdentity, PriceClass, SecurityPolicyProtocol, SSLMethod, ViewerCertificate, ViewerProtocolPolicy } from 'aws-cdk-lib/aws-cloudfront'; import { Effect, PolicyStatement } from 'aws-cdk-lib/aws-iam'; import { CfnRecordSetGroup } from 'aws-cdk-lib/aws-route53'; import { BlockPublicAccess, Bucket, BucketPolicy } from 'aws-cdk-lib/aws-s3'; @@ -20,7 +20,8 @@ export class StaticContentConstruct extends Construct { const staticContentBucket = new Bucket(this, "Bucket", { removalPolicy: RemovalPolicy.DESTROY, - blockPublicAccess: BlockPublicAccess.BLOCK_ALL + blockPublicAccess: BlockPublicAccess.BLOCK_ALL, + websiteIndexDocument: "index.html" }); const certificate = Certificate.fromCertificateArn(this, "Certificate", props.sslCertificateArn); @@ -30,6 +31,7 @@ export class StaticContentConstruct extends Construct { }); const cloudfrontDistribution = new CloudFrontWebDistribution(this, "CloudFrontDistribution", { + enabled: true, comment: `${props.domain}`, originConfigs: [{ behaviors: [{ isDefaultBehavior: true }], @@ -41,12 +43,13 @@ export class StaticContentConstruct extends Construct { defaultRootObject: "index.html", enableIpV6: true, viewerCertificate: ViewerCertificate.fromAcmCertificate(certificate, { - securityPolicy: SecurityPolicyProtocol.TLS_V1_2_2018, + securityPolicy: SecurityPolicyProtocol.TLS_V1_2_2021, sslMethod: SSLMethod.SNI, aliases: [props.domain] }), priceClass: PriceClass.PRICE_CLASS_100, - viewerProtocolPolicy: ViewerProtocolPolicy.REDIRECT_TO_HTTPS + viewerProtocolPolicy: ViewerProtocolPolicy.REDIRECT_TO_HTTPS, + httpVersion: HttpVersion.HTTP2_AND_3, }); const bucketPolicy = new BucketPolicy(this, "AllowReadAccessToCloudFront", { bucket: staticContentBucket }); diff --git a/infrastructure/package-lock.json b/infrastructure/package-lock.json index f01b232..4056d6d 100644 --- a/infrastructure/package-lock.json +++ b/infrastructure/package-lock.json @@ -8,8 +8,8 @@ "name": "infrastructure", "version": "0.1.0", "dependencies": { - "aws-cdk": "^2.132.0", - "aws-cdk-lib": "^2.132.0", + "aws-cdk": "^2.135.0", + "aws-cdk-lib": "^2.135.0", "constructs": "^10.3.0", "source-map-support": "^0.5.21" }, @@ -19,11 +19,11 @@ "devDependencies": { "@aws-cdk/assert": "^2.68.0", "@types/jest": "^29.5.12", - "@types/node": "20.11.25", + "@types/node": "20.12.4", "jest": "^29.7.0", "ts-jest": "^29.1.2", "ts-node": "^10.9.2", - "typescript": "~5.4.2" + "typescript": "~5.4.4" } }, "node_modules/@ampproject/remapping": { @@ -1281,9 +1281,9 @@ } }, "node_modules/@types/node": { - "version": "20.11.25", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.25.tgz", - "integrity": "sha512-TBHyJxk2b7HceLVGFcpAUjsa5zIdsPWlR6XHfyGzd0SFu+/NFgQgMAl96MSDZgQDvJAvV6BKsFOrt6zIL09JDw==", + "version": "20.12.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.4.tgz", + "integrity": "sha512-E+Fa9z3wSQpzgYQdYmme5X3OTuejnnTx88A6p6vkkJosR3KBz+HpE3kqNm98VE6cfLFcISx7zW7MsJkH6KwbTw==", "dev": true, "dependencies": { "undici-types": "~5.26.4" @@ -1335,7 +1335,6 @@ "version": "8.12.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "dev": true, "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -1366,7 +1365,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, "engines": { "node": ">=8" } @@ -1375,7 +1373,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -1418,7 +1415,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "dev": true, "engines": { "node": ">=8" } @@ -1433,9 +1429,9 @@ } }, "node_modules/aws-cdk": { - "version": "2.132.0", - "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.132.0.tgz", - "integrity": "sha512-C2j9iQqpl21YGuip02tIAAkgkDZNDDWeEoWfPcdXCJlQ9DVpYTJG24QxtY0rWflJ7Xkn+iAozdjlCrXSxYeAfA==", + "version": "2.135.0", + "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.135.0.tgz", + "integrity": "sha512-id/kBxDvXQhcPYhkP/3fwhaKN0uD3raz1Z4RZcO9jJ4UoQV2RElQl+dYdmIrwNSoNVhtZeV1O4IdEtBHUhdShQ==", "bin": { "cdk": "bin/cdk" }, @@ -1447,9 +1443,9 @@ } }, "node_modules/aws-cdk-lib": { - "version": "2.132.0", - "resolved": "https://registry.npmjs.org/aws-cdk-lib/-/aws-cdk-lib-2.132.0.tgz", - "integrity": "sha512-auztTTYy8j62MmRZNdM7Vd8eQ5eP3xLMhrrILhDZf3DiSDD0lyYL0hv98VD4XPkWGMQ8yOmo5nZ3s/zD7cnKlw==", + "version": "2.135.0", + "resolved": "https://registry.npmjs.org/aws-cdk-lib/-/aws-cdk-lib-2.135.0.tgz", + "integrity": "sha512-0RcmhPqJyMFgXqjESv+LilL7TfOQ7uZ4G125hp5/sSoaM7IFz/L3KDAUKVW/01rrebOQo0NZR9M7WIU3JJ7ezQ==", "bundleDependencies": [ "@balena/dockerignore", "case", @@ -1476,7 +1472,7 @@ "minimatch": "^3.1.2", "punycode": "^2.3.1", "semver": "^7.6.0", - "table": "^6.8.1", + "table": "^6.8.2", "yaml": "1.10.2" }, "engines": { @@ -1764,7 +1760,7 @@ } }, "node_modules/aws-cdk-lib/node_modules/table": { - "version": "6.8.1", + "version": "6.8.2", "inBundle": true, "license": "BSD-3-Clause", "dependencies": { @@ -2111,7 +2107,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, "dependencies": { "color-name": "~1.1.4" }, @@ -2122,8 +2117,7 @@ "node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "node_modules/concat-map": { "version": "0.0.1", @@ -2283,8 +2277,7 @@ "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, "node_modules/error-ex": { "version": "1.3.2", @@ -2377,8 +2370,7 @@ "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", @@ -2645,7 +2637,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, "engines": { "node": ">=8" } @@ -3390,8 +3381,7 @@ "node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" }, "node_modules/json5": { "version": "2.2.3", @@ -3462,8 +3452,7 @@ "node_modules/lodash.truncate": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", - "dev": true + "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==" }, "node_modules/lru-cache": { "version": "5.1.1", @@ -3841,7 +3830,6 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", - "dev": true, "engines": { "node": ">=6" } @@ -3881,7 +3869,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -3988,7 +3975,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", - "dev": true, "dependencies": { "ansi-styles": "^4.0.0", "astral-regex": "^2.0.0", @@ -4053,7 +4039,6 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -4067,7 +4052,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, "dependencies": { "ansi-regex": "^5.0.1" }, @@ -4133,7 +4117,6 @@ "version": "6.8.1", "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz", "integrity": "sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==", - "dev": true, "dependencies": { "ajv": "^8.0.1", "lodash.truncate": "^4.4.2", @@ -4336,9 +4319,9 @@ } }, "node_modules/typescript": { - "version": "5.4.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.2.tgz", - "integrity": "sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==", + "version": "5.4.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.4.tgz", + "integrity": "sha512-dGE2Vv8cpVvw28v8HCPqyb08EzbBURxDpuhJvTrusShUfGnhHBafDsLdS1EhhxyL6BJQE+2cT3dDPAv+MQ6oLw==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -4397,7 +4380,6 @@ "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, "dependencies": { "punycode": "^2.1.0" } diff --git a/infrastructure/package.json b/infrastructure/package.json index 3a97ed4..ec44cef 100644 --- a/infrastructure/package.json +++ b/infrastructure/package.json @@ -13,15 +13,15 @@ "devDependencies": { "@aws-cdk/assert": "^2.68.0", "@types/jest": "^29.5.12", - "@types/node": "20.11.25", + "@types/node": "20.12.4", "jest": "^29.7.0", "ts-jest": "^29.1.2", "ts-node": "^10.9.2", - "typescript": "~5.4.2" + "typescript": "~5.4.4" }, "dependencies": { - "aws-cdk": "^2.132.0", - "aws-cdk-lib": "^2.132.0", + "aws-cdk": "^2.135.0", + "aws-cdk-lib": "^2.135.0", "constructs": "^10.3.0", "source-map-support": "^0.5.21" }