diff --git a/app/package.json b/app/package.json index 9ab1369b..437af3f2 100644 --- a/app/package.json +++ b/app/package.json @@ -23,6 +23,7 @@ }, "dependencies": { "@apollo/server": "^4.9.4", + "@aws-sdk/client-secrets-manager": "^3.433.0", "@nestjs/apollo": "^12.0.7", "@nestjs/axios": "^3.0.0", "@nestjs/cache-manager": "^2.0.1", diff --git a/app/pnpm-lock.yaml b/app/pnpm-lock.yaml index a460350a..83167af1 100644 --- a/app/pnpm-lock.yaml +++ b/app/pnpm-lock.yaml @@ -8,6 +8,9 @@ dependencies: '@apollo/server': specifier: ^4.9.4 version: 4.9.4(graphql@16.8.1) + '@aws-sdk/client-secrets-manager': + specifier: ^3.433.0 + version: 3.433.0 '@nestjs/apollo': specifier: ^12.0.7 version: 12.0.7(@apollo/server@4.9.4)(@nestjs/common@10.0.0)(@nestjs/core@10.0.0)(@nestjs/graphql@12.0.7)(graphql@16.8.1) @@ -401,6 +404,442 @@ packages: xss: 1.0.14 dev: false + /@aws-crypto/crc32@3.0.0: + resolution: {integrity: sha512-IzSgsrxUcsrejQbPVilIKy16kAT52EwB6zSaI+M3xxIhKh5+aldEyvI+z6erM7TCLB2BJsFrtHjp6/4/sr+3dA==} + dependencies: + '@aws-crypto/util': 3.0.0 + '@aws-sdk/types': 3.433.0 + tslib: 1.14.1 + dev: false + + /@aws-crypto/ie11-detection@3.0.0: + resolution: {integrity: sha512-341lBBkiY1DfDNKai/wXM3aujNBkXR7tq1URPQDL9wi3AUbI80NR74uF1TXHMm7po1AcnFk8iu2S2IeU/+/A+Q==} + dependencies: + tslib: 1.14.1 + dev: false + + /@aws-crypto/sha256-browser@3.0.0: + resolution: {integrity: sha512-8VLmW2B+gjFbU5uMeqtQM6Nj0/F1bro80xQXCW6CQBWgosFWXTx77aeOF5CAIAmbOK64SdMBJdNr6J41yP5mvQ==} + dependencies: + '@aws-crypto/ie11-detection': 3.0.0 + '@aws-crypto/sha256-js': 3.0.0 + '@aws-crypto/supports-web-crypto': 3.0.0 + '@aws-crypto/util': 3.0.0 + '@aws-sdk/types': 3.433.0 + '@aws-sdk/util-locate-window': 3.310.0 + '@aws-sdk/util-utf8-browser': 3.259.0 + tslib: 1.14.1 + dev: false + + /@aws-crypto/sha256-js@3.0.0: + resolution: {integrity: sha512-PnNN7os0+yd1XvXAy23CFOmTbMaDxgxXtTKHybrJ39Y8kGzBATgBFibWJKH6BhytLI/Zyszs87xCOBNyBig6vQ==} + dependencies: + '@aws-crypto/util': 3.0.0 + '@aws-sdk/types': 3.433.0 + tslib: 1.14.1 + dev: false + + /@aws-crypto/supports-web-crypto@3.0.0: + resolution: {integrity: sha512-06hBdMwUAb2WFTuGG73LSC0wfPu93xWwo5vL2et9eymgmu3Id5vFAHBbajVWiGhPO37qcsdCap/FqXvJGJWPIg==} + dependencies: + tslib: 1.14.1 + dev: false + + /@aws-crypto/util@3.0.0: + resolution: {integrity: sha512-2OJlpeJpCR48CC8r+uKVChzs9Iungj9wkZrl8Z041DWEWvyIHILYKCPNzJghKsivj+S3mLo6BVc7mBNzdxA46w==} + dependencies: + '@aws-sdk/types': 3.433.0 + '@aws-sdk/util-utf8-browser': 3.259.0 + tslib: 1.14.1 + dev: false + + /@aws-sdk/client-secrets-manager@3.433.0: + resolution: {integrity: sha512-dovFUtsl0uJuW3/XywP4jyL6iiT5+/+thGLpXHZbbXf/5188SBJXIfTr9FRyWiCK67XaPAGWdsq+6CCknL9ZZA==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-crypto/sha256-browser': 3.0.0 + '@aws-crypto/sha256-js': 3.0.0 + '@aws-sdk/client-sts': 3.433.0 + '@aws-sdk/credential-provider-node': 3.433.0 + '@aws-sdk/middleware-host-header': 3.433.0 + '@aws-sdk/middleware-logger': 3.433.0 + '@aws-sdk/middleware-recursion-detection': 3.433.0 + '@aws-sdk/middleware-signing': 3.433.0 + '@aws-sdk/middleware-user-agent': 3.433.0 + '@aws-sdk/region-config-resolver': 3.433.0 + '@aws-sdk/types': 3.433.0 + '@aws-sdk/util-endpoints': 3.433.0 + '@aws-sdk/util-user-agent-browser': 3.433.0 + '@aws-sdk/util-user-agent-node': 3.433.0 + '@smithy/config-resolver': 2.0.16 + '@smithy/fetch-http-handler': 2.2.4 + '@smithy/hash-node': 2.0.12 + '@smithy/invalid-dependency': 2.0.12 + '@smithy/middleware-content-length': 2.0.14 + '@smithy/middleware-endpoint': 2.1.3 + '@smithy/middleware-retry': 2.0.18 + '@smithy/middleware-serde': 2.0.12 + '@smithy/middleware-stack': 2.0.6 + '@smithy/node-config-provider': 2.1.3 + '@smithy/node-http-handler': 2.1.8 + '@smithy/protocol-http': 3.0.8 + '@smithy/smithy-client': 2.1.12 + '@smithy/types': 2.4.0 + '@smithy/url-parser': 2.0.12 + '@smithy/util-base64': 2.0.0 + '@smithy/util-body-length-browser': 2.0.0 + '@smithy/util-body-length-node': 2.1.0 + '@smithy/util-defaults-mode-browser': 2.0.16 + '@smithy/util-defaults-mode-node': 2.0.21 + '@smithy/util-retry': 2.0.5 + '@smithy/util-utf8': 2.0.0 + tslib: 2.6.0 + uuid: 8.3.2 + transitivePeerDependencies: + - aws-crt + dev: false + + /@aws-sdk/client-sso@3.433.0: + resolution: {integrity: sha512-L7ksMP7UnYH+w52ly+m+s5vk8662VtyqJ+UduFEMPqKUHTFEm7w+CCw4Xfk3hl5GlVvqPvYWqBqv8eLKSHpCEQ==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-crypto/sha256-browser': 3.0.0 + '@aws-crypto/sha256-js': 3.0.0 + '@aws-sdk/middleware-host-header': 3.433.0 + '@aws-sdk/middleware-logger': 3.433.0 + '@aws-sdk/middleware-recursion-detection': 3.433.0 + '@aws-sdk/middleware-user-agent': 3.433.0 + '@aws-sdk/region-config-resolver': 3.433.0 + '@aws-sdk/types': 3.433.0 + '@aws-sdk/util-endpoints': 3.433.0 + '@aws-sdk/util-user-agent-browser': 3.433.0 + '@aws-sdk/util-user-agent-node': 3.433.0 + '@smithy/config-resolver': 2.0.16 + '@smithy/fetch-http-handler': 2.2.4 + '@smithy/hash-node': 2.0.12 + '@smithy/invalid-dependency': 2.0.12 + '@smithy/middleware-content-length': 2.0.14 + '@smithy/middleware-endpoint': 2.1.3 + '@smithy/middleware-retry': 2.0.18 + '@smithy/middleware-serde': 2.0.12 + '@smithy/middleware-stack': 2.0.6 + '@smithy/node-config-provider': 2.1.3 + '@smithy/node-http-handler': 2.1.8 + '@smithy/protocol-http': 3.0.8 + '@smithy/smithy-client': 2.1.12 + '@smithy/types': 2.4.0 + '@smithy/url-parser': 2.0.12 + '@smithy/util-base64': 2.0.0 + '@smithy/util-body-length-browser': 2.0.0 + '@smithy/util-body-length-node': 2.1.0 + '@smithy/util-defaults-mode-browser': 2.0.16 + '@smithy/util-defaults-mode-node': 2.0.21 + '@smithy/util-retry': 2.0.5 + '@smithy/util-utf8': 2.0.0 + tslib: 2.6.0 + transitivePeerDependencies: + - aws-crt + dev: false + + /@aws-sdk/client-sts@3.433.0: + resolution: {integrity: sha512-hQ+NLIcA1KRJ2qPdrtkJ3fOEVnehLLMlnB/I5mjg9K2UKjuiOufLao6tc5SyW9fseIL9AdX3fjJ8Unhg+y1RWg==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-crypto/sha256-browser': 3.0.0 + '@aws-crypto/sha256-js': 3.0.0 + '@aws-sdk/credential-provider-node': 3.433.0 + '@aws-sdk/middleware-host-header': 3.433.0 + '@aws-sdk/middleware-logger': 3.433.0 + '@aws-sdk/middleware-recursion-detection': 3.433.0 + '@aws-sdk/middleware-sdk-sts': 3.433.0 + '@aws-sdk/middleware-signing': 3.433.0 + '@aws-sdk/middleware-user-agent': 3.433.0 + '@aws-sdk/region-config-resolver': 3.433.0 + '@aws-sdk/types': 3.433.0 + '@aws-sdk/util-endpoints': 3.433.0 + '@aws-sdk/util-user-agent-browser': 3.433.0 + '@aws-sdk/util-user-agent-node': 3.433.0 + '@smithy/config-resolver': 2.0.16 + '@smithy/fetch-http-handler': 2.2.4 + '@smithy/hash-node': 2.0.12 + '@smithy/invalid-dependency': 2.0.12 + '@smithy/middleware-content-length': 2.0.14 + '@smithy/middleware-endpoint': 2.1.3 + '@smithy/middleware-retry': 2.0.18 + '@smithy/middleware-serde': 2.0.12 + '@smithy/middleware-stack': 2.0.6 + '@smithy/node-config-provider': 2.1.3 + '@smithy/node-http-handler': 2.1.8 + '@smithy/protocol-http': 3.0.8 + '@smithy/smithy-client': 2.1.12 + '@smithy/types': 2.4.0 + '@smithy/url-parser': 2.0.12 + '@smithy/util-base64': 2.0.0 + '@smithy/util-body-length-browser': 2.0.0 + '@smithy/util-body-length-node': 2.1.0 + '@smithy/util-defaults-mode-browser': 2.0.16 + '@smithy/util-defaults-mode-node': 2.0.21 + '@smithy/util-retry': 2.0.5 + '@smithy/util-utf8': 2.0.0 + fast-xml-parser: 4.2.5 + tslib: 2.6.0 + transitivePeerDependencies: + - aws-crt + dev: false + + /@aws-sdk/credential-provider-env@3.433.0: + resolution: {integrity: sha512-Vl7Qz5qYyxBurMn6hfSiNJeUHSqfVUlMt0C1Bds3tCkl3IzecRWwyBOlxtxO3VCrgVeW3HqswLzCvhAFzPH6nQ==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-sdk/types': 3.433.0 + '@smithy/property-provider': 2.0.13 + '@smithy/types': 2.4.0 + tslib: 2.6.0 + dev: false + + /@aws-sdk/credential-provider-ini@3.433.0: + resolution: {integrity: sha512-T+YhCOORyA4+i4T86FfFCmi/jPsmLOP6GAtScHp/K8XzB9XuVvJSZ+T8SUKeW6/9G9z3Az7dqeBVLcMdC6fFDA==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-sdk/credential-provider-env': 3.433.0 + '@aws-sdk/credential-provider-process': 3.433.0 + '@aws-sdk/credential-provider-sso': 3.433.0 + '@aws-sdk/credential-provider-web-identity': 3.433.0 + '@aws-sdk/types': 3.433.0 + '@smithy/credential-provider-imds': 2.0.18 + '@smithy/property-provider': 2.0.13 + '@smithy/shared-ini-file-loader': 2.2.2 + '@smithy/types': 2.4.0 + tslib: 2.6.0 + transitivePeerDependencies: + - aws-crt + dev: false + + /@aws-sdk/credential-provider-node@3.433.0: + resolution: {integrity: sha512-uOTBJszqGJIX5SrH2YdN501cv9rW4ghuSkasxI9DL+sVV5YRMd/bwu6I3PphRyK7z4dosDEbJ1xoIuVR/W04HQ==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-sdk/credential-provider-env': 3.433.0 + '@aws-sdk/credential-provider-ini': 3.433.0 + '@aws-sdk/credential-provider-process': 3.433.0 + '@aws-sdk/credential-provider-sso': 3.433.0 + '@aws-sdk/credential-provider-web-identity': 3.433.0 + '@aws-sdk/types': 3.433.0 + '@smithy/credential-provider-imds': 2.0.18 + '@smithy/property-provider': 2.0.13 + '@smithy/shared-ini-file-loader': 2.2.2 + '@smithy/types': 2.4.0 + tslib: 2.6.0 + transitivePeerDependencies: + - aws-crt + dev: false + + /@aws-sdk/credential-provider-process@3.433.0: + resolution: {integrity: sha512-W7FcGlQjio9Y/PepcZGRyl5Bpwb0uWU7qIUCh+u4+q2mW4D5ZngXg8V/opL9/I/p4tUH9VXZLyLGwyBSkdhL+A==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-sdk/types': 3.433.0 + '@smithy/property-provider': 2.0.13 + '@smithy/shared-ini-file-loader': 2.2.2 + '@smithy/types': 2.4.0 + tslib: 2.6.0 + dev: false + + /@aws-sdk/credential-provider-sso@3.433.0: + resolution: {integrity: sha512-vuc2X7q/1HUAO/NowfnNMpRDoHw8H2lyZZzUc0lmamy6PDrEFBi/VTm1nStGPuS9egCFrYlkRHsfp50ukYGa5w==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-sdk/client-sso': 3.433.0 + '@aws-sdk/token-providers': 3.433.0 + '@aws-sdk/types': 3.433.0 + '@smithy/property-provider': 2.0.13 + '@smithy/shared-ini-file-loader': 2.2.2 + '@smithy/types': 2.4.0 + tslib: 2.6.0 + transitivePeerDependencies: + - aws-crt + dev: false + + /@aws-sdk/credential-provider-web-identity@3.433.0: + resolution: {integrity: sha512-RlwjP1I5wO+aPpwyCp23Mk8nmRbRL33hqRASy73c4JA2z2YiRua+ryt6MalIxehhwQU6xvXUKulJnPG9VaMFZg==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-sdk/types': 3.433.0 + '@smithy/property-provider': 2.0.13 + '@smithy/types': 2.4.0 + tslib: 2.6.0 + dev: false + + /@aws-sdk/middleware-host-header@3.433.0: + resolution: {integrity: sha512-mBTq3UWv1UzeHG+OfUQ2MB/5GEkt5LTKFaUqzL7ESwzW8XtpBgXnjZvIwu3Vcd3sEetMwijwaGiJhY0ae/YyaA==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-sdk/types': 3.433.0 + '@smithy/protocol-http': 3.0.8 + '@smithy/types': 2.4.0 + tslib: 2.6.0 + dev: false + + /@aws-sdk/middleware-logger@3.433.0: + resolution: {integrity: sha512-We346Fb5xGonTGVZC9Nvqtnqy74VJzYuTLLiuuftA5sbNzftBDy/22QCfvYSTOAl3bvif+dkDUzQY2ihc5PwOQ==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-sdk/types': 3.433.0 + '@smithy/types': 2.4.0 + tslib: 2.6.0 + dev: false + + /@aws-sdk/middleware-recursion-detection@3.433.0: + resolution: {integrity: sha512-HEvYC9PQlWY/ccUYtLvAlwwf1iCif2TSAmLNr3YTBRVa98x6jKL0hlCrHWYklFeqOGSKy6XhE+NGJMUII0/HaQ==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-sdk/types': 3.433.0 + '@smithy/protocol-http': 3.0.8 + '@smithy/types': 2.4.0 + tslib: 2.6.0 + dev: false + + /@aws-sdk/middleware-sdk-sts@3.433.0: + resolution: {integrity: sha512-ORYbJnBejUyonFl5FwIqhvI3Cq6sAp9j+JpkKZtFNma9tFPdrhmYgfCeNH32H/wGTQV/tUoQ3luh0gA4cuk6DA==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-sdk/middleware-signing': 3.433.0 + '@aws-sdk/types': 3.433.0 + '@smithy/types': 2.4.0 + tslib: 2.6.0 + dev: false + + /@aws-sdk/middleware-signing@3.433.0: + resolution: {integrity: sha512-jxPvt59NZo/epMNLNTu47ikmP8v0q217I6bQFGJG7JVFnfl36zDktMwGw+0xZR80qiK47/2BWrNpta61Zd2FxQ==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-sdk/types': 3.433.0 + '@smithy/property-provider': 2.0.13 + '@smithy/protocol-http': 3.0.8 + '@smithy/signature-v4': 2.0.12 + '@smithy/types': 2.4.0 + '@smithy/util-middleware': 2.0.5 + tslib: 2.6.0 + dev: false + + /@aws-sdk/middleware-user-agent@3.433.0: + resolution: {integrity: sha512-jMgA1jHfisBK4oSjMKrtKEZf0sl2vzADivkFmyZFzORpSZxBnF6hC21RjaI+70LJLcc9rSCzLgcoz5lHb9LLDg==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-sdk/types': 3.433.0 + '@aws-sdk/util-endpoints': 3.433.0 + '@smithy/protocol-http': 3.0.8 + '@smithy/types': 2.4.0 + tslib: 2.6.0 + dev: false + + /@aws-sdk/region-config-resolver@3.433.0: + resolution: {integrity: sha512-xpjRjCZW+CDFdcMmmhIYg81ST5UAnJh61IHziQEk0FXONrg4kjyYPZAOjEdzXQ+HxJQuGQLKPhRdzxmQnbX7pg==} + engines: {node: '>=14.0.0'} + dependencies: + '@smithy/node-config-provider': 2.1.3 + '@smithy/types': 2.4.0 + '@smithy/util-config-provider': 2.0.0 + '@smithy/util-middleware': 2.0.5 + tslib: 2.6.0 + dev: false + + /@aws-sdk/token-providers@3.433.0: + resolution: {integrity: sha512-Q6aYVaQKB+CkBLHQQlN8MHVpOzZv9snRfVz7SxIpdbHkRuGEHiLliCY3fg6Sonvu3AKEPERPuHcaC75tnNpOBw==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-crypto/sha256-browser': 3.0.0 + '@aws-crypto/sha256-js': 3.0.0 + '@aws-sdk/middleware-host-header': 3.433.0 + '@aws-sdk/middleware-logger': 3.433.0 + '@aws-sdk/middleware-recursion-detection': 3.433.0 + '@aws-sdk/middleware-user-agent': 3.433.0 + '@aws-sdk/types': 3.433.0 + '@aws-sdk/util-endpoints': 3.433.0 + '@aws-sdk/util-user-agent-browser': 3.433.0 + '@aws-sdk/util-user-agent-node': 3.433.0 + '@smithy/config-resolver': 2.0.16 + '@smithy/fetch-http-handler': 2.2.4 + '@smithy/hash-node': 2.0.12 + '@smithy/invalid-dependency': 2.0.12 + '@smithy/middleware-content-length': 2.0.14 + '@smithy/middleware-endpoint': 2.1.3 + '@smithy/middleware-retry': 2.0.18 + '@smithy/middleware-serde': 2.0.12 + '@smithy/middleware-stack': 2.0.6 + '@smithy/node-config-provider': 2.1.3 + '@smithy/node-http-handler': 2.1.8 + '@smithy/property-provider': 2.0.13 + '@smithy/protocol-http': 3.0.8 + '@smithy/shared-ini-file-loader': 2.2.2 + '@smithy/smithy-client': 2.1.12 + '@smithy/types': 2.4.0 + '@smithy/url-parser': 2.0.12 + '@smithy/util-base64': 2.0.0 + '@smithy/util-body-length-browser': 2.0.0 + '@smithy/util-body-length-node': 2.1.0 + '@smithy/util-defaults-mode-browser': 2.0.16 + '@smithy/util-defaults-mode-node': 2.0.21 + '@smithy/util-retry': 2.0.5 + '@smithy/util-utf8': 2.0.0 + tslib: 2.6.0 + transitivePeerDependencies: + - aws-crt + dev: false + + /@aws-sdk/types@3.433.0: + resolution: {integrity: sha512-0jEE2mSrNDd8VGFjTc1otYrwYPIkzZJEIK90ZxisKvQ/EURGBhNzWn7ejWB9XCMFT6XumYLBR0V9qq5UPisWtA==} + engines: {node: '>=14.0.0'} + dependencies: + '@smithy/types': 2.4.0 + tslib: 2.6.0 + dev: false + + /@aws-sdk/util-endpoints@3.433.0: + resolution: {integrity: sha512-LFNUh9FH7RMtYjSjPGz9lAJQMzmJ3RcXISzc5X5k2R/9mNwMK7y1k2VAfvx+RbuDbll6xwsXlgv6QHcxVdF2zw==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-sdk/types': 3.433.0 + tslib: 2.6.0 + dev: false + + /@aws-sdk/util-locate-window@3.310.0: + resolution: {integrity: sha512-qo2t/vBTnoXpjKxlsC2e1gBrRm80M3bId27r0BRB2VniSSe7bL1mmzM+/HFtujm0iAxtPM+aLEflLJlJeDPg0w==} + engines: {node: '>=14.0.0'} + dependencies: + tslib: 2.6.0 + dev: false + + /@aws-sdk/util-user-agent-browser@3.433.0: + resolution: {integrity: sha512-2Cf/Lwvxbt5RXvWFXrFr49vXv0IddiUwrZoAiwhDYxvsh+BMnh+NUFot+ZQaTrk/8IPZVDeLPWZRdVy00iaVXQ==} + dependencies: + '@aws-sdk/types': 3.433.0 + '@smithy/types': 2.4.0 + bowser: 2.11.0 + tslib: 2.6.0 + dev: false + + /@aws-sdk/util-user-agent-node@3.433.0: + resolution: {integrity: sha512-yT1tO4MbbsUBLl5+S+jVv8wxiAtP5TKjKib9B2KQ2x0OtWWTrIf2o+IZK8va+zQqdV4MVMjezdxdE20hOdB4yQ==} + engines: {node: '>=14.0.0'} + peerDependencies: + aws-crt: '>=1.0.0' + peerDependenciesMeta: + aws-crt: + optional: true + dependencies: + '@aws-sdk/types': 3.433.0 + '@smithy/node-config-provider': 2.1.3 + '@smithy/types': 2.4.0 + tslib: 2.6.0 + dev: false + + /@aws-sdk/util-utf8-browser@3.259.0: + resolution: {integrity: sha512-UvFa/vR+e19XookZF8RzFZBrw2EUkQWxiBW0yYQAhvk3C+QVGl0H3ouca8LDBlBfQKXwmW3huo/59H8rwb1wJw==} + dependencies: + tslib: 2.6.0 + dev: false + /@babel/code-frame@7.22.5: resolution: {integrity: sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==} engines: {node: '>=6.9.0'} @@ -1580,6 +2019,352 @@ packages: '@sinonjs/commons': 3.0.0 dev: true + /@smithy/abort-controller@2.0.12: + resolution: {integrity: sha512-YIJyefe1mi3GxKdZxEBEuzYOeQ9xpYfqnFmWzojCssRAuR7ycxwpoRQgp965vuW426xUAQhCV5rCaWElQ7XsaA==} + engines: {node: '>=14.0.0'} + dependencies: + '@smithy/types': 2.4.0 + tslib: 2.6.0 + dev: false + + /@smithy/config-resolver@2.0.16: + resolution: {integrity: sha512-1k+FWHQDt2pfpXhJsOmNMmlAZ3NUQ98X5tYsjQhVGq+0X6cOBMhfh6Igd0IX3Ut6lEO6DQAdPMI/blNr3JZfMQ==} + engines: {node: '>=14.0.0'} + dependencies: + '@smithy/node-config-provider': 2.1.3 + '@smithy/types': 2.4.0 + '@smithy/util-config-provider': 2.0.0 + '@smithy/util-middleware': 2.0.5 + tslib: 2.6.0 + dev: false + + /@smithy/credential-provider-imds@2.0.18: + resolution: {integrity: sha512-QnPBi6D2zj6AHJdUTo5zXmk8vwHJ2bNevhcVned1y+TZz/OI5cizz5DsYNkqFUIDn8tBuEyKNgbmKVNhBbuY3g==} + engines: {node: '>=14.0.0'} + dependencies: + '@smithy/node-config-provider': 2.1.3 + '@smithy/property-provider': 2.0.13 + '@smithy/types': 2.4.0 + '@smithy/url-parser': 2.0.12 + tslib: 2.6.0 + dev: false + + /@smithy/eventstream-codec@2.0.12: + resolution: {integrity: sha512-ZZQLzHBJkbiAAdj2C5K+lBlYp/XJ+eH2uy+jgJgYIFW/o5AM59Hlj7zyI44/ZTDIQWmBxb3EFv/c5t44V8/g8A==} + dependencies: + '@aws-crypto/crc32': 3.0.0 + '@smithy/types': 2.4.0 + '@smithy/util-hex-encoding': 2.0.0 + tslib: 2.6.0 + dev: false + + /@smithy/fetch-http-handler@2.2.4: + resolution: {integrity: sha512-gIPRFEGi+c6V52eauGKrjDzPWF2Cu7Z1r5F8A3j2wcwz25sPG/t8kjsbEhli/tS/2zJp/ybCZXe4j4ro3yv/HA==} + dependencies: + '@smithy/protocol-http': 3.0.8 + '@smithy/querystring-builder': 2.0.12 + '@smithy/types': 2.4.0 + '@smithy/util-base64': 2.0.0 + tslib: 2.6.0 + dev: false + + /@smithy/hash-node@2.0.12: + resolution: {integrity: sha512-fDZnTr5j9t5qcbeJ037aMZXxMka13Znqwrgy3PAqYj6Dm3XHXHftTH3q+NWgayUxl1992GFtQt1RuEzRMy3NnQ==} + engines: {node: '>=14.0.0'} + dependencies: + '@smithy/types': 2.4.0 + '@smithy/util-buffer-from': 2.0.0 + '@smithy/util-utf8': 2.0.0 + tslib: 2.6.0 + dev: false + + /@smithy/invalid-dependency@2.0.12: + resolution: {integrity: sha512-p5Y+iMHV3SoEpy3VSR7mifbreHQwVSvHSAz/m4GdoXfOzKzaYC8hYv10Ks7Deblkf7lhas8U+lAp9ThbBM+ZXA==} + dependencies: + '@smithy/types': 2.4.0 + tslib: 2.6.0 + dev: false + + /@smithy/is-array-buffer@2.0.0: + resolution: {integrity: sha512-z3PjFjMyZNI98JFRJi/U0nGoLWMSJlDjAW4QUX2WNZLas5C0CmVV6LJ01JI0k90l7FvpmixjWxPFmENSClQ7ug==} + engines: {node: '>=14.0.0'} + dependencies: + tslib: 2.6.0 + dev: false + + /@smithy/middleware-content-length@2.0.14: + resolution: {integrity: sha512-poUNgKTw9XwPXfX9nEHpVgrMNVpaSMZbshqvPxFVoalF4wp6kRzYKOfdesSVectlQ51VtigoLfbXcdyPwvxgTg==} + engines: {node: '>=14.0.0'} + dependencies: + '@smithy/protocol-http': 3.0.8 + '@smithy/types': 2.4.0 + tslib: 2.6.0 + dev: false + + /@smithy/middleware-endpoint@2.1.3: + resolution: {integrity: sha512-ZrQ0/YX6hNVTxqMEHtEaDbDv6pNeEji/a5Vk3HuFC5R3ZY8lfoATyxmOGxBVYnF3NUvZLNC7umEv1WzWGWvCGQ==} + engines: {node: '>=14.0.0'} + dependencies: + '@smithy/middleware-serde': 2.0.12 + '@smithy/node-config-provider': 2.1.3 + '@smithy/shared-ini-file-loader': 2.2.2 + '@smithy/types': 2.4.0 + '@smithy/url-parser': 2.0.12 + '@smithy/util-middleware': 2.0.5 + tslib: 2.6.0 + dev: false + + /@smithy/middleware-retry@2.0.18: + resolution: {integrity: sha512-VyrHQRldGSb3v9oFOB5yPxmLT7U2sQic2ytylOnYlnsmVOLlFIaI6sW22c+w2675yq+XZ6HOuzV7x2OBYCWRNA==} + engines: {node: '>=14.0.0'} + dependencies: + '@smithy/node-config-provider': 2.1.3 + '@smithy/protocol-http': 3.0.8 + '@smithy/service-error-classification': 2.0.5 + '@smithy/types': 2.4.0 + '@smithy/util-middleware': 2.0.5 + '@smithy/util-retry': 2.0.5 + tslib: 2.6.0 + uuid: 8.3.2 + dev: false + + /@smithy/middleware-serde@2.0.12: + resolution: {integrity: sha512-IBeco157lIScecq2Z+n0gq56i4MTnfKxS7rbfrAORveDJgnbBAaEQgYqMqp/cYqKrpvEXcyTjwKHrBjCCIZh2A==} + engines: {node: '>=14.0.0'} + dependencies: + '@smithy/types': 2.4.0 + tslib: 2.6.0 + dev: false + + /@smithy/middleware-stack@2.0.6: + resolution: {integrity: sha512-YSvNZeOKWLJ0M/ycxwDIe2Ztkp6Qixmcml1ggsSv2fdHKGkBPhGrX5tMzPGMI1yyx55UEYBi2OB4s+RriXX48A==} + engines: {node: '>=14.0.0'} + dependencies: + '@smithy/types': 2.4.0 + tslib: 2.6.0 + dev: false + + /@smithy/node-config-provider@2.1.3: + resolution: {integrity: sha512-J6lXvRHGVnSX3n1PYi+e1L5HN73DkkJpUviV3Ebf+8wSaIjAf+eVNbzyvh/S5EQz7nf4KVfwbD5vdoZMAthAEQ==} + engines: {node: '>=14.0.0'} + dependencies: + '@smithy/property-provider': 2.0.13 + '@smithy/shared-ini-file-loader': 2.2.2 + '@smithy/types': 2.4.0 + tslib: 2.6.0 + dev: false + + /@smithy/node-http-handler@2.1.8: + resolution: {integrity: sha512-KZylM7Wff/So5SmCiwg2kQNXJ+RXgz34wkxS7WNwIUXuZrZZpY/jKJCK+ZaGyuESDu3TxcaY+zeYGJmnFKbQsA==} + engines: {node: '>=14.0.0'} + dependencies: + '@smithy/abort-controller': 2.0.12 + '@smithy/protocol-http': 3.0.8 + '@smithy/querystring-builder': 2.0.12 + '@smithy/types': 2.4.0 + tslib: 2.6.0 + dev: false + + /@smithy/property-provider@2.0.13: + resolution: {integrity: sha512-VJqUf2CbsQX6uUiC5dUPuoEATuFjkbkW3lJHbRnpk9EDC9X+iKqhfTK+WP+lve5EQ9TcCI1Q6R7hrg41FyC54w==} + engines: {node: '>=14.0.0'} + dependencies: + '@smithy/types': 2.4.0 + tslib: 2.6.0 + dev: false + + /@smithy/protocol-http@3.0.8: + resolution: {integrity: sha512-SHJvYeWq8q0FK8xHk+xjV9dzDUDjFMT+G1pZbV+XB6OVoac/FSVshlMNPeUJ8AmSkcDKHRu5vASnRqZHgD3qhw==} + engines: {node: '>=14.0.0'} + dependencies: + '@smithy/types': 2.4.0 + tslib: 2.6.0 + dev: false + + /@smithy/querystring-builder@2.0.12: + resolution: {integrity: sha512-cDbF07IuCjiN8CdGvPzfJjXIrmDSelScRfyJYrYBNBbKl2+k7QD/KqiHhtRyEKgID5mmEVrV6KE6L/iPJ98sFw==} + engines: {node: '>=14.0.0'} + dependencies: + '@smithy/types': 2.4.0 + '@smithy/util-uri-escape': 2.0.0 + tslib: 2.6.0 + dev: false + + /@smithy/querystring-parser@2.0.12: + resolution: {integrity: sha512-fytyTcXaMzPBuNtPlhj5v6dbl4bJAnwKZFyyItAGt4Tgm9HFPZNo7a9r1SKPr/qdxUEBzvL9Rh+B9SkTX3kFxg==} + engines: {node: '>=14.0.0'} + dependencies: + '@smithy/types': 2.4.0 + tslib: 2.6.0 + dev: false + + /@smithy/service-error-classification@2.0.5: + resolution: {integrity: sha512-M0SeJnEgD2ywJyV99Fb1yKFzmxDe9JfpJiYTVSRMyRLc467BPU0qsuuDPzMCdB1mU8M8u1rVOdkqdoyFN8UFTw==} + engines: {node: '>=14.0.0'} + dependencies: + '@smithy/types': 2.4.0 + dev: false + + /@smithy/shared-ini-file-loader@2.2.2: + resolution: {integrity: sha512-noyQUPn7b1M8uB0GEXc/Zyxq+5K2b7aaqWnLp+hgJ7+xu/FCvtyWy5eWLDjQEsHnAet2IZhS5QF8872OR69uNg==} + engines: {node: '>=14.0.0'} + dependencies: + '@smithy/types': 2.4.0 + tslib: 2.6.0 + dev: false + + /@smithy/signature-v4@2.0.12: + resolution: {integrity: sha512-6Kc2lCZEVmb1nNYngyNbWpq0d82OZwITH11SW/Q0U6PX5fH7B2cIcFe7o6eGEFPkTZTP8itTzmYiGcECL0D0Lw==} + engines: {node: '>=14.0.0'} + dependencies: + '@smithy/eventstream-codec': 2.0.12 + '@smithy/is-array-buffer': 2.0.0 + '@smithy/types': 2.4.0 + '@smithy/util-hex-encoding': 2.0.0 + '@smithy/util-middleware': 2.0.5 + '@smithy/util-uri-escape': 2.0.0 + '@smithy/util-utf8': 2.0.0 + tslib: 2.6.0 + dev: false + + /@smithy/smithy-client@2.1.12: + resolution: {integrity: sha512-XXqhridfkKnpj+lt8vM6HRlZbqUAqBjVC74JIi13F/AYQd/zTj9SOyGfxnbp4mjY9q28LityxIuV8CTinr9r5w==} + engines: {node: '>=14.0.0'} + dependencies: + '@smithy/middleware-stack': 2.0.6 + '@smithy/types': 2.4.0 + '@smithy/util-stream': 2.0.17 + tslib: 2.6.0 + dev: false + + /@smithy/types@2.4.0: + resolution: {integrity: sha512-iH1Xz68FWlmBJ9vvYeHifVMWJf82ONx+OybPW8ZGf5wnEv2S0UXcU4zwlwJkRXuLKpcSLHrraHbn2ucdVXLb4g==} + engines: {node: '>=14.0.0'} + dependencies: + tslib: 2.6.0 + dev: false + + /@smithy/url-parser@2.0.12: + resolution: {integrity: sha512-qgkW2mZqRvlNUcBkxYB/gYacRaAdck77Dk3/g2iw0S9F0EYthIS3loGfly8AwoWpIvHKhkTsCXXQfzksgZ4zIA==} + dependencies: + '@smithy/querystring-parser': 2.0.12 + '@smithy/types': 2.4.0 + tslib: 2.6.0 + dev: false + + /@smithy/util-base64@2.0.0: + resolution: {integrity: sha512-Zb1E4xx+m5Lud8bbeYi5FkcMJMnn+1WUnJF3qD7rAdXpaL7UjkFQLdmW5fHadoKbdHpwH9vSR8EyTJFHJs++tA==} + engines: {node: '>=14.0.0'} + dependencies: + '@smithy/util-buffer-from': 2.0.0 + tslib: 2.6.0 + dev: false + + /@smithy/util-body-length-browser@2.0.0: + resolution: {integrity: sha512-JdDuS4ircJt+FDnaQj88TzZY3+njZ6O+D3uakS32f2VNnDo3vyEuNdBOh/oFd8Df1zSZOuH1HEChk2AOYDezZg==} + dependencies: + tslib: 2.6.0 + dev: false + + /@smithy/util-body-length-node@2.1.0: + resolution: {integrity: sha512-/li0/kj/y3fQ3vyzn36NTLGmUwAICb7Jbe/CsWCktW363gh1MOcpEcSO3mJ344Gv2dqz8YJCLQpb6hju/0qOWw==} + engines: {node: '>=14.0.0'} + dependencies: + tslib: 2.6.0 + dev: false + + /@smithy/util-buffer-from@2.0.0: + resolution: {integrity: sha512-/YNnLoHsR+4W4Vf2wL5lGv0ksg8Bmk3GEGxn2vEQt52AQaPSCuaO5PM5VM7lP1K9qHRKHwrPGktqVoAHKWHxzw==} + engines: {node: '>=14.0.0'} + dependencies: + '@smithy/is-array-buffer': 2.0.0 + tslib: 2.6.0 + dev: false + + /@smithy/util-config-provider@2.0.0: + resolution: {integrity: sha512-xCQ6UapcIWKxXHEU4Mcs2s7LcFQRiU3XEluM2WcCjjBtQkUN71Tb+ydGmJFPxMUrW/GWMgQEEGipLym4XG0jZg==} + engines: {node: '>=14.0.0'} + dependencies: + tslib: 2.6.0 + dev: false + + /@smithy/util-defaults-mode-browser@2.0.16: + resolution: {integrity: sha512-Uv5Cu8nVkuvLn0puX+R9zWbSNpLIR3AxUlPoLJ7hC5lvir8B2WVqVEkJLwtixKAncVLasnTVjPDCidtAUTGEQw==} + engines: {node: '>= 10.0.0'} + dependencies: + '@smithy/property-provider': 2.0.13 + '@smithy/smithy-client': 2.1.12 + '@smithy/types': 2.4.0 + bowser: 2.11.0 + tslib: 2.6.0 + dev: false + + /@smithy/util-defaults-mode-node@2.0.21: + resolution: {integrity: sha512-cUEsttVZ79B7Al2rWK2FW03HBpD9LyuqFtm+1qFty5u9sHSdesr215gS2Ln53fTopNiPgeXpdoM3IgjvIO0rJw==} + engines: {node: '>= 10.0.0'} + dependencies: + '@smithy/config-resolver': 2.0.16 + '@smithy/credential-provider-imds': 2.0.18 + '@smithy/node-config-provider': 2.1.3 + '@smithy/property-provider': 2.0.13 + '@smithy/smithy-client': 2.1.12 + '@smithy/types': 2.4.0 + tslib: 2.6.0 + dev: false + + /@smithy/util-hex-encoding@2.0.0: + resolution: {integrity: sha512-c5xY+NUnFqG6d7HFh1IFfrm3mGl29lC+vF+geHv4ToiuJCBmIfzx6IeHLg+OgRdPFKDXIw6pvi+p3CsscaMcMA==} + engines: {node: '>=14.0.0'} + dependencies: + tslib: 2.6.0 + dev: false + + /@smithy/util-middleware@2.0.5: + resolution: {integrity: sha512-1lyT3TcaMJQe+OFfVI+TlomDkPuVzb27NZYdYtmSTltVmLaUjdCyt4KE+OH1CnhZKsz4/cdCL420Lg9UH5Z2Mw==} + engines: {node: '>=14.0.0'} + dependencies: + '@smithy/types': 2.4.0 + tslib: 2.6.0 + dev: false + + /@smithy/util-retry@2.0.5: + resolution: {integrity: sha512-x3t1+MQAJ6QONk3GTbJNcugCFDVJ+Bkro5YqQQK1EyVesajNDqxFtCx9WdOFNGm/Cbm7tUdwVEmfKQOJoU2Vtw==} + engines: {node: '>= 14.0.0'} + dependencies: + '@smithy/service-error-classification': 2.0.5 + '@smithy/types': 2.4.0 + tslib: 2.6.0 + dev: false + + /@smithy/util-stream@2.0.17: + resolution: {integrity: sha512-fP/ZQ27rRvHsqItds8yB7jerwMpZFTL3QqbQbidUiG0+mttMoKdP0ZqnvM8UK5q0/dfc3/pN7g4XKPXOU7oRWw==} + engines: {node: '>=14.0.0'} + dependencies: + '@smithy/fetch-http-handler': 2.2.4 + '@smithy/node-http-handler': 2.1.8 + '@smithy/types': 2.4.0 + '@smithy/util-base64': 2.0.0 + '@smithy/util-buffer-from': 2.0.0 + '@smithy/util-hex-encoding': 2.0.0 + '@smithy/util-utf8': 2.0.0 + tslib: 2.6.0 + dev: false + + /@smithy/util-uri-escape@2.0.0: + resolution: {integrity: sha512-ebkxsqinSdEooQduuk9CbKcI+wheijxEb3utGXkCoYQkJnwTnLbH1JXGimJtUkQwNQbsbuYwG2+aFVyZf5TLaw==} + engines: {node: '>=14.0.0'} + dependencies: + tslib: 2.6.0 + dev: false + + /@smithy/util-utf8@2.0.0: + resolution: {integrity: sha512-rctU1VkziY84n5OXe3bPNpKR001ZCME2JCaBBFgtiM2hfKbHFudc/BkMuPab8hRbLd0j3vbnBTTZ1igBf0wgiQ==} + engines: {node: '>=14.0.0'} + dependencies: + '@smithy/util-buffer-from': 2.0.0 + tslib: 2.6.0 + dev: false + /@tsconfig/node10@1.0.9: resolution: {integrity: sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==} dev: true @@ -2415,6 +3200,10 @@ packages: transitivePeerDependencies: - supports-color + /bowser@2.11.0: + resolution: {integrity: sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==} + dev: false + /brace-expansion@1.1.11: resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} dependencies: @@ -3261,6 +4050,13 @@ packages: resolution: {integrity: sha512-VhXlQgj9ioXCqGstD37E/HBeqEGV/qOD/kmbVG8h5xKBYvM1L3lR1Zn4555cQ8GkYbJa8aJSipLPndE1k6zK2w==} dev: false + /fast-xml-parser@4.2.5: + resolution: {integrity: sha512-B9/wizE4WngqQftFPmdaMYlXoJlJOYxGQOanC77fq9k8+Z0v5dDSVh+3glErdIROP//s/jgb7ZuxKfB8nVyo0g==} + hasBin: true + dependencies: + strnum: 1.0.5 + dev: false + /fastq@1.15.0: resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==} dependencies: @@ -5539,6 +6335,10 @@ packages: engines: {node: '>=8'} dev: true + /strnum@1.0.5: + resolution: {integrity: sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==} + dev: false + /subscriptions-transport-ws@0.11.0(graphql@16.8.1): resolution: {integrity: sha512-8D4C6DIH5tGiAIpp5I0wD/xRlNiZAPGHygzCe7VzyzUoxHtawzjNAY9SUTXU05/EY2NMY9/9GF0ycizkXr1CWQ==} deprecated: The `subscriptions-transport-ws` package is no longer maintained. We recommend you use `graphql-ws` instead. For help migrating Apollo software to `graphql-ws`, see https://www.apollographql.com/docs/apollo-server/data/subscriptions/#switching-from-subscriptions-transport-ws For general help using `graphql-ws`, see https://github.com/enisdenjo/graphql-ws/blob/master/README.md @@ -5848,6 +6648,10 @@ packages: strip-bom: 3.0.0 dev: true + /tslib@1.14.1: + resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + dev: false + /tslib@2.5.3: resolution: {integrity: sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==} @@ -5943,6 +6747,11 @@ packages: resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} engines: {node: '>= 0.4.0'} + /uuid@8.3.2: + resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} + hasBin: true + dev: false + /uuid@9.0.0: resolution: {integrity: sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==} hasBin: true diff --git a/app/src/app.module.ts b/app/src/app.module.ts index 6f765f7c..7402a08a 100644 --- a/app/src/app.module.ts +++ b/app/src/app.module.ts @@ -10,6 +10,7 @@ import { StatAuthGuard } from './auth/statAuthGuard'; import { CacheDecoratorOnReturnModule } from './cache/decrators/onReturn/cache.decorator.onReturn.module'; import { ShallowStore } from './cache/shallowStore/cache.shallowStore'; import { API_CONFIG } from './config/api'; +import { AWS_CONFIG } from './config/aws'; import { CDN_CONFIG } from './config/cdn'; import { DATABASE_CONFIG } from './config/database'; import { FT_CLIENT_CONFIG } from './config/ftClient'; @@ -37,7 +38,12 @@ import { TeamInfoModule } from './page/teamInfo/teamInfo.module'; imports: [ ConfigModule.forRoot({ isGlobal: true, - envFilePath: ['../env/.env.prod', '../env/.env.dev', '../env/.env.local'], + envFilePath: [ + '../env/.env.common', + '../env/.env.prod', + '../env/.env.dev', + '../env/.env.local', + ], load: [ DATABASE_CONFIG, FT_CLIENT_CONFIG, @@ -46,6 +52,7 @@ import { TeamInfoModule } from './page/teamInfo/teamInfo.module'; RUNTIME_CONFIG, CDN_CONFIG, API_CONFIG, + AWS_CONFIG, ], }), MongooseRootModule, diff --git a/app/src/config/aws.ts b/app/src/config/aws.ts new file mode 100644 index 00000000..5a985b37 --- /dev/null +++ b/app/src/config/aws.ts @@ -0,0 +1,28 @@ +import { registerAs } from '@nestjs/config'; +import { findEnvByKey } from './util/findEnvByKey'; + +type AwsConfig = { + REGION: string; + AWS_PROD_FT_CLIENT_SECRET_ID: string; + AWS_DEV_FT_CLIENT_SECRET_ID: string; + AWS_LOCAL_FT_CLIENT_SECRET_ID: string; + AWS_FT_CLIENT_SECRET_KEY: string; +}; + +const AWS_FT_CLIENT_SECRET_KEY = 'CLIENT_SECRET'; + +export type AwsFtClientSecret = { + [AWS_FT_CLIENT_SECRET_KEY]: string; +}; + +export const AWS_CONFIG = registerAs('aws', (): AwsConfig => { + return { + REGION: 'ap-northeast-2', + AWS_PROD_FT_CLIENT_SECRET_ID: findEnvByKey('AWS_PROD_FT_CLIENT_SECRET_ID'), + AWS_DEV_FT_CLIENT_SECRET_ID: findEnvByKey('AWS_DEV_FT_CLIENT_SECRET_ID'), + AWS_LOCAL_FT_CLIENT_SECRET_ID: findEnvByKey( + 'AWS_LOCAL_FT_CLIENT_SECRET_ID', + ), + AWS_FT_CLIENT_SECRET_KEY, + }; +}); diff --git a/app/src/config/ftClient.ts b/app/src/config/ftClient.ts index f75e2cb9..a27b4400 100644 --- a/app/src/config/ftClient.ts +++ b/app/src/config/ftClient.ts @@ -3,13 +3,10 @@ import { findEnvByKey } from './util/findEnvByKey'; type FtClientConfig = { ID: string; - SECRET: string; REDIRECT_URI: string; DEV_ID: string; - DEV_SECRET: string; DEV_REDIRECT_URI: string; LOCAL_ID: string; - LOCAL_SECRET: string; LOCAL_REDIRECT_URI: string; INTRA_TOKEN_URL: string; INTRA_ME_URL: string; @@ -20,13 +17,10 @@ export const FT_CLIENT_CONFIG = registerAs( () => ({ ID: findEnvByKey('CLIENT_ID'), - SECRET: findEnvByKey('CLIENT_SECRET'), REDIRECT_URI: findEnvByKey('REDIRECT_URI'), DEV_ID: findEnvByKey('DEV_CLIENT_ID'), - DEV_SECRET: findEnvByKey('DEV_CLIENT_SECRET'), DEV_REDIRECT_URI: findEnvByKey('DEV_REDIRECT_URI'), LOCAL_ID: findEnvByKey('LOCAL_CLIENT_ID'), - LOCAL_SECRET: findEnvByKey('LOCAL_CLIENT_SECRET'), LOCAL_REDIRECT_URI: findEnvByKey('LOCAL_REDIRECT_URI'), INTRA_TOKEN_URL: findEnvByKey('INTRA_TOKEN_URL'), INTRA_ME_URL: findEnvByKey('INTRA_ME_URL'), diff --git a/app/src/login/login.module.ts b/app/src/login/login.module.ts index 1d65427e..30531dce 100644 --- a/app/src/login/login.module.ts +++ b/app/src/login/login.module.ts @@ -5,6 +5,7 @@ import { JwtModule } from '@nestjs/jwt'; import { TokenModule } from 'src/auth/token/token.module'; import { JWT_CONFIG } from 'src/config/jwt'; import { AccountModule } from 'src/login/account/account.module'; +import { RemoteConfigModule } from 'src/remoteConfig/remoteConfig.module'; import { LoginResolver } from './login.resolver'; import { LoginService } from './login.service'; @@ -21,6 +22,7 @@ import { LoginService } from './login.service'; }), AccountModule, TokenModule, + RemoteConfigModule, HttpModule, ], providers: [LoginResolver, LoginService], diff --git a/app/src/login/login.service.ts b/app/src/login/login.service.ts index fb32ee80..c034975b 100644 --- a/app/src/login/login.service.ts +++ b/app/src/login/login.service.ts @@ -17,6 +17,7 @@ import mongoose from 'mongoose'; import { lastValueFrom } from 'rxjs'; import type { token } from 'src/auth/token/db/token.database.schema'; import { TokenService } from 'src/auth/token/token.service'; +import { AWS_CONFIG, AwsFtClientSecret } from 'src/config/aws'; import { FT_CLIENT_CONFIG } from 'src/config/ftClient'; import { GOOGLE_CLIENT_CONFIG } from 'src/config/googleClient'; import { JWT_CONFIG } from 'src/config/jwt'; @@ -24,6 +25,7 @@ import { RUNTIME_CONFIG } from 'src/config/runtime'; import { DateWrapper } from 'src/dateWrapper/dateWrapper'; import { HttpExceptionFilter } from 'src/http-exception.filter'; import { AccountService } from 'src/login/account/account.service'; +import { RemoteConfigService } from 'src/remoteConfig/remoteConfig.service'; import type { account } from './account/db/account.database.schema'; import type { GoogleLoginInput } from './dtos/login.dto'; import type { @@ -47,6 +49,9 @@ export class LoginService { >, @Inject(RUNTIME_CONFIG.KEY) private readonly runtimeConfig: ConfigType, + @Inject(AWS_CONFIG.KEY) + private readonly awsConfig: ConfigType, + private readonly remoteConfigService: RemoteConfigService, private readonly accountService: AccountService, private readonly httpService: HttpService, private readonly jwtService: JwtService, @@ -108,40 +113,37 @@ export class LoginService { */ private async getFtUser(ftCode: string): Promise { if (this.runtimeConfig.PROD) { - try { - return await this.requestFtOAuth({ - clientId: this.ftClientConfig.ID, - clientSecret: this.ftClientConfig.SECRET, - redirectURI: this.ftClientConfig.REDIRECT_URI, - ftCode, - }); - } catch (e) { - console.error(e); - try { - return await this.requestFtOAuth({ - clientId: this.ftClientConfig.ID, - clientSecret: this.ftClientConfig.SECRET, - redirectURI: this.ftClientConfig.REDIRECT_URI, - ftCode, - }); - } catch (e) { - console.error(e); - throw e; - } - } + const clientSecret = await this.fetchFtClientSecret( + this.awsConfig.AWS_PROD_FT_CLIENT_SECRET_ID, + ); + + return await this.requestFtOAuth({ + clientId: this.ftClientConfig.ID, + clientSecret, + redirectURI: this.ftClientConfig.REDIRECT_URI, + ftCode, + }); } else { try { + const clientSecret = await this.fetchFtClientSecret( + this.awsConfig.AWS_LOCAL_FT_CLIENT_SECRET_ID, + ); + return await this.requestFtOAuth({ clientId: this.ftClientConfig.LOCAL_ID, - clientSecret: this.ftClientConfig.LOCAL_SECRET, + clientSecret, redirectURI: this.ftClientConfig.LOCAL_REDIRECT_URI, ftCode, }); } catch (e) { if (e instanceof BadRequestException) { + const clientSecret = await this.fetchFtClientSecret( + this.awsConfig.AWS_DEV_FT_CLIENT_SECRET_ID, + ); + return await this.requestFtOAuth({ clientId: this.ftClientConfig.DEV_ID, - clientSecret: this.ftClientConfig.DEV_SECRET, + clientSecret, redirectURI: this.ftClientConfig.DEV_REDIRECT_URI, ftCode, }); @@ -152,6 +154,17 @@ export class LoginService { } } + private async fetchFtClientSecret(secretId: string): Promise { + try { + const clientSecret = await this.remoteConfigService.fetchConfig(secretId); + + return (clientSecret as AwsFtClientSecret).CLIENT_SECRET; + } catch (e) { + console.error('wrong aws secrets manager config', e); + throw new InternalServerErrorException(); + } + } + /** * * @throws {BadRequestException} ftCode가 유효하지 않은 경우 @@ -176,32 +189,45 @@ export class LoginService { searchParams.set('code', ftCode); searchParams.set('redirect_uri', redirectURI); - let accessToken: string; + let accessToken: string | undefined = undefined; - try { - const authResult = await lastValueFrom( - this.httpService.post<{ access_token: string }>( - this.ftClientConfig.INTRA_TOKEN_URL, - searchParams, - ), - ); + for (let i = 0; i < 2; i++) { + try { + const authResult = await lastValueFrom( + this.httpService.post<{ access_token: string }>( + this.ftClientConfig.INTRA_TOKEN_URL, + searchParams, + ), + ); - accessToken = authResult.data.access_token; - } catch { - throw new BadRequestException('42 code error'); + accessToken = authResult.data.access_token; + + break; + } catch {} } - try { - const userInfo = await lastValueFrom( - this.httpService.get<{ id: number }>(this.ftClientConfig.INTRA_ME_URL, { - headers: { Authorization: `Bearer ${accessToken}` }, - }), - ); + if (!accessToken) { + console.error('42 code error'); + throw new BadRequestException('42 code error'); + } - return userInfo.data.id; - } catch { - throw new InternalServerErrorException('42 server error'); + for (let i = 0; i < 2; i++) { + try { + const userInfo = await lastValueFrom( + this.httpService.get<{ id: number }>( + this.ftClientConfig.INTRA_ME_URL, + { + headers: { Authorization: `Bearer ${accessToken}` }, + }, + ), + ); + + return userInfo.data.id; + } catch {} } + + console.error('42 server error'); + throw new InternalServerErrorException('42 server error'); } async generateTokenPair(userId: number): Promise> { diff --git a/app/src/remoteConfig/remoteConfig.module.ts b/app/src/remoteConfig/remoteConfig.module.ts new file mode 100644 index 00000000..abbb2286 --- /dev/null +++ b/app/src/remoteConfig/remoteConfig.module.ts @@ -0,0 +1,9 @@ +import { Module } from '@nestjs/common'; +import { RemoteConfigService } from './remoteConfig.service'; + +@Module({ + providers: [RemoteConfigService], + exports: [RemoteConfigService], +}) +// eslint-disable-next-line +export class RemoteConfigModule {} diff --git a/app/src/remoteConfig/remoteConfig.service.ts b/app/src/remoteConfig/remoteConfig.service.ts new file mode 100644 index 00000000..e8b6f9cb --- /dev/null +++ b/app/src/remoteConfig/remoteConfig.service.ts @@ -0,0 +1,44 @@ +import { + GetSecretValueCommand, + SecretsManagerClient, +} from '@aws-sdk/client-secrets-manager'; +import { + Inject, + Injectable, + InternalServerErrorException, +} from '@nestjs/common'; +import type { ConfigType } from '@nestjs/config'; +import { CacheOnReturn } from 'src/cache/decrators/onReturn/cache.decorator.onReturn.symbol'; +import { AWS_CONFIG } from 'src/config/aws'; +import { DateWrapper } from 'src/dateWrapper/dateWrapper'; + +@Injectable() +export class RemoteConfigService { + private readonly secretsManager: SecretsManagerClient; + + constructor( + @Inject(AWS_CONFIG.KEY) + private readonly awsConfig: ConfigType, + ) { + this.secretsManager = new SecretsManagerClient({ + region: this.awsConfig.REGION, + }); + } + + @CacheOnReturn(DateWrapper.MIN * 5) + async fetchConfig(secretId: string): Promise { + const response = await this.secretsManager.send( + new GetSecretValueCommand({ + SecretId: secretId, + }), + ); + + if (!response.SecretString) { + throw new InternalServerErrorException( + 'wrong aws secrets manager config', + ); + } + + return JSON.parse(response.SecretString); + } +} diff --git a/env b/env index 20a42df6..88b09a6c 160000 --- a/env +++ b/env @@ -1 +1 @@ -Subproject commit 20a42df627acdea6a9ff4bfaa18000e893be668d +Subproject commit 88b09a6c5402fc70221de631d4bc1d9ea0fa409e