diff --git a/backend/package-lock.json b/backend/package-lock.json index 98e94ddd..6aed041b 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -53,6 +53,8 @@ "uuid": "^9.0.1", "wappalyzer": "^6.10.63", "wappalyzer-core": "^6.10.63", + "winston": "^3.11.0", + "winston-cloudwatch": "^6.2.0", "ws": "^8.13.0" }, "devDependencies": { @@ -81,6 +83,7 @@ "prettier": "^3.0.0", "sentencer": "^0.2.1", "serverless": "^3.30", + "serverless-better-credentials": "^1.2.0", "serverless-domain-manager": "^7.0", "serverless-dotenv-plugin": "^6.0.0", "serverless-webpack": "^5.11.0", @@ -3656,6 +3659,14 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, + "node_modules/@colors/colors": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz", + "integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==", + "engines": { + "node": ">=0.1.90" + } + }, "node_modules/@cspotcode/source-map-support": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", @@ -3678,6 +3689,16 @@ "@jridgewell/sourcemap-codec": "^1.4.10" } }, + "node_modules/@dabh/diagnostics": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz", + "integrity": "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==", + "dependencies": { + "colorspace": "1.1.x", + "enabled": "2.0.x", + "kuler": "^2.0.0" + } + }, "node_modules/@discoveryjs/json-ext": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", @@ -6585,6 +6606,11 @@ "@types/superagent": "*" } }, + "node_modules/@types/triple-beam": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.5.tgz", + "integrity": "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==" + }, "node_modules/@types/uuid": { "version": "9.0.7", "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.7.tgz", @@ -8551,6 +8577,15 @@ "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", "dev": true }, + "node_modules/color": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", + "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", + "dependencies": { + "color-convert": "^1.9.3", + "color-string": "^1.6.0" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -8567,12 +8602,43 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "node_modules/color/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, "node_modules/colorette": { "version": "2.0.20", "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", "dev": true }, + "node_modules/colorspace": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz", + "integrity": "sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==", + "dependencies": { + "color": "^3.1.3", + "text-hex": "1.0.x" + } + }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -9460,6 +9526,11 @@ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, + "node_modules/enabled": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz", + "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==" + }, "node_modules/encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", @@ -10325,8 +10396,7 @@ "node_modules/fast-safe-stringify": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", - "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", - "dev": true + "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==" }, "node_modules/fast-xml-parser": { "version": "4.2.5", @@ -10384,6 +10454,11 @@ "pend": "~1.2.0" } }, + "node_modules/fecha": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz", + "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==" + }, "node_modules/figures": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", @@ -10580,6 +10655,11 @@ "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", "dev": true }, + "node_modules/fn.name": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", + "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" + }, "node_modules/follow-redirects": { "version": "1.15.4", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz", @@ -11607,7 +11687,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true, "engines": { "node": ">=8" }, @@ -14718,6 +14797,11 @@ "node": ">=6" } }, + "node_modules/kuler": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", + "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==" + }, "node_modules/lazystream": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", @@ -14835,6 +14919,11 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, + "node_modules/lodash.assign": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", + "integrity": "sha512-hFuH8TY+Yji7Eja3mGiuAxBqLagejScbG8GbG0j6o9vzn0YL14My+ktnqtZgFTosKymC9/44wP6s7xyuLfnClw==" + }, "node_modules/lodash.clonedeep": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", @@ -14852,6 +14941,11 @@ "integrity": "sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA==", "dev": true }, + "node_modules/lodash.find": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.find/-/lodash.find-4.6.0.tgz", + "integrity": "sha512-yaRZoAV3Xq28F1iafWN1+a0rflOej93l1DQUejs3SZ41h2O9UJBoS9aueGjPDgAl4B6tPC0NuuchLKaDQQ3Isg==" + }, "node_modules/lodash.flatten": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", @@ -14874,6 +14968,16 @@ "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" }, + "node_modules/lodash.isempty": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.isempty/-/lodash.isempty-4.4.0.tgz", + "integrity": "sha512-oKMuF3xEeqDltrGMfDxAPGIVMSSRv8tbRSODbrs4KGsRRLEhrW8N8Rd4DRgB2+621hY8A8XwwrTVhXWpxFvMzg==" + }, + "node_modules/lodash.iserror": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lodash.iserror/-/lodash.iserror-3.1.1.tgz", + "integrity": "sha512-eT/VeNns9hS7vAj1NKW/rRX6b+C3UX3/IAAqEE7aC4Oo2C0iD82NaP5IS4bSlQsammTii4qBJ8G1zd1LTL8hCw==" + }, "node_modules/lodash.isfinite": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/lodash.isfinite/-/lodash.isfinite-3.3.2.tgz", @@ -15002,6 +15106,22 @@ "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==", "dev": true }, + "node_modules/logform": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/logform/-/logform-2.6.0.tgz", + "integrity": "sha512-1ulHeNPp6k/LD8H91o7VYFBng5i1BDE7HoKxVbZiGFidS1Rj65qcywLxX+pVfAPoQJEjRdvKcusKwOupHCVOVQ==", + "dependencies": { + "@colors/colors": "1.6.0", + "@types/triple-beam": "^1.3.2", + "fecha": "^4.2.0", + "ms": "^2.1.1", + "safe-stable-stringify": "^2.3.1", + "triple-beam": "^1.3.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, "node_modules/lowercase-keys": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", @@ -15613,6 +15733,14 @@ "wrappy": "1" } }, + "node_modules/one-time": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz", + "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==", + "dependencies": { + "fn.name": "1.x.x" + } + }, "node_modules/onetime": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", @@ -17036,7 +17164,6 @@ "version": "2.4.3", "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz", "integrity": "sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==", - "dev": true, "engines": { "node": ">=10" } @@ -17307,6 +17434,23 @@ "node": ">=12.0" } }, + "node_modules/serverless-better-credentials": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/serverless-better-credentials/-/serverless-better-credentials-1.3.0.tgz", + "integrity": "sha512-izk8oVmAgnowXm/p7SKul2LskgT8gK6cLXRb4otVUn6zHRH6slylfvSTMOpEbtarKFX9r6fmpFhKwzhIfajt3Q==", + "dev": true, + "dependencies": { + "open": "^8.4.2" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "@serverless/utils": "^6.0.2", + "aws-sdk": "^2.567.0", + "serverless": "^2 || ^3" + } + }, "node_modules/serverless-domain-manager": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/serverless-domain-manager/-/serverless-domain-manager-7.1.2.tgz", @@ -17634,6 +17778,19 @@ "url": "https://github.com/steveukx/git-js?sponsor=1" } }, + "node_modules/simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "node_modules/simple-swizzle/node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + }, "node_modules/sisteransi": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", @@ -17751,6 +17908,14 @@ "resolved": "https://registry.npmjs.org/ssl-checker/-/ssl-checker-2.0.8.tgz", "integrity": "sha512-pIDGxablZowKR/elbm72Wk7T3lEdrcAKT4ltPsdQrpm7N6EIIvuFQpIcMNG+A/wmiymcRwFDzTd83bW6Yy5LKQ==" }, + "node_modules/stack-trace": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", + "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==", + "engines": { + "node": "*" + } + }, "node_modules/stack-utils": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", @@ -18224,6 +18389,11 @@ "node": ">=8" } }, + "node_modules/text-hex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", + "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==" + }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -18443,6 +18613,14 @@ "node": ">=0.8.0" } }, + "node_modules/triple-beam": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.4.1.tgz", + "integrity": "sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==", + "engines": { + "node": ">= 14.0.0" + } + }, "node_modules/ts-jest": { "version": "27.1.5", "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-27.1.5.tgz", @@ -19543,6 +19721,68 @@ "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", "dev": true }, + "node_modules/winston": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/winston/-/winston-3.12.0.tgz", + "integrity": "sha512-OwbxKaOlESDi01mC9rkM0dQqQt2I8DAUMRLZ/HpbwvDXm85IryEHgoogy5fziQy38PntgZsLlhAYHz//UPHZ5w==", + "dependencies": { + "@colors/colors": "^1.6.0", + "@dabh/diagnostics": "^2.0.2", + "async": "^3.2.3", + "is-stream": "^2.0.0", + "logform": "^2.4.0", + "one-time": "^1.0.0", + "readable-stream": "^3.4.0", + "safe-stable-stringify": "^2.3.1", + "stack-trace": "0.0.x", + "triple-beam": "^1.3.0", + "winston-transport": "^4.7.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/winston-cloudwatch": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/winston-cloudwatch/-/winston-cloudwatch-6.2.0.tgz", + "integrity": "sha512-FcJ3x+rcAKGKr4Y9tbPjXkt39I6aiAMD//ElDYcWGMFp4GjMeXP6JYrfl1yNqvH65fzehqLD71MQMlt/5/9ZIQ==", + "dependencies": { + "async": "^3.1.0", + "chalk": "^4.0.0", + "fast-safe-stringify": "^2.0.7", + "lodash.assign": "^4.2.0", + "lodash.find": "^4.6.0", + "lodash.isempty": "^4.4.0", + "lodash.iserror": "^3.1.1" + }, + "peerDependencies": { + "@aws-sdk/client-cloudwatch-logs": "^3.0.0", + "winston": "^3.0.0" + } + }, + "node_modules/winston-cloudwatch/node_modules/async": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", + "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==" + }, + "node_modules/winston-transport": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.7.0.tgz", + "integrity": "sha512-ajBj65K5I7denzer2IYW6+2bNIVqLGDHqDw3Ow8Ohh+vdW+rv4MZ6eiDvHoKhfJFZ2auyN8byXieDDJ96ViONg==", + "dependencies": { + "logform": "^2.3.2", + "readable-stream": "^3.6.0", + "triple-beam": "^1.3.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/winston/node_modules/async": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", + "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==" + }, "node_modules/wordnet-db": { "version": "3.1.14", "resolved": "https://registry.npmjs.org/wordnet-db/-/wordnet-db-3.1.14.tgz", diff --git a/backend/package.json b/backend/package.json index 915067f1..fb1e3ee1 100644 --- a/backend/package.json +++ b/backend/package.json @@ -51,6 +51,8 @@ "uuid": "^9.0.1", "wappalyzer": "^6.10.63", "wappalyzer-core": "^6.10.63", + "winston": "^3.11.0", + "winston-cloudwatch": "^6.2.0", "ws": "^8.13.0" }, "devDependencies": { @@ -79,6 +81,7 @@ "prettier": "^3.0.0", "sentencer": "^0.2.1", "serverless": "^3.30", + "serverless-better-credentials": "^1.2.0", "serverless-domain-manager": "^7.0", "serverless-dotenv-plugin": "^6.0.0", "serverless-webpack": "^5.11.0", @@ -116,4 +119,4 @@ }, "author": "", "license": "ISC" -} +} \ No newline at end of file diff --git a/backend/src/api/app.ts b/backend/src/api/app.ts index 61025450..c8395bde 100644 --- a/backend/src/api/app.ts +++ b/backend/src/api/app.ts @@ -110,12 +110,12 @@ app.use( defaultSrc: [ "'self'", 'https://cognito-idp.us-gov-west-1.amazonaws.com', - 'https://api.staging.crossfeed.cyber.dhs.gov' + 'https://api.crossfeed.cyber.dhs.gov' ], objectSrc: ["'none'"], scriptSrc: [ "'self'", - 'https://api.staging.crossfeed.cyber.dhs.gov' + 'https://api.crossfeed.cyber.dhs.gov' // Add any other allowed script sources here ], frameAncestors: ["'none'"] diff --git a/backend/src/api/auth.ts b/backend/src/api/auth.ts index 380e67d5..eedcffc1 100644 --- a/backend/src/api/auth.ts +++ b/backend/src/api/auth.ts @@ -122,13 +122,14 @@ export const callback = async (event, context) => { } catch (e) { return { statusCode: 500, - body: e + body: '' }; } + if (!userInfo.email_verified) { return { statusCode: 403, - body: 'Email is not verified' + body: '' }; } @@ -261,6 +262,15 @@ export const isGlobalViewAdmin = (event: APIGatewayProxyEvent) => { : false; }; +/** Check if a user has regionalAdmin view permissions */ +export const isRegionalAdmin = (event: APIGatewayProxyEvent) => { + return event.requestContext.authorizer && + (event.requestContext.authorizer.userType === UserType.REGIONAL_ADMIN || + event.requestContext.authorizer.userType === UserType.GLOBAL_ADMIN) + ? true + : false; +}; + /** Checks if the current user is allowed to access (modify) a user with id userId */ export const canAccessUser = (event: APIGatewayProxyEvent, userId?: string) => { return userId && (userId === getUserId(event) || isGlobalWriteAdmin(event)); diff --git a/backend/src/api/helpers.ts b/backend/src/api/helpers.ts index 540e08ef..6a4e3f95 100644 --- a/backend/src/api/helpers.ts +++ b/backend/src/api/helpers.ts @@ -7,9 +7,11 @@ import { import { ValidationOptions, validateOrReject } from 'class-validator'; import { ClassType } from 'class-transformer/ClassTransformer'; import { plainToClass } from 'class-transformer'; +import S3Client from '../tasks/s3-client'; import { SES } from 'aws-sdk'; import * as nodemailer from 'nodemailer'; import logger from '../tools/lambda-logger'; +import * as handlebars from 'handlebars'; const AWS = require('aws-sdk'); const httpProxy = require('https-proxy-agent'); @@ -75,12 +77,12 @@ export const wrapHandler: WrapHandler = export const NotFound: APIGatewayProxyResult = { statusCode: 404, - body: '' + body: 'Item not found. View logs for details.' }; export const Unauthorized: APIGatewayProxyResult = { statusCode: 403, - body: '' + body: 'Unauthorized access. View logs for details.' }; export const sendEmail = async ( @@ -121,3 +123,202 @@ export const sendEmail = async ( throw error; } }; + +export const sendRegistrationTextEmail = async (recipient: string) => { + process.env.HTTPS_PROXY = 'http://proxy.lz.us-cert.gov:8080'; + process.env.HTTP_PROXY = 'http://proxy.lz.us-cert.gov:8080'; + const proxyAgent = process.env.HTTPS_PROXY || process.env.HTTP_PROXY; + AWS.config.update({ + httpOptions: { + agent: proxyAgent ? httpProxy(proxyAgent) : undefined + } + }); + const transporter = nodemailer.createTransport({ + SES: new SES({ + region: 'us-gov-west-1', + endpoint: 'https://email.us-gov-west-1.amazonaws.com' + }) + }); + + const mailOptions = { + from: process.env.CROSSFEED_SUPPORT_EMAIL_SENDER!, + to: recipient, + subject: 'Crossfeed Registration Pending', + text: 'Your registration is pending approval.', + replyTo: process.env.CROSSFEED_SUPPORT_EMAIL_REPLYTO! + }; + + await transporter.sendMail(mailOptions, (error, data) => { + console.log(data); + if (error) { + console.log(error); + } + }); +}; + +export const sendRegistrationHtmlEmail = async (recipient: string) => { + process.env.HTTPS_PROXY = 'http://proxy.lz.us-cert.gov:8080'; + process.env.HTTP_PROXY = 'http://proxy.lz.us-cert.gov:8080'; + const proxyAgent = process.env.HTTPS_PROXY || process.env.HTTP_PROXY; + AWS.config.update({ + httpOptions: { + agent: proxyAgent ? httpProxy(proxyAgent) : undefined + } + }); + const transporter = nodemailer.createTransport({ + SES: new SES({ + region: 'us-gov-west-1', + endpoint: 'https://email.us-gov-west-1.amazonaws.com' + }) + }); + + const mailOptions = { + from: process.env.CROSSFEED_SUPPORT_EMAIL_SENDER!, + to: recipient, + subject: 'Crossfeed Registration Pending', + html: '

Your registration is pending approval.

', + replyTo: process.env.CROSSFEED_SUPPORT_EMAIL_REPLYTO! + }; + + await transporter.sendMail(mailOptions, (error, data) => { + console.log(data); + if (error) { + console.log(error); + } + }); +}; + +export const sendUserRegistrationEmail = async ( + recepient: string, + subject: string, + firstName: string, + lastName: string, + templateFileName: string +) => { + try { + const client = new S3Client(); + const htmlTemplate = await client.getEmailAsset(templateFileName); + const template = handlebars.compile(htmlTemplate); + const data = { + firstName: firstName, + lastName: lastName + }; + + const htmlToSend = template(data); + const mailOptions = { + from: process.env.CROSSFEED_SUPPORT_EMAIL_SENDER!, + to: recepient, + subject: subject, + html: htmlToSend, + replyTo: process.env.CROSSFEED_SUPPORT_EMAIL_REPLYTO! + }; + + process.env.HTTPS_PROXY = 'http://proxy.lz.us-cert.gov:8080'; + process.env.HTTP_PROXY = 'http://proxy.lz.us-cert.gov:8080'; + const proxyAgent = process.env.HTTPS_PROXY || process.env.HTTP_PROXY; + AWS.config.update({ + httpOptions: { + agent: proxyAgent ? httpProxy(proxyAgent) : undefined + } + }); + const transporter = nodemailer.createTransport({ + SES: new SES({ + region: 'us-gov-west-1', + endpoint: 'https://email.us-gov-west-1.amazonaws.com' + }) + }); + await transporter.sendMail(mailOptions); + } catch (errorMessage) { + console.log('Email error: ', errorMessage); + } +}; + +export const sendRegistrationDeniedEmail = async ( + recepient: string, + subject: string, + firstName: string, + lastName: string, + templateFileName: string +) => { + try { + const client = new S3Client(); + const htmlTemplate = await client.getEmailAsset(templateFileName); + const template = handlebars.compile(htmlTemplate); + const data = { + firstName: firstName, + lastName: lastName + }; + + const htmlToSend = template(data); + const mailOptions = { + from: process.env.CROSSFEED_SUPPORT_EMAIL_SENDER!, + to: recepient, + subject: subject, + html: htmlToSend, + replyTo: process.env.CROSSFEED_SUPPORT_EMAIL_REPLYTO! + }; + + process.env.HTTPS_PROXY = 'http://proxy.lz.us-cert.gov:8080'; + process.env.HTTP_PROXY = 'http://proxy.lz.us-cert.gov:8080'; + const proxyAgent = process.env.HTTPS_PROXY || process.env.HTTP_PROXY; + AWS.config.update({ + httpOptions: { + agent: proxyAgent ? httpProxy(proxyAgent) : undefined + } + }); + const transporter = nodemailer.createTransport({ + SES: new SES({ + region: 'us-gov-west-1', + endpoint: 'https://email.us-gov-west-1.amazonaws.com' + }) + }); + await transporter.sendMail(mailOptions); + } catch (errorMessage) { + console.log('Email error: ', errorMessage); + } +}; + +export const sendRegistrationApprovedEmail = async ( + recepient: string, + subject: string, + firstName: string, + lastName: string, + templateFileName: string +) => { + try { + const client = new S3Client(); + const htmlTemplate = await client.getEmailAsset(templateFileName); + const template = handlebars.compile(htmlTemplate); + const data = { + firstName: firstName, + lastName: lastName + }; + + const htmlToSend = template(data); + const mailOptions = { + from: process.env.CROSSFEED_SUPPORT_EMAIL_SENDER!, + to: recepient, + subject: subject, + html: htmlToSend, + replyTo: process.env.CROSSFEED_SUPPORT_EMAIL_REPLYTO! + }; + + process.env.HTTPS_PROXY = 'http://proxy.lz.us-cert.gov:8080'; + process.env.HTTP_PROXY = 'http://proxy.lz.us-cert.gov:8080'; + const proxyAgent = process.env.HTTPS_PROXY || process.env.HTTP_PROXY; + AWS.config.update({ + httpOptions: { + agent: proxyAgent ? httpProxy(proxyAgent) : undefined + } + }); + const transporter = nodemailer.createTransport({ + SES: new SES({ + region: 'us-gov-west-1', + endpoint: 'https://email.us-gov-west-1.amazonaws.com' + }) + }); + await transporter.sendMail(mailOptions); + } catch (errorMessage) { + console.log('Email error: ', errorMessage); + } +}; diff --git a/backend/src/api/users.ts b/backend/src/api/users.ts index a5df83cc..282ec64a 100644 --- a/backend/src/api/users.ts +++ b/backend/src/api/users.ts @@ -36,6 +36,7 @@ import { import { Type, plainToClass } from 'class-transformer'; import { IsNull } from 'typeorm'; import { create } from './organizations'; +import logger from '../tools/lambda-logger'; class UserSearch { @IsInt() diff --git a/backend/src/tasks/checkUserExpiration.ts b/backend/src/tasks/checkUserExpiration.ts index f17a9eaa..847a36c2 100644 --- a/backend/src/tasks/checkUserExpiration.ts +++ b/backend/src/tasks/checkUserExpiration.ts @@ -7,7 +7,6 @@ import { getRepository } from 'typeorm'; const cognito = new AWS.CognitoIdentityServiceProvider(); const userPoolId = process.env.REACT_APP_USER_POOL_ID!; -const ses = new AWS.SES({ region: 'us-east-1' }); // Assuming SES for email notifications export const handler: Handler = async (event) => { await connectToDatabase(true); diff --git a/backend/src/tasks/s3-client.ts b/backend/src/tasks/s3-client.ts index 1fda6f2d..3fd863a2 100644 --- a/backend/src/tasks/s3-client.ts +++ b/backend/src/tasks/s3-client.ts @@ -94,6 +94,27 @@ class S3Client { throw e; } } + + async getEmailAsset(fileName: string) { + try { + const params = { + Bucket: process.env.EMAIL_BUCKET_NAME!, + Key: fileName + }; + + const data = await this.s3 + .getObject(params, function (err, data) { + if (err) throw err; + }) + .promise(); + if (data && data.Body) { + return data.Body.toString('utf-8'); + } + } catch (e) { + console.error(e); + throw e; + } + } } export default S3Client; diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 0f7ca227..cd242b68 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -54,7 +54,9 @@ "resolve-url-loader": "^5.0.0", "universal-cookie": "^4.0.4", "uswds": "^2.13.3", - "web-vitals": "^2.1.4" + "web-vitals": "^2.1.4", + "winston": "^3.11.0", + "winston-cloudwatch": "^6.2.0" }, "devDependencies": { "@babel/plugin-proposal-private-property-in-object": "^7.21.11", @@ -12615,6 +12617,14 @@ "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==" }, + "node_modules/@colors/colors": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz", + "integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==", + "engines": { + "node": ">=0.1.90" + } + }, "node_modules/@cspotcode/source-map-support": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", @@ -12907,6 +12917,16 @@ "postcss-selector-parser": "^6.0.10" } }, + "node_modules/@dabh/diagnostics": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz", + "integrity": "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==", + "dependencies": { + "colorspace": "1.1.x", + "enabled": "2.0.x", + "kuler": "^2.0.0" + } + }, "node_modules/@discoveryjs/json-ext": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", @@ -19736,6 +19756,11 @@ "@types/jest": "*" } }, + "node_modules/@types/triple-beam": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.5.tgz", + "integrity": "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==" + }, "node_modules/@types/trusted-types": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.3.tgz", @@ -22493,6 +22518,15 @@ "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==" }, + "node_modules/color": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", + "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", + "dependencies": { + "color-convert": "^1.9.3", + "color-string": "^1.6.0" + } + }, "node_modules/color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -22506,6 +22540,15 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, "node_modules/colord": { "version": "2.9.3", "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", @@ -22517,6 +22560,15 @@ "integrity": "sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==", "peer": true }, + "node_modules/colorspace": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz", + "integrity": "sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==", + "dependencies": { + "color": "^3.1.3", + "text-hex": "1.0.x" + } + }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -24315,6 +24367,11 @@ "node": ">= 4" } }, + "node_modules/enabled": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz", + "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==" + }, "node_modules/encode-utf8": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/encode-utf8/-/encode-utf8-1.0.3.tgz", @@ -25800,8 +25857,7 @@ "node_modules/fast-safe-stringify": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", - "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", - "dev": true + "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==" }, "node_modules/fast-xml-parser": { "version": "4.3.2", @@ -25869,6 +25925,11 @@ "pend": "~1.2.0" } }, + "node_modules/fecha": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz", + "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==" + }, "node_modules/fetch-readablestream": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/fetch-readablestream/-/fetch-readablestream-0.2.0.tgz", @@ -26306,6 +26367,11 @@ "node": ">=0.4.0" } }, + "node_modules/fn.name": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", + "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" + }, "node_modules/follow-redirects": { "version": "1.15.4", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz", @@ -31782,6 +31848,11 @@ "node": ">= 8" } }, + "node_modules/kuler": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", + "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==" + }, "node_modules/language-subtag-registry": { "version": "0.3.22", "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz", @@ -31922,6 +31993,11 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, + "node_modules/lodash.assign": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", + "integrity": "sha512-hFuH8TY+Yji7Eja3mGiuAxBqLagejScbG8GbG0j6o9vzn0YL14My+ktnqtZgFTosKymC9/44wP6s7xyuLfnClw==" + }, "node_modules/lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", @@ -31939,6 +32015,11 @@ "integrity": "sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA==", "dev": true }, + "node_modules/lodash.find": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.find/-/lodash.find-4.6.0.tgz", + "integrity": "sha512-yaRZoAV3Xq28F1iafWN1+a0rflOej93l1DQUejs3SZ41h2O9UJBoS9aueGjPDgAl4B6tPC0NuuchLKaDQQ3Isg==" + }, "node_modules/lodash.flatten": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", @@ -31951,6 +32032,16 @@ "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", "dev": true }, + "node_modules/lodash.isempty": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.isempty/-/lodash.isempty-4.4.0.tgz", + "integrity": "sha512-oKMuF3xEeqDltrGMfDxAPGIVMSSRv8tbRSODbrs4KGsRRLEhrW8N8Rd4DRgB2+621hY8A8XwwrTVhXWpxFvMzg==" + }, + "node_modules/lodash.iserror": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lodash.iserror/-/lodash.iserror-3.1.1.tgz", + "integrity": "sha512-eT/VeNns9hS7vAj1NKW/rRX6b+C3UX3/IAAqEE7aC4Oo2C0iD82NaP5IS4bSlQsammTii4qBJ8G1zd1LTL8hCw==" + }, "node_modules/lodash.isplainobject": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", @@ -32129,6 +32220,22 @@ "node": ">=8" } }, + "node_modules/logform": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/logform/-/logform-2.6.0.tgz", + "integrity": "sha512-1ulHeNPp6k/LD8H91o7VYFBng5i1BDE7HoKxVbZiGFidS1Rj65qcywLxX+pVfAPoQJEjRdvKcusKwOupHCVOVQ==", + "dependencies": { + "@colors/colors": "1.6.0", + "@types/triple-beam": "^1.3.2", + "fecha": "^4.2.0", + "ms": "^2.1.1", + "safe-stable-stringify": "^2.3.1", + "triple-beam": "^1.3.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, "node_modules/logkitty": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/logkitty/-/logkitty-0.7.1.tgz", @@ -34386,6 +34493,14 @@ "wrappy": "1" } }, + "node_modules/one-time": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz", + "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==", + "dependencies": { + "fn.name": "1.x.x" + } + }, "node_modules/onetime": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", @@ -39699,6 +39814,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/safe-stable-stringify": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz", + "integrity": "sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==", + "engines": { + "node": ">=10" + } + }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -40598,6 +40721,19 @@ "url": "https://github.com/steveukx/git-js?sponsor=1" } }, + "node_modules/simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "node_modules/simple-swizzle/node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + }, "node_modules/sisteransi": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", @@ -40858,6 +40994,14 @@ "es5-ext": "^0.10.53" } }, + "node_modules/stack-trace": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", + "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==", + "engines": { + "node": "*" + } + }, "node_modules/stack-utils": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", @@ -42053,6 +42197,11 @@ "resolved": "https://registry.npmjs.org/text-encoding-utf-8/-/text-encoding-utf-8-1.0.2.tgz", "integrity": "sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg==" }, + "node_modules/text-hex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", + "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==" + }, "node_modules/text-segmentation": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/text-segmentation/-/text-segmentation-1.0.3.tgz", @@ -42312,6 +42461,14 @@ "node": ">=0.8.0" } }, + "node_modules/triple-beam": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.4.1.tgz", + "integrity": "sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==", + "engines": { + "node": ">= 14.0.0" + } + }, "node_modules/trough": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/trough/-/trough-2.1.0.tgz", @@ -43838,6 +43995,122 @@ "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", "dev": true }, + "node_modules/winston": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/winston/-/winston-3.12.0.tgz", + "integrity": "sha512-OwbxKaOlESDi01mC9rkM0dQqQt2I8DAUMRLZ/HpbwvDXm85IryEHgoogy5fziQy38PntgZsLlhAYHz//UPHZ5w==", + "dependencies": { + "@colors/colors": "^1.6.0", + "@dabh/diagnostics": "^2.0.2", + "async": "^3.2.3", + "is-stream": "^2.0.0", + "logform": "^2.4.0", + "one-time": "^1.0.0", + "readable-stream": "^3.4.0", + "safe-stable-stringify": "^2.3.1", + "stack-trace": "0.0.x", + "triple-beam": "^1.3.0", + "winston-transport": "^4.7.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/winston-cloudwatch": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/winston-cloudwatch/-/winston-cloudwatch-6.2.0.tgz", + "integrity": "sha512-FcJ3x+rcAKGKr4Y9tbPjXkt39I6aiAMD//ElDYcWGMFp4GjMeXP6JYrfl1yNqvH65fzehqLD71MQMlt/5/9ZIQ==", + "dependencies": { + "async": "^3.1.0", + "chalk": "^4.0.0", + "fast-safe-stringify": "^2.0.7", + "lodash.assign": "^4.2.0", + "lodash.find": "^4.6.0", + "lodash.isempty": "^4.4.0", + "lodash.iserror": "^3.1.1" + }, + "peerDependencies": { + "@aws-sdk/client-cloudwatch-logs": "^3.0.0", + "winston": "^3.0.0" + } + }, + "node_modules/winston-cloudwatch/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/winston-cloudwatch/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/winston-cloudwatch/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/winston-cloudwatch/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==" + }, + "node_modules/winston-cloudwatch/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/winston-cloudwatch/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/winston-transport": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.7.0.tgz", + "integrity": "sha512-ajBj65K5I7denzer2IYW6+2bNIVqLGDHqDw3Ow8Ohh+vdW+rv4MZ6eiDvHoKhfJFZ2auyN8byXieDDJ96ViONg==", + "dependencies": { + "logform": "^2.3.2", + "readable-stream": "^3.6.0", + "triple-beam": "^1.3.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, "node_modules/workbox-background-sync": { "version": "6.6.0", "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-6.6.0.tgz", diff --git a/frontend/package.json b/frontend/package.json index 8f7150e5..f25634c3 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -57,7 +57,9 @@ "resolve-url-loader": "^5.0.0", "universal-cookie": "^4.0.4", "uswds": "^2.13.3", - "web-vitals": "^2.1.4" + "web-vitals": "^2.1.4", + "winston": "^3.11.0", + "winston-cloudwatch": "^6.2.0" }, "overrides": { "@mattiasbuelens/web-streams-polyfill": "npm:web-streams-polyfill", @@ -151,4 +153,4 @@ "webpack": "^5.88", "webpack-cli": "^5.1" } -} +} \ No newline at end of file diff --git a/frontend/scripts/api.js b/frontend/scripts/api.js index 3ada623b..a690e49d 100644 --- a/frontend/scripts/api.js +++ b/frontend/scripts/api.js @@ -1,9 +1,11 @@ // Main entrypoint for serverless frontend code. import serverless from 'serverless-http'; +import cors from 'cors'; import helmet from 'helmet'; import express from 'express'; import path from 'path'; +import { ALLOW_ORIGIN, ALLOW_METHODS } from './constants.js'; import logger from 'lambda-logger'; export const app = express(); @@ -26,9 +28,28 @@ app.use((req, res, next) => { next(); }); +app.use(cors({ origin: ALLOW_ORIGIN, methods: ALLOW_METHODS })); + app.use( helmet({ - strictTransportSecurity: { + contentSecurityPolicy: { + directives: { + defaultSrc: [ + "'self'", + 'https://cognito-idp.us-gov-west-1.amazonaws.com', + 'https://api.crossfeed.cyber.dhs.gov' + ], + objectSrc: ["'none'"], + scriptSrc: [ + "'self'", + 'https://api.crossfeed.cyber.dhs.gov' + // Add any other allowed script sources here + ], + frameAncestors: ["'none'"] + // Add other directives as needed + } + }, + hsts: { maxAge: 31536000, includeSubDomains: true, preload: true @@ -36,28 +57,10 @@ app.use( }) ); -app.use( - helmet.contentSecurityPolicy({ - directives: { - defaultSrc: [ - "'self'", - 'https://cognito-idp.us-gov-west-1.amazonaws.com', - 'https://api.crossfeed.cyber.dhs.gov' - ], - scriptSrc: [ - "'self'", - 'https://api.crossfeed.cyber.dhs.gov', - // Add any other allowed script sources here - "'unsafe-inline'" // Allow inline scripts (not recommended for security) - ] - // Add other directives as needed - } - }) -); - -// app.get('/', (request, response) => { -// response.send("Hello world " + __dirname + " " + JSON.stringify(getDirectories(path.join(__dirname, '../')))); -// }) +app.use((req, res, next) => { + res.setHeader('X-XSS-Protection', '0'); + next(); +}); app.use(express.static(path.join(__dirname, '../build'))); diff --git a/frontend/scripts/constants.js b/frontend/scripts/constants.js index 3520ae39..57a3005a 100644 --- a/frontend/scripts/constants.js +++ b/frontend/scripts/constants.js @@ -1,3 +1,3 @@ //CORS Options -export const ALLOW_ORIGIN = '*'; +export const ALLOW_ORIGIN = ["*"]; export const ALLOW_METHODS = ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS']; diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index bf934043..12f67b28 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -16,6 +16,7 @@ import { import { Domain, AuthLogin, + AuthLoginCreate, AuthCreateAccount, Scans, Scan, @@ -31,10 +32,10 @@ import { LoginGovCallback, Feeds, Domains, - Reports + Reports, + RegionUsers } from 'pages'; import { Layout, RouteGuard } from 'components'; -import { CrossfeedFooter } from './components/Footer'; import './styles.scss'; import { Authenticator } from '@aws-amplify/ui-react'; @@ -103,9 +104,14 @@ const App: React.FC = () => ( exact path="/signup" render={() => } - unauth={(props) => ( - - )} + unauth={AuthLoginCreate} + component={Risk} + /> + } + unauth={AuthLoginCreate} component={Risk} /> ( /> - + ( )} + permissions={['standard', 'globalView']} /> + + + + + - - - - - - + + + + - - - - diff --git a/infrastructure/cloudtrail_bucket_policy.tpl b/infrastructure/cloudtrail_bucket_policy.tpl index c5cd000e..0ba644de 100644 --- a/infrastructure/cloudtrail_bucket_policy.tpl +++ b/infrastructure/cloudtrail_bucket_policy.tpl @@ -2,21 +2,21 @@ "Version": "2012-10-17", "Statement": [ { - "Sid": "AWSCloudTrailAclCheck", + "Sid": "AWSCloudTrailAclCheck20121017", "Effect": "Allow", "Principal": { "Service": "cloudtrail.amazonaws.com" }, - "Action": "s3:GetBucketAcl", - "Resource": "arn:aws-us-gov:s3:::${bucketName}" + "Action": ["s3:GetBucketAcl"], + "Resource": ["arn:aws-us-gov:s3:::${bucketName}"] }, { - "Sid": "AWSCloudTrailWrite", + "Sid": "AWSCloudTrailWrite20121017", "Effect": "Allow", "Principal": { "Service": "cloudtrail.amazonaws.com" }, - "Action": "s3:PutObject", + "Action": ["s3:PutObject"], "Resource": [ "arn:aws-us-gov:s3:::${bucketName}/AWSLogs/${accountId}", "arn:aws-us-gov:s3:::${bucketName}/AWSLogs/${accountId}/*" @@ -41,15 +41,6 @@ "aws:SecureTransport": "false" } } - }, - { - "Action": "s3:PutObject", - "Effect": "Allow", - "Principal": { - "Service": "logging.s3.amazonaws.com" - }, - "Resource": "arn:aws-us-gov:s3:::${bucketName}/*", - "Sid": "S3PolicyStmt-DO-NOT-MODIFY-1697490065333" } ] -} +} \ No newline at end of file diff --git a/infrastructure/database.tf b/infrastructure/database.tf index e6e77b03..fdeb83d5 100644 --- a/infrastructure/database.tf +++ b/infrastructure/database.tf @@ -32,7 +32,7 @@ resource "aws_db_instance" "db" { max_allocated_storage = 10000 storage_type = "gp2" engine = "postgres" - engine_version = "15.3" + engine_version = "15.5" allow_major_version_upgrade = true skip_final_snapshot = true availability_zone = data.aws_availability_zones.available.names[0] @@ -148,6 +148,8 @@ resource "aws_instance" "db_accessor" { OperationalStatus = "Stage" ResourceSavings = "" Security = "" + StrStp = "" + POC = "" } root_block_device { diff --git a/infrastructure/elastic.tf b/infrastructure/elastic.tf index 65b2990e..e8115995 100644 --- a/infrastructure/elastic.tf +++ b/infrastructure/elastic.tf @@ -22,6 +22,8 @@ resource "aws_instance" "elk_stack" { ResourceSavings = "" Security = "" Lifecycle_TargetTag = "Sunday-02" + POC = "" + StrStp = "" } root_block_device { volume_size = 15 @@ -33,6 +35,7 @@ resource "aws_instance" "elk_stack" { iam_instance_profile = aws_iam_instance_profile.db_accessor.id user_data = file("./ssm-agent-install.sh") + lifecycle { # prevent_destroy = true ignore_changes = [ami] diff --git a/infrastructure/matomo.tf b/infrastructure/matomo.tf index ced19147..164ea9df 100644 --- a/infrastructure/matomo.tf +++ b/infrastructure/matomo.tf @@ -196,7 +196,7 @@ resource "aws_db_instance" "matomo_db" { engine = "mariadb" engine_version = "10.6" skip_final_snapshot = true - availability_zone = "us-gov-east-1a" + availability_zone = data.aws_availability_zones.available.names[0] multi_az = true backup_retention_period = 35 storage_encrypted = true diff --git a/infrastructure/prod.tfvars b/infrastructure/prod.tfvars index 2e76b4f9..fee0718e 100644 --- a/infrastructure/prod.tfvars +++ b/infrastructure/prod.tfvars @@ -11,6 +11,26 @@ db_port = 5432 db_table_name = "cfproddb" db_instance_class = "db.m5.xlarge" ssm_crossfeed_vpc_name = "/crossfeed/prod/VPC_NAME" +log_metric_namespace = "LogMetrics" +log_metric_api_error_rate = "crossfeed-prod-APIErrorRate" +log_metric_root_user = "crossfeed-prod-RootUserAccess" +log_metric_unauthorized_api_call = "crossfeed-prod-UnauthorizedApiCall" +log_metric_login_without_mfa = "crossfeed-prod-ConsoleSignInWithoutMFA" +log_metric_iam_policy = "crossfeed-prod-IAMPolicyChange" +log_metric_cloudtrail = "crossfeed-prod-CloudTrailConfigurationChanges" +log_metric_login_failure = "crossfeed-prod-ConsoleLoginFailure" +log_metric_cmk_delete_disable = "crossfeed-prod-DisablingOrScheduledDeletionOfCMK" +log_metric_s3_bucket_policy = "crossfeed-prod-S3BucketPolicyChanges" +log_metric_aws_config = "crossfeed-prod-AWSConfigConfigurationChange" +log_metric_security_group = "crossfeed-prod-SecurityGroupChange" +log_metric_nacl = "crossfeed-prod-NACLChange" +log_metric_network_gateway = "crossfeed-prod-NetworkGatewayChange" +log_metric_route_table = "crossfeed-prod-RouteTableChange" +log_metric_vpc = "crossfeed-prod-VPCChange" +log_metric_ec2_shutdown = "crossfeed-prod-EC2Shutdown" +log_metric_db_shutdown = "crossfeed-prod-DBShutdown" +log_metric_db_deletion = "crossfeed-prod-DBDeletion" +sns_topic_alarms = "crossfeed-prod-cis-alarms" ssm_lambda_subnet = "/crossfeed/prod/SUBNET_ID" ssm_lambda_sg = "/crossfeed/prod/SG_ID" ssm_worker_subnet = "/crossfeed/prod/WORKER_SUBNET_ID" @@ -37,6 +57,7 @@ ssm_lg_api_key = "/crossfeed/prod/LG_API_KEY" ssm_lg_workspace_name = "/crossfeed/prod/LG_WORKSPACE_NAME" ssm_https_proxy = "/crossfeed/prod/HTTPS_PROXY" ssm_ses_email_identity_arn = "/crossfeed/prod/SES_EMAIL_IDENTITY_ARN" +ssm_worker_kms_keys = "/crossfeed/prod/WORKER_KMS_KEYS" db_group_name = "crossfeed-prod-db-group" worker_ecs_repository_name = "crossfeed-prod-worker" worker_ecs_cluster_name = "crossfeed-prod-worker" diff --git a/infrastructure/sns.tf b/infrastructure/sns.tf new file mode 100644 index 00000000..c7a8a9aa --- /dev/null +++ b/infrastructure/sns.tf @@ -0,0 +1,9 @@ +resource "aws_sns_topic" "alarms" { + name = var.sns_topic_alarms + kms_master_key_id = "alias/aws/sns" + + tags = { + Project = var.project + Stage = var.stage + } +} \ No newline at end of file diff --git a/infrastructure/stage.tfvars b/infrastructure/stage.tfvars index ab362e66..99cb75bb 100644 --- a/infrastructure/stage.tfvars +++ b/infrastructure/stage.tfvars @@ -10,6 +10,26 @@ db_name = "crossfeed-stage-db" db_port = 5432 db_table_name = "cfstagingdb" db_instance_class = "db.m5.xlarge" +log_metric_namespace = "LogMetrics" +log_metric_root_user = "crossfeed-staging-RootUserAccess" +log_metric_api_error_rate = "crossfeed-staging-APIErrorRate" +log_metric_unauthorized_api_call = "crossfeed-staging-UnauthorizedApiCall" +log_metric_login_without_mfa = "crossfeed-staging-ConsoleSignInWithoutMFA" +log_metric_iam_policy = "crossfeed-staging-IAMPolicyChange" +log_metric_cloudtrail = "crossfeed-staging-CloudTrailConfigurationChanges" +log_metric_login_failure = "crossfeed-staging-ConsoleLoginFailure" +log_metric_cmk_delete_disable = "crossfeed-staging-DisablingOrScheduledDeletionOfCMK" +log_metric_s3_bucket_policy = "crossfeed-staging-S3BucketPolicyChanges" +log_metric_aws_config = "crossfeed-staging-AWSConfigConfigurationChange" +log_metric_security_group = "crossfeed-staging-SecurityGroupChange" +log_metric_nacl = "crossfeed-staging-NACLChange" +log_metric_network_gateway = "crossfeed-staging-NetworkGatewayChange" +log_metric_route_table = "crossfeed-staging-RouteTableChange" +log_metric_vpc = "crossfeed-staging-VPCChange" +log_metric_ec2_shutdown = "crossfeed-staging-EC2Shutdown" +log_metric_db_shutdown = "crossfeed-staging-DBShutdown" +log_metric_db_deletion = "crossfeed-staging-DBDeletion" +sns_topic_alarms = "crossfeed-staging-cis-alarms" ssm_crossfeed_vpc_name = "/crossfeed/staging/VPC_NAME" ssm_lambda_subnet = "/crossfeed/staging/SUBNET_ID" ssm_lambda_sg = "/crossfeed/staging/SG_ID" @@ -37,6 +57,7 @@ ssm_lg_api_key = "/crossfeed/staging/LG_API_KEY" ssm_lg_workspace_name = "/crossfeed/staging/LG_WORKSPACE_NAME" ssm_https_proxy = "/crossfeed/staging/HTTPS_PROXY" ssm_ses_email_identity_arn = "/crossfeed/staging/SES_EMAIL_IDENTITY_ARN" +ssm_worker_kms_keys = "/crossfeed/staging/WORKER_KMS_KEYS" db_group_name = "crossfeed-staging-db-group" worker_ecs_repository_name = "crossfeed-staging-worker" worker_ecs_cluster_name = "crossfeed-staging-worker" diff --git a/infrastructure/vars.tf b/infrastructure/vars.tf index 834f0966..3ace1128 100644 --- a/infrastructure/vars.tf +++ b/infrastructure/vars.tf @@ -70,6 +70,126 @@ variable "frontend_cert_arn" { default = "arn:aws:acm:us-east-1:563873274798:certificate/7c6a5980-80e3-47a4-9f21-cbda44b6f34c" } +variable "log_metric_namespace" { + description = "log_metric_namespace" + type = string + default = "LogMetrics" +} + +variable "log_metric_api_error_rate" { + description = "log_metric_filter_api_error_rate" + type = string + default = "crossfeed-staging-APIErrorRate" +} + +variable "log_metric_root_user" { + description = "log_metric_filter_root_user" + type = string + default = "crossfeed-staging-RootUserAccess" +} + +variable "log_metric_unauthorized_api_call" { + description = "log_metric_filter_unauthorized_api_call" + type = string + default = "crossfeed-staging-UnauthorizedAPICall" +} + +variable "log_metric_login_without_mfa" { + description = "log_metric_filter_login_without_mfa" + type = string + default = "crossfeed-staging-ConsoleLoginWithoutMFA" +} + +variable "log_metric_iam_policy" { + description = "log_metric_filter_iam_policy" + type = string + default = "crossfeed-staging-IAMPolicyChange" +} + +variable "log_metric_cloudtrail" { + description = "log_metric_filter_cloudtrail" + type = string + default = "crossfeed-staging-CloudTrailConfigurationChange" +} + +variable "log_metric_login_failure" { + description = "log_metric_filter_login_failure" + type = string + default = "crossfeed-staging-ConsoleLoginFailure" +} + +variable "log_metric_cmk_delete_disable" { + description = "log_metric_filter_cmk_delete_disable" + type = string + default = "crossfeed-staging-DisablingOrScheduledDeletionOfCMK" +} + +variable "log_metric_s3_bucket_policy" { + description = "log_metric_filter_s3_bucket_policy" + type = string + default = "crossfeed-staging-S3BucketPolicyChange" +} + +variable "log_metric_aws_config" { + description = "log_metric_filter_aws_config" + type = string + default = "crossfeed-staging-AWSConfigConfigurationChange" +} + +variable "log_metric_security_group" { + description = "log_metric_filter_security_group" + type = string + default = "crossfeed-staging-SecurityGroupChange" +} + +variable "log_metric_nacl" { + description = "log_metric_filter_nacl" + type = string + default = "crossfeed-staging-NACLChange" +} + +variable "log_metric_network_gateway" { + description = "log_metric_filter_network_gateway" + type = string + default = "crossfeed-staging-NetworkGatewayChange" +} + +variable "log_metric_route_table" { + description = "log_metric_filter_route_table" + type = string + default = "crossfeed-staging-RouteTableChange" +} + +variable "log_metric_vpc" { + description = "log_metric_filter_vpc" + type = string + default = "crossfeed-staging-VPCChange" +} + +variable "log_metric_ec2_shutdown" { + description = "log_metric_filter_ec2_shutdown" + type = string + default = "crossfeed-staging-EC2Shutdown" +} + +variable "log_metric_db_shutdown" { + description = "log_metric_filter_DB_shutdown" + type = string + default = "crossfeed-staging-DBShutdown" +} + +variable "log_metric_db_deletion" { + description = "log_metric_filter_db_deletion" + type = string + default = "crossfeed-staging-DBDeletion" +} + +variable "sns_topic_alarms" { + description = "sns_alarm_topic_name" + type = string + default = "crossfeed-staging-cis-alarms" +} + variable "ssm_db_name" { description = "ssm_db_name" type = string @@ -407,6 +527,30 @@ variable "create_elk_instance" { default = false } +variable "severity_critical" { + description = "severity_critical" + type = string + default = "CRITICAL" +} + +variable "severity_high" { + description = "severity_high" + type = string + default = "HIGH" +} + +variable "severity_medium" { + description = "severity_medium" + type = string + default = "MEDIUM" +} + +variable "severity_low" { + description = "severity_low" + type = string + default = "LOW" +} + variable "ami_id" { description = "ID of the AMI to use for EC2 instances." type = string @@ -517,4 +661,10 @@ variable "ssm_ses_email_identity_arn" { description = "ssm_ses_email_identity_arn" type = string default = "/crossfeed/staging/SES_EMAIL_IDENTITY_ARN" +} + +variable "ssm_worker_kms_keys" { + description = "ssm_worker_kms_keys" + type = string + default = "/crossfeed/staging/WORKER_KMS_KEYS" } \ No newline at end of file diff --git a/infrastructure/worker.tf b/infrastructure/worker.tf index dcd08e80..54bf7368 100644 --- a/infrastructure/worker.tf +++ b/infrastructure/worker.tf @@ -42,6 +42,8 @@ resource "aws_iam_role" "worker_task_execution_role" { } } +data "aws_ssm_parameter" "worker_kms_keys" { name = var.ssm_worker_kms_keys } + resource "aws_iam_role_policy" "worker_task_execution_role_policy" { name_prefix = var.worker_ecs_role_name role = aws_iam_role.worker_task_execution_role.id @@ -95,13 +97,14 @@ resource "aws_iam_role_policy" "worker_task_execution_role_policy" { "Action": [ "kms:Decrypt" ], - "Resource": "*" + "Resource": ${data.aws_ssm_parameter.worker_kms_keys.value} } ] } EOF } + resource "aws_iam_role" "worker_task_role" { name = "crossfeed-${var.stage}-worker-task" assume_role_policy = <