diff --git a/api/package.json b/api/package.json index 43e16e3c3f4..8c6e2f96be3 100644 --- a/api/package.json +++ b/api/package.json @@ -4,6 +4,7 @@ "url": "https://github.com/freeCodeCamp/freeCodeCamp/issues" }, "dependencies": { + "@aws-sdk/client-ses": "^3.347.1", "@fastify/cookie": "^8.3.0", "@fastify/csrf-protection": "6.3.0", "@fastify/middie": "8.3", @@ -24,6 +25,7 @@ "mongodb": "^4.16.0", "nanoid": "3", "nodemon": "2.0.22", + "nodemailer": "^6.9.3", "query-string": "^7.1.3" }, "description": "The freeCodeCamp.org open-source codebase and curriculum", @@ -32,6 +34,7 @@ "@types/bad-words": "^3.0.1", "@types/express-session": "1.17.7", "@types/jsonwebtoken": "^9.0.2", + "@types/nodemailer": "^6.4.8", "@types/supertest": "2.0.12", "dotenv-cli": "7.2.1", "jest": "29.6.2", diff --git a/api/src/app.ts b/api/src/app.ts index 49132c8a1cc..526d0968c2b 100644 --- a/api/src/app.ts +++ b/api/src/app.ts @@ -22,6 +22,9 @@ import addFormats from 'ajv-formats'; import cors from './plugins/cors'; import jwtAuthz from './plugins/fastify-jwt-authz'; +import { NodemailerProvider } from './plugins/mail-providers/nodemailer'; +import { SESProvider } from './plugins/mail-providers/ses'; +import mailer from './plugins/mailer'; import security from './plugins/security'; import sessionAuth from './plugins/session-auth'; import redirectWithMessage from './plugins/redirect-with-message'; @@ -41,7 +44,8 @@ import { FCC_ENABLE_SWAGGER_UI, API_LOCATION, FCC_ENABLE_DEV_LOGIN_MODE, - SENTRY_DSN + SENTRY_DSN, + EMAIL_PROVIDER } from './utils/env'; import { challengeRoutes } from './routes/challenge'; import { userRoutes } from './routes/user'; @@ -148,6 +152,10 @@ export const build = async ( }) }); + const provider = + EMAIL_PROVIDER === 'ses' ? new SESProvider() : new NodemailerProvider(); + void fastify.register(mailer, { provider }); + // Swagger plugin if (FCC_ENABLE_SWAGGER_UI) { void fastify.register(fastifySwagger, { diff --git a/api/src/plugins/mail-providers/nodemailer.ts b/api/src/plugins/mail-providers/nodemailer.ts new file mode 100644 index 00000000000..2b64812f2a5 --- /dev/null +++ b/api/src/plugins/mail-providers/nodemailer.ts @@ -0,0 +1,48 @@ +import nodemailer, { Transporter } from 'nodemailer'; + +import { MailProvider, SendEmailArgs } from '../mailer'; + +/** + * NodemailerProvider is a wrapper around nodemailer that provides a clean + * interface for sending email. + */ +export class NodemailerProvider implements MailProvider { + private transporter: Transporter; + + /** + * Sets up nodemailer, with hardcodeded configuration. This is intended for + * use in development. + */ + constructor() { + this.transporter = nodemailer.createTransport({ + host: 'localhost', + secure: false, + port: 1025, + auth: { + user: 'test', + pass: 'test' + }, + tls: { + rejectUnauthorized: false + } + }); + } + + /** + * Sends an email using nodemailer. + * + * @param param Email options. + * @param param.to Email address to send to. + * @param param.from Email address to send from. + * @param param.subject Email subject. + * @param param.text Email body (raw text only). + */ + async send({ to, from, subject, text }: SendEmailArgs) { + await this.transporter.sendMail({ + from, + to, + subject, + text + }); + } +} diff --git a/api/src/plugins/mail-providers/ses.ts b/api/src/plugins/mail-providers/ses.ts new file mode 100644 index 00000000000..63e22bacd1d --- /dev/null +++ b/api/src/plugins/mail-providers/ses.ts @@ -0,0 +1,65 @@ +import { + SESClient, + SESClientConfig, + SendEmailCommand +} from '@aws-sdk/client-ses'; + +import { MailProvider, SendEmailArgs } from '../mailer'; +import { SES_ID, SES_SECRET, SES_REGION } from '../../utils/env'; + +/** + * SESProvider is a wrapper around nodemailer that provides a clean interface + * for sending email. + */ +export class SESProvider implements MailProvider { + private client: SESClient; + + /** + * Sets up SESClient and configures it with keys pulled from environment. + */ + constructor() { + if (!SES_ID || !SES_SECRET || !SES_REGION) { + throw new Error('Email service is set to SES but missing required keys.'); + } + const awsConfig: SESClientConfig = { + credentials: { + accessKeyId: SES_ID, + secretAccessKey: SES_SECRET + }, + region: SES_REGION + }; + this.client = new SESClient(awsConfig); + } + + /** + * Sends an email using the SES sdk. + * + * @param param Email options. + * @param param.to Email address to send to. + * @param param.from Email address to send from. + * @param param.subject Email subject. + * @param param.text Email body (raw text only). + */ + async send({ to, from, subject, text }: SendEmailArgs) { + const opts = new SendEmailCommand({ + Destination: { + ToAddresses: [to] + }, + Message: { + Subject: { + Data: subject, + Charset: 'UTF-8' + }, + Body: { + Text: { + Charset: 'UTF-8', + Data: text + } + } + }, + Source: from + }); + + await this.client.send(opts); + } +} diff --git a/api/src/plugins/mailer.test.ts b/api/src/plugins/mailer.test.ts new file mode 100644 index 00000000000..eab43b9fa1d --- /dev/null +++ b/api/src/plugins/mailer.test.ts @@ -0,0 +1,29 @@ +import Fastify from 'fastify'; + +import mailer from './mailer'; + +describe('mailer', () => { + it('should throw if not given a provider', async () => { + const fastify = Fastify(); + await expect(fastify.register(mailer)).rejects.toThrow( + "The mailer plugin must be passed a provider via register's options." + ); + }); + + it('should send an email via the provider', async () => { + const fastify = Fastify(); + const send = jest.fn(); + await fastify.register(mailer, { provider: { send } }); + + const data = { + to: 'test@add.ress', + from: 'team@freecodecamp.org', + subject: 'test', + text: 'test' + }; + + await fastify.sendEmail(data); + + expect(send).toHaveBeenCalledWith(data); + }); +}); diff --git a/api/src/plugins/mailer.ts b/api/src/plugins/mailer.ts new file mode 100644 index 00000000000..ce58978c0f7 --- /dev/null +++ b/api/src/plugins/mailer.ts @@ -0,0 +1,46 @@ +import { FastifyPluginCallback } from 'fastify'; + +import fp from 'fastify-plugin'; + +declare module 'fastify' { + interface FastifyInstance { + sendEmail: SendEmail; + } +} + +export type SendEmailArgs = { + to: string; + from: string; + subject: string; + text: string; +}; + +type SendEmail = (args: SendEmailArgs) => Promise; + +export interface MailProvider { + send: SendEmail; +} + +const plugin: FastifyPluginCallback<{ provider: MailProvider }> = ( + fastify, + options, + done +) => { + const { provider } = options; + + if (!provider) + return done( + Error( + "The mailer plugin must be passed a provider via register's options." + ) + ); + + fastify.decorate( + 'sendEmail', + async (args: SendEmailArgs) => await provider.send(args) + ); + + done(); +}; + +export default fp(plugin); diff --git a/api/src/utils/env.ts b/api/src/utils/env.ts index 93a0a675699..8d7a3e1b2d2 100644 --- a/api/src/utils/env.ts +++ b/api/src/utils/env.ts @@ -22,9 +22,15 @@ function isAllowedEnv(env: string): env is 'development' | 'production' { return ['development', 'production'].includes(env); } +function isAllowedProvider(provider: string): provider is 'ses' | 'nodemailer' { + return ['ses', 'nodemailer'].includes(provider); +} + assert.ok(process.env.HOME_LOCATION); assert.ok(process.env.FREECODECAMP_NODE_ENV); assert.ok(isAllowedEnv(process.env.FREECODECAMP_NODE_ENV)); +assert.ok(process.env.EMAIL_PROVIDER); +assert.ok(isAllowedProvider(process.env.EMAIL_PROVIDER)); assert.ok(process.env.AUTH0_DOMAIN); assert.ok(process.env.AUTH0_AUDIENCE); assert.ok(process.env.API_LOCATION); @@ -34,20 +40,30 @@ assert.ok(process.env.FCC_ENABLE_DEV_LOGIN_MODE); assert.ok(process.env.JWT_SECRET); if (process.env.FREECODECAMP_NODE_ENV !== 'development') { + assert.ok(process.env.SES_ID); + assert.ok(process.env.SES_SECRET); + assert.notEqual( + process.env.SES_SECRET, + 'ses_secret_from_aws', + 'The SES secret should be changed from the default value.' + ); + assert.ok(process.env.SES_REGION); assert.ok(process.env.COOKIE_DOMAIN); assert.ok(process.env.PORT); assert.ok(process.env.MONGOHQ_URL); assert.ok(process.env.SENTRY_DSN); - assert.notEqual( - process.env.JWT_SECRET, - 'a_jwt_secret', - 'The JWT secret should be changed from the default value.' - ); + // The following values can exist in development, but production-like + // environments need to override the defaults. assert.notEqual( process.env.SENTRY_DSN, 'dsn_from_sentry_dashboard', `The DSN from Sentry's dashboard should be used.` ); + assert.notEqual( + process.env.JWT_SECRET, + 'a_jwt_secret', + 'The JWT secret should be changed from the default value.' + ); assert.notEqual( process.env.SESSION_SECRET, 'a_thirty_two_plus_character_session_secret', @@ -57,6 +73,10 @@ if (process.env.FREECODECAMP_NODE_ENV !== 'development') { process.env.FCC_ENABLE_DEV_LOGIN_MODE !== 'true', 'Dev login mode MUST be disabled in production.' ); + assert.ok( + process.env.EMAIL_PROVIDER === 'ses', + 'SES MUST be used in production.' + ); } export const HOME_LOCATION = process.env.HOME_LOCATION; @@ -79,3 +99,7 @@ export const SENTRY_DSN = : process.env.SENTRY_DSN; export const COOKIE_DOMAIN = process.env.COOKIE_DOMAIN || 'localhost'; export const JWT_SECRET = process.env.JWT_SECRET; +export const SES_ID = process.env.SES_ID; +export const SES_SECRET = process.env.SES_SECRET; +export const SES_REGION = process.env.SES_REGION; +export const EMAIL_PROVIDER = process.env.EMAIL_PROVIDER; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 414c4f7f14f..dd618a99ed3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -174,6 +174,9 @@ importers: api: dependencies: + '@aws-sdk/client-ses': + specifier: ^3.347.1 + version: 3.347.1 '@fastify/cookie': specifier: ^8.3.0 version: 8.3.0 @@ -231,6 +234,9 @@ importers: nanoid: specifier: '3' version: 3.3.4 + nodemailer: + specifier: ^6.9.3 + version: 6.9.3 nodemon: specifier: 2.0.22 version: 2.0.22 @@ -250,6 +256,9 @@ importers: '@types/jsonwebtoken': specifier: ^9.0.2 version: 9.0.2 + '@types/nodemailer': + specifier: ^6.4.8 + version: 6.4.8 '@types/supertest': specifier: 2.0.12 version: 2.0.12 @@ -1634,7 +1643,6 @@ packages: '@aws-sdk/types': 3.357.0 tslib: 1.14.1 dev: false - optional: true /@aws-crypto/ie11-detection@3.0.0: resolution: {integrity: sha512-341lBBkiY1DfDNKai/wXM3aujNBkXR7tq1URPQDL9wi3AUbI80NR74uF1TXHMm7po1AcnFk8iu2S2IeU/+/A+Q==} @@ -1642,7 +1650,6 @@ packages: dependencies: tslib: 1.14.1 dev: false - optional: true /@aws-crypto/sha256-browser@3.0.0: resolution: {integrity: sha512-8VLmW2B+gjFbU5uMeqtQM6Nj0/F1bro80xQXCW6CQBWgosFWXTx77aeOF5CAIAmbOK64SdMBJdNr6J41yP5mvQ==} @@ -1657,7 +1664,6 @@ packages: '@aws-sdk/util-utf8-browser': 3.259.0 tslib: 1.14.1 dev: false - optional: true /@aws-crypto/sha256-js@3.0.0: resolution: {integrity: sha512-PnNN7os0+yd1XvXAy23CFOmTbMaDxgxXtTKHybrJ39Y8kGzBATgBFibWJKH6BhytLI/Zyszs87xCOBNyBig6vQ==} @@ -1667,7 +1673,6 @@ packages: '@aws-sdk/types': 3.357.0 tslib: 1.14.1 dev: false - optional: true /@aws-crypto/supports-web-crypto@3.0.0: resolution: {integrity: sha512-06hBdMwUAb2WFTuGG73LSC0wfPu93xWwo5vL2et9eymgmu3Id5vFAHBbajVWiGhPO37qcsdCap/FqXvJGJWPIg==} @@ -1675,7 +1680,6 @@ packages: dependencies: tslib: 1.14.1 dev: false - optional: true /@aws-crypto/util@3.0.0: resolution: {integrity: sha512-2OJlpeJpCR48CC8r+uKVChzs9Iungj9wkZrl8Z041DWEWvyIHILYKCPNzJghKsivj+S3mLo6BVc7mBNzdxA46w==} @@ -1685,7 +1689,14 @@ packages: '@aws-sdk/util-utf8-browser': 3.259.0 tslib: 1.14.1 dev: false - optional: true + + /@aws-sdk/abort-controller@3.347.0: + resolution: {integrity: sha512-P/2qE6ntYEmYG4Ez535nJWZbXqgbkJx8CMz7ChEuEg3Gp3dvVYEKg+iEUEvlqQ2U5dWP5J3ehw5po9t86IsVPQ==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-sdk/types': 3.347.0 + tslib: 2.6.1 + dev: false /@aws-sdk/abort-controller@3.357.0: resolution: {integrity: sha512-nQYDJon87quPwt2JZJwUN2GFKJnvE5kWb6tZP4xb5biSGUKBqDQo06oYed7yokatCuCMouIXV462aN0fWODtOw==} @@ -1743,6 +1754,93 @@ packages: dev: false optional: true + /@aws-sdk/client-ses@3.347.1: + resolution: {integrity: sha512-zrPaVykH8LGp1YJIVF9jD75/pGWME+TKH9hnFZIrtJGHd9ISOhWyl1RcSNnqs+mEen3b9tzZc8WEr4FUaN3agQ==} + 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.347.1 + '@aws-sdk/config-resolver': 3.347.0 + '@aws-sdk/credential-provider-node': 3.347.0 + '@aws-sdk/fetch-http-handler': 3.347.0 + '@aws-sdk/hash-node': 3.347.0 + '@aws-sdk/invalid-dependency': 3.347.0 + '@aws-sdk/middleware-content-length': 3.347.0 + '@aws-sdk/middleware-endpoint': 3.347.0 + '@aws-sdk/middleware-host-header': 3.347.0 + '@aws-sdk/middleware-logger': 3.347.0 + '@aws-sdk/middleware-recursion-detection': 3.347.0 + '@aws-sdk/middleware-retry': 3.347.0 + '@aws-sdk/middleware-serde': 3.347.0 + '@aws-sdk/middleware-signing': 3.347.0 + '@aws-sdk/middleware-stack': 3.347.0 + '@aws-sdk/middleware-user-agent': 3.347.0 + '@aws-sdk/node-config-provider': 3.347.0 + '@aws-sdk/node-http-handler': 3.347.0 + '@aws-sdk/smithy-client': 3.347.0 + '@aws-sdk/types': 3.347.0 + '@aws-sdk/url-parser': 3.347.0 + '@aws-sdk/util-base64': 3.310.0 + '@aws-sdk/util-body-length-browser': 3.310.0 + '@aws-sdk/util-body-length-node': 3.310.0 + '@aws-sdk/util-defaults-mode-browser': 3.347.0 + '@aws-sdk/util-defaults-mode-node': 3.347.0 + '@aws-sdk/util-endpoints': 3.347.0 + '@aws-sdk/util-retry': 3.347.0 + '@aws-sdk/util-user-agent-browser': 3.347.0 + '@aws-sdk/util-user-agent-node': 3.347.0 + '@aws-sdk/util-utf8': 3.310.0 + '@aws-sdk/util-waiter': 3.347.0 + '@smithy/protocol-http': 1.1.0 + '@smithy/types': 1.1.0 + fast-xml-parser: 4.2.4 + tslib: 2.6.1 + transitivePeerDependencies: + - aws-crt + dev: false + + /@aws-sdk/client-sso-oidc@3.347.0: + resolution: {integrity: sha512-IBxRfPqb8f9FqpmDbzcRDfoiasj/Y47C4Gj+j3kA5T1XWyGwbDI9QnPW/rnkZTWxLUUG1LSbBNwbPD6TLoff8A==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-crypto/sha256-browser': 3.0.0 + '@aws-crypto/sha256-js': 3.0.0 + '@aws-sdk/config-resolver': 3.347.0 + '@aws-sdk/fetch-http-handler': 3.347.0 + '@aws-sdk/hash-node': 3.347.0 + '@aws-sdk/invalid-dependency': 3.347.0 + '@aws-sdk/middleware-content-length': 3.347.0 + '@aws-sdk/middleware-endpoint': 3.347.0 + '@aws-sdk/middleware-host-header': 3.347.0 + '@aws-sdk/middleware-logger': 3.347.0 + '@aws-sdk/middleware-recursion-detection': 3.347.0 + '@aws-sdk/middleware-retry': 3.347.0 + '@aws-sdk/middleware-serde': 3.347.0 + '@aws-sdk/middleware-stack': 3.347.0 + '@aws-sdk/middleware-user-agent': 3.347.0 + '@aws-sdk/node-config-provider': 3.347.0 + '@aws-sdk/node-http-handler': 3.347.0 + '@aws-sdk/smithy-client': 3.347.0 + '@aws-sdk/types': 3.347.0 + '@aws-sdk/url-parser': 3.347.0 + '@aws-sdk/util-base64': 3.310.0 + '@aws-sdk/util-body-length-browser': 3.310.0 + '@aws-sdk/util-body-length-node': 3.310.0 + '@aws-sdk/util-defaults-mode-browser': 3.347.0 + '@aws-sdk/util-defaults-mode-node': 3.347.0 + '@aws-sdk/util-endpoints': 3.347.0 + '@aws-sdk/util-retry': 3.347.0 + '@aws-sdk/util-user-agent-browser': 3.347.0 + '@aws-sdk/util-user-agent-node': 3.347.0 + '@aws-sdk/util-utf8': 3.310.0 + '@smithy/protocol-http': 1.1.0 + '@smithy/types': 1.1.0 + tslib: 2.6.1 + transitivePeerDependencies: + - aws-crt + dev: false + /@aws-sdk/client-sso-oidc@3.362.0: resolution: {integrity: sha512-/urfavz0BjyeWSahp6oh9DjzV8oM5EPmza7iIZXJaPyK03enjse9A52vse4/EfKWaSHtapIgV3ZUKvYDk8AcKA==} engines: {node: '>=14.0.0'} @@ -1786,6 +1884,47 @@ packages: dev: false optional: true + /@aws-sdk/client-sso@3.347.0: + resolution: {integrity: sha512-AZehWCNLUXTrDavsZYRi7d84Uef20ppYJ2FY0KxqrKB3lx89mO29SfSJSC4woeW5+6ooBokq8HtKxw5ImPfRhA==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-crypto/sha256-browser': 3.0.0 + '@aws-crypto/sha256-js': 3.0.0 + '@aws-sdk/config-resolver': 3.347.0 + '@aws-sdk/fetch-http-handler': 3.347.0 + '@aws-sdk/hash-node': 3.347.0 + '@aws-sdk/invalid-dependency': 3.347.0 + '@aws-sdk/middleware-content-length': 3.347.0 + '@aws-sdk/middleware-endpoint': 3.347.0 + '@aws-sdk/middleware-host-header': 3.347.0 + '@aws-sdk/middleware-logger': 3.347.0 + '@aws-sdk/middleware-recursion-detection': 3.347.0 + '@aws-sdk/middleware-retry': 3.347.0 + '@aws-sdk/middleware-serde': 3.347.0 + '@aws-sdk/middleware-stack': 3.347.0 + '@aws-sdk/middleware-user-agent': 3.347.0 + '@aws-sdk/node-config-provider': 3.347.0 + '@aws-sdk/node-http-handler': 3.347.0 + '@aws-sdk/smithy-client': 3.347.0 + '@aws-sdk/types': 3.347.0 + '@aws-sdk/url-parser': 3.347.0 + '@aws-sdk/util-base64': 3.310.0 + '@aws-sdk/util-body-length-browser': 3.310.0 + '@aws-sdk/util-body-length-node': 3.310.0 + '@aws-sdk/util-defaults-mode-browser': 3.347.0 + '@aws-sdk/util-defaults-mode-node': 3.347.0 + '@aws-sdk/util-endpoints': 3.347.0 + '@aws-sdk/util-retry': 3.347.0 + '@aws-sdk/util-user-agent-browser': 3.347.0 + '@aws-sdk/util-user-agent-node': 3.347.0 + '@aws-sdk/util-utf8': 3.310.0 + '@smithy/protocol-http': 1.1.0 + '@smithy/types': 1.1.0 + tslib: 2.6.1 + transitivePeerDependencies: + - aws-crt + dev: false + /@aws-sdk/client-sso@3.362.0: resolution: {integrity: sha512-11M+S7mlr8MBE8NB2yPZWOeb7BV4pcfQ+2p9EE9jVDbcq7VW21chvnf4F+L11aNV1yNtswsnHOSHLKM6YBMM7w==} engines: {node: '>=14.0.0'} @@ -1829,6 +1968,51 @@ packages: dev: false optional: true + /@aws-sdk/client-sts@3.347.1: + resolution: {integrity: sha512-i7vomVsbZcGD2pzOuEl0RS7yCtFcT6CVfSP1wZLwgcjAssUKTLHi65I/uSAUF0KituChw31aXlxh7EGq1uDqaA==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-crypto/sha256-browser': 3.0.0 + '@aws-crypto/sha256-js': 3.0.0 + '@aws-sdk/config-resolver': 3.347.0 + '@aws-sdk/credential-provider-node': 3.347.0 + '@aws-sdk/fetch-http-handler': 3.347.0 + '@aws-sdk/hash-node': 3.347.0 + '@aws-sdk/invalid-dependency': 3.347.0 + '@aws-sdk/middleware-content-length': 3.347.0 + '@aws-sdk/middleware-endpoint': 3.347.0 + '@aws-sdk/middleware-host-header': 3.347.0 + '@aws-sdk/middleware-logger': 3.347.0 + '@aws-sdk/middleware-recursion-detection': 3.347.0 + '@aws-sdk/middleware-retry': 3.347.0 + '@aws-sdk/middleware-sdk-sts': 3.347.0 + '@aws-sdk/middleware-serde': 3.347.0 + '@aws-sdk/middleware-signing': 3.347.0 + '@aws-sdk/middleware-stack': 3.347.0 + '@aws-sdk/middleware-user-agent': 3.347.0 + '@aws-sdk/node-config-provider': 3.347.0 + '@aws-sdk/node-http-handler': 3.347.0 + '@aws-sdk/smithy-client': 3.347.0 + '@aws-sdk/types': 3.347.0 + '@aws-sdk/url-parser': 3.347.0 + '@aws-sdk/util-base64': 3.310.0 + '@aws-sdk/util-body-length-browser': 3.310.0 + '@aws-sdk/util-body-length-node': 3.310.0 + '@aws-sdk/util-defaults-mode-browser': 3.347.0 + '@aws-sdk/util-defaults-mode-node': 3.347.0 + '@aws-sdk/util-endpoints': 3.347.0 + '@aws-sdk/util-retry': 3.347.0 + '@aws-sdk/util-user-agent-browser': 3.347.0 + '@aws-sdk/util-user-agent-node': 3.347.0 + '@aws-sdk/util-utf8': 3.310.0 + '@smithy/protocol-http': 1.1.0 + '@smithy/types': 1.1.0 + fast-xml-parser: 4.2.4 + tslib: 2.6.1 + transitivePeerDependencies: + - aws-crt + dev: false + /@aws-sdk/client-sts@3.362.0: resolution: {integrity: sha512-4Kh6oM2hfJbckuMb9O5eRIG66s/eA0wazXYvCbxSiSi3XgkX9L4m5OSNxlzLPe7uVgkEx8ykuk8Xz6qZrZWJcQ==} engines: {node: '>=14.0.0'} @@ -1876,6 +2060,16 @@ packages: dev: false optional: true + /@aws-sdk/config-resolver@3.347.0: + resolution: {integrity: sha512-2ja+Sf/VnUO7IQ3nKbDQ5aumYKKJUaTm/BuVJ29wNho8wYHfuf7wHZV0pDTkB8RF5SH7IpHap7zpZAj39Iq+EA==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-sdk/types': 3.347.0 + '@aws-sdk/util-config-provider': 3.310.0 + '@aws-sdk/util-middleware': 3.347.0 + tslib: 2.6.1 + dev: false + /@aws-sdk/config-resolver@3.357.0: resolution: {integrity: sha512-cukfg0nX7Tzx/xFyH5F4Eyb8DA1ITCGtSQv4vnEjgUop+bkzckuGLKEeBcBhyZY+aw+2C9CVwIHwIMhRm0ul5w==} engines: {node: '>=14.0.0'} @@ -1902,6 +2096,15 @@ packages: dev: false optional: true + /@aws-sdk/credential-provider-env@3.347.0: + resolution: {integrity: sha512-UnEM+LKGpXKzw/1WvYEQsC6Wj9PupYZdQOE+e2Dgy2dqk/pVFy4WueRtFXYDT2B41ppv3drdXUuKZRIDVqIgNQ==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-sdk/property-provider': 3.347.0 + '@aws-sdk/types': 3.347.0 + tslib: 2.6.1 + dev: false + /@aws-sdk/credential-provider-env@3.357.0: resolution: {integrity: sha512-UOecwfqvXgJVqhfWSZ2S44v2Nq2oceW0PQVQp0JAa9opc2rxSVIfyOhPr0yMoPmpyNcP22rgeg6ce70KULYwiA==} engines: {node: '>=14.0.0'} @@ -1913,6 +2116,17 @@ packages: dev: false optional: true + /@aws-sdk/credential-provider-imds@3.347.0: + resolution: {integrity: sha512-7scCy/DCDRLIhlqTxff97LQWDnRwRXji3bxxMg+xWOTTaJe7PWx+etGSbBWaL42vsBHFShQjSLvJryEgoBktpw==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-sdk/node-config-provider': 3.347.0 + '@aws-sdk/property-provider': 3.347.0 + '@aws-sdk/types': 3.347.0 + '@aws-sdk/url-parser': 3.347.0 + tslib: 2.6.1 + dev: false + /@aws-sdk/credential-provider-imds@3.357.0: resolution: {integrity: sha512-upw/bfsl7/WydT6gM0lBuR4Ipp4fzYm/E3ObFr0Mg5OkgVPt5ZJE+eeFTvwCpDdBSTKs4JfrK6/iEK8A23Q1jQ==} engines: {node: '>=14.0.0'} @@ -1926,6 +2140,23 @@ packages: dev: false optional: true + /@aws-sdk/credential-provider-ini@3.347.0: + resolution: {integrity: sha512-84TNF34ryabmVbILOq7f+/Jy8tJaskvHdax3X90qxFtXRU11kX0bf5NYL616KT0epR0VGpy50ThfIqvBwxeJfQ==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-sdk/credential-provider-env': 3.347.0 + '@aws-sdk/credential-provider-imds': 3.347.0 + '@aws-sdk/credential-provider-process': 3.347.0 + '@aws-sdk/credential-provider-sso': 3.347.0 + '@aws-sdk/credential-provider-web-identity': 3.347.0 + '@aws-sdk/property-provider': 3.347.0 + '@aws-sdk/shared-ini-file-loader': 3.347.0 + '@aws-sdk/types': 3.347.0 + tslib: 2.6.1 + transitivePeerDependencies: + - aws-crt + dev: false + /@aws-sdk/credential-provider-ini@3.362.0: resolution: {integrity: sha512-56gOo0XrqfEXTYrpWwZEYqrKEyNNpyNNvagfuP29d4aqok7ON5CkL1ymmKhNuDGHbbHXVGOIGdLNJBkGBgwE1g==} engines: {node: '>=14.0.0'} @@ -1945,6 +2176,24 @@ packages: dev: false optional: true + /@aws-sdk/credential-provider-node@3.347.0: + resolution: {integrity: sha512-ds2uxE0krl94RdQ7bstwafUXdlMeEOPgedhaheVVlj8kH+XqlZdwUUaUv1uoEI9iBzuSjKftUkIHo0xsTiwtaw==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-sdk/credential-provider-env': 3.347.0 + '@aws-sdk/credential-provider-imds': 3.347.0 + '@aws-sdk/credential-provider-ini': 3.347.0 + '@aws-sdk/credential-provider-process': 3.347.0 + '@aws-sdk/credential-provider-sso': 3.347.0 + '@aws-sdk/credential-provider-web-identity': 3.347.0 + '@aws-sdk/property-provider': 3.347.0 + '@aws-sdk/shared-ini-file-loader': 3.347.0 + '@aws-sdk/types': 3.347.0 + tslib: 2.6.1 + transitivePeerDependencies: + - aws-crt + dev: false + /@aws-sdk/credential-provider-node@3.362.0: resolution: {integrity: sha512-G/oCGTdN3Gx1HgSX6KlGC71q9EQw9luSgGGIgZHAw9u3IllLEARqxVQ5PUPlhEM4FkNNMpzicUbWeI5NeMRuyA==} engines: {node: '>=14.0.0'} @@ -1965,6 +2214,16 @@ packages: dev: false optional: true + /@aws-sdk/credential-provider-process@3.347.0: + resolution: {integrity: sha512-yl1z4MsaBdXd4GQ2halIvYds23S67kElyOwz7g8kaQ4kHj+UoYWxz3JVW/DGusM6XmQ9/F67utBrUVA0uhQYyw==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-sdk/property-provider': 3.347.0 + '@aws-sdk/shared-ini-file-loader': 3.347.0 + '@aws-sdk/types': 3.347.0 + tslib: 2.6.1 + dev: false + /@aws-sdk/credential-provider-process@3.357.0: resolution: {integrity: sha512-qFWWilFPsc2hR7O0KIhwcE78w+pVIK+uQR6MQMfdRyxUndgiuCorJwVjedc3yZtmnoELHF34j+m8whTBXv9E7Q==} engines: {node: '>=14.0.0'} @@ -1977,6 +2236,20 @@ packages: dev: false optional: true + /@aws-sdk/credential-provider-sso@3.347.0: + resolution: {integrity: sha512-M1d7EnUaJbSNCmNalEbINmtFkc9wJufx7UhKtEeFwSq9KEzOMroH1MEOeiqIw9f/zE8NI/iPkVeEhw123vmBrQ==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-sdk/client-sso': 3.347.0 + '@aws-sdk/property-provider': 3.347.0 + '@aws-sdk/shared-ini-file-loader': 3.347.0 + '@aws-sdk/token-providers': 3.347.0 + '@aws-sdk/types': 3.347.0 + tslib: 2.6.1 + transitivePeerDependencies: + - aws-crt + dev: false + /@aws-sdk/credential-provider-sso@3.362.0: resolution: {integrity: sha512-jf5jG8IQXNSTuOPMT0SMOpBi+Tlct+3Ik5njpEECFzo5POzU8DgJkc2ALMNW5j+XojuchwgeqWZclPRoacKjVw==} engines: {node: '>=14.0.0'} @@ -1993,6 +2266,15 @@ packages: dev: false optional: true + /@aws-sdk/credential-provider-web-identity@3.347.0: + resolution: {integrity: sha512-DxoTlVK8lXjS1zVphtz/Ab+jkN/IZor9d6pP2GjJHNoAIIzXfRwwj5C8vr4eTayx/5VJ7GRP91J8GJ2cKly8Qw==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-sdk/property-provider': 3.347.0 + '@aws-sdk/types': 3.347.0 + tslib: 2.6.1 + dev: false + /@aws-sdk/credential-provider-web-identity@3.357.0: resolution: {integrity: sha512-0KRRAFrXy5HJe2vqnCWCoCS+fQw7IoIj3KQsuURJMW4F+ifisxCgEsh3brJ2LQlN4ElWTRJhlrDHNZ/pd61D4w==} engines: {node: '>=14.0.0'} @@ -2028,6 +2310,15 @@ packages: dev: false optional: true + /@aws-sdk/eventstream-codec@3.347.0: + resolution: {integrity: sha512-61q+SyspjsaQ4sdgjizMyRgVph2CiW4aAtfpoH69EJFJfTxTR/OqnZ9Jx/3YiYi0ksrvDenJddYodfWWJqD8/w==} + dependencies: + '@aws-crypto/crc32': 3.0.0 + '@aws-sdk/types': 3.347.0 + '@aws-sdk/util-hex-encoding': 3.310.0 + tslib: 2.6.1 + dev: false + /@aws-sdk/eventstream-codec@3.357.0: resolution: {integrity: sha512-bqenTHG6GH6aCk/Il+ooWXVVAZuc8lOgVEy9bE2hI49oVqT8zSuXxQB+w1WWyZoAOPcelsjayB1wfPub8VDBxQ==} requiresBuild: true @@ -2039,6 +2330,16 @@ packages: dev: false optional: true + /@aws-sdk/fetch-http-handler@3.347.0: + resolution: {integrity: sha512-sQ5P7ivY8//7wdxfA76LT1sF6V2Tyyz1qF6xXf9sihPN5Q1Y65c+SKpMzXyFSPqWZ82+SQQuDliYZouVyS6kQQ==} + dependencies: + '@aws-sdk/protocol-http': 3.347.0 + '@aws-sdk/querystring-builder': 3.347.0 + '@aws-sdk/types': 3.347.0 + '@aws-sdk/util-base64': 3.310.0 + tslib: 2.6.1 + dev: false + /@aws-sdk/fetch-http-handler@3.357.0: resolution: {integrity: sha512-5sPloTO8y8fAnS/6/Sfp/aVoL9zuhzkLdWBORNzMazdynVNEzWKWCPZ27RQpgkaCDHiXjqUY4kfuFXAGkvFfDQ==} requiresBuild: true @@ -2051,6 +2352,16 @@ packages: dev: false optional: true + /@aws-sdk/hash-node@3.347.0: + resolution: {integrity: sha512-96+ml/4EaUaVpzBdOLGOxdoXOjkPgkoJp/0i1fxOJEvl8wdAQSwc3IugVK9wZkCxy2DlENtgOe6DfIOhfffm/g==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-sdk/types': 3.347.0 + '@aws-sdk/util-buffer-from': 3.310.0 + '@aws-sdk/util-utf8': 3.310.0 + tslib: 2.6.1 + dev: false + /@aws-sdk/hash-node@3.357.0: resolution: {integrity: sha512-fq3LS9AxHKb7dTZkm6iM1TrGk6XOTZz96iEZPME1+vjiSEXGWuebHt87q92n+KozVGRypn9MId3lHOPBBjygNQ==} engines: {node: '>=14.0.0'} @@ -2063,6 +2374,13 @@ packages: dev: false optional: true + /@aws-sdk/invalid-dependency@3.347.0: + resolution: {integrity: sha512-8imQcwLwqZ/wTJXZqzXT9pGLIksTRckhGLZaXT60tiBOPKuerTsus2L59UstLs5LP8TKaVZKFFSsjRIn9dQdmQ==} + dependencies: + '@aws-sdk/types': 3.347.0 + tslib: 2.6.1 + dev: false + /@aws-sdk/invalid-dependency@3.357.0: resolution: {integrity: sha512-HnCYZczf0VdyxMVMMxmA3QJAyyPSFbcMtZzgKbxVTWTG7GKpQe0psWZu/7O2Nk31mKg6vEUdiP1FylqLBsgMOA==} requiresBuild: true @@ -2079,7 +2397,15 @@ packages: dependencies: tslib: 2.6.1 dev: false - optional: true + + /@aws-sdk/middleware-content-length@3.347.0: + resolution: {integrity: sha512-i4qtWTDImMaDUtwKQPbaZpXsReiwiBomM1cWymCU4bhz81HL01oIxOxOBuiM+3NlDoCSPr3KI6txZSz/8cqXCQ==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-sdk/protocol-http': 3.347.0 + '@aws-sdk/types': 3.347.0 + tslib: 2.6.1 + dev: false /@aws-sdk/middleware-content-length@3.357.0: resolution: {integrity: sha512-zQOFEyzOXAgN4M54tYNWGxKxnyzY0WwYDTFzh9riJRmxN1hTEKHUKmze4nILIf5rkQmOG4kTf1qmfazjkvZAhw==} @@ -2092,6 +2418,17 @@ packages: dev: false optional: true + /@aws-sdk/middleware-endpoint@3.347.0: + resolution: {integrity: sha512-unF0c6dMaUL1ffU+37Ugty43DgMnzPWXr/Jup/8GbK5fzzWT5NQq6dj9KHPubMbWeEjQbmczvhv25JuJdK8gNQ==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-sdk/middleware-serde': 3.347.0 + '@aws-sdk/types': 3.347.0 + '@aws-sdk/url-parser': 3.347.0 + '@aws-sdk/util-middleware': 3.347.0 + tslib: 2.6.1 + dev: false + /@aws-sdk/middleware-endpoint@3.357.0: resolution: {integrity: sha512-ScJi0SL8X/Lyi0Fp5blg0QN/Z6PoRwV/ZJXd8dQkXSznkbSvJHfqPP0xk/w3GcQ1TKsu5YEPfeYy8ejcq+7Pgg==} engines: {node: '>=14.0.0'} @@ -2105,6 +2442,15 @@ packages: dev: false optional: true + /@aws-sdk/middleware-host-header@3.347.0: + resolution: {integrity: sha512-kpKmR9OvMlnReqp5sKcJkozbj1wmlblbVSbnQAIkzeQj2xD5dnVR3Nn2ogQKxSmU1Fv7dEroBtrruJ1o3fY38A==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-sdk/protocol-http': 3.347.0 + '@aws-sdk/types': 3.347.0 + tslib: 2.6.1 + dev: false + /@aws-sdk/middleware-host-header@3.357.0: resolution: {integrity: sha512-HuGLcP7JP1qJ5wGT9GSlEknDaTSnOzHY4T6IPFuvFjAy3PvY5siQNm6+VRqdVS+n6/kzpL3JP5sAVM3aoxHT6Q==} engines: {node: '>=14.0.0'} @@ -2116,6 +2462,14 @@ packages: dev: false optional: true + /@aws-sdk/middleware-logger@3.347.0: + resolution: {integrity: sha512-NYC+Id5UCkVn+3P1t/YtmHt75uED06vwaKyxDy0UmB2K66PZLVtwWbLpVWrhbroaw1bvUHYcRyQ9NIfnVcXQjA==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-sdk/types': 3.347.0 + tslib: 2.6.1 + dev: false + /@aws-sdk/middleware-logger@3.357.0: resolution: {integrity: sha512-dncT3tr+lZ9+duZo52rASgO6AKVwRcsc2/T93gmaYVrJqI6WWAwQ7yML5s72l9ZjQ5LZ+4jjrgtlufavAS0eCg==} engines: {node: '>=14.0.0'} @@ -2126,6 +2480,15 @@ packages: dev: false optional: true + /@aws-sdk/middleware-recursion-detection@3.347.0: + resolution: {integrity: sha512-qfnSvkFKCAMjMHR31NdsT0gv5Sq/ZHTUD4yQsSLpbVQ6iYAS834lrzXt41iyEHt57Y514uG7F/Xfvude3u4icQ==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-sdk/protocol-http': 3.347.0 + '@aws-sdk/types': 3.347.0 + tslib: 2.6.1 + dev: false + /@aws-sdk/middleware-recursion-detection@3.357.0: resolution: {integrity: sha512-AXC54IeDS3jC1dbbkYHML4STvBPcKZ4IJTWdjEK1RCOgqXd0Ze1cE1e21wyj1tM6prF03zLyvpBd+3TS++nqfA==} engines: {node: '>=14.0.0'} @@ -2137,6 +2500,19 @@ packages: dev: false optional: true + /@aws-sdk/middleware-retry@3.347.0: + resolution: {integrity: sha512-CpdM+8dCSbX96agy4FCzOfzDmhNnGBM/pxrgIVLm5nkYTLuXp/d7ubpFEUHULr+4hCd5wakHotMt7yO29NFaVw==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-sdk/protocol-http': 3.347.0 + '@aws-sdk/service-error-classification': 3.347.0 + '@aws-sdk/types': 3.347.0 + '@aws-sdk/util-middleware': 3.347.0 + '@aws-sdk/util-retry': 3.347.0 + tslib: 2.6.1 + uuid: 8.3.2 + dev: false + /@aws-sdk/middleware-retry@3.362.0: resolution: {integrity: sha512-ZFsty5fXIdvTTm+GnTtCPre89b2QFZYQmD0L5nhJULDFoU5Fz/bsI5C3b98/wb4YCAIfXBZpx4Kh2RAEKnxkyg==} engines: {node: '>=14.0.0'} @@ -2152,6 +2528,15 @@ packages: dev: false optional: true + /@aws-sdk/middleware-sdk-sts@3.347.0: + resolution: {integrity: sha512-38LJ0bkIoVF3W97x6Jyyou72YV9Cfbml4OaDEdnrCOo0EssNZM5d7RhjMvQDwww7/3OBY/BzeOcZKfJlkYUXGw==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-sdk/middleware-signing': 3.347.0 + '@aws-sdk/types': 3.347.0 + tslib: 2.6.1 + dev: false + /@aws-sdk/middleware-sdk-sts@3.357.0: resolution: {integrity: sha512-Ng2VjLrPiL02QOcs1qs9jG2boO4Gn+v3VIbOJLG4zXcfbSq55iIWtlmr2ljfw9vP5aLhWtcODfmKHS5Bp+019Q==} engines: {node: '>=14.0.0'} @@ -2163,6 +2548,14 @@ packages: dev: false optional: true + /@aws-sdk/middleware-serde@3.347.0: + resolution: {integrity: sha512-x5Foi7jRbVJXDu9bHfyCbhYDH5pKK+31MmsSJ3k8rY8keXLBxm2XEEg/AIoV9/TUF9EeVvZ7F1/RmMpJnWQsEg==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-sdk/types': 3.347.0 + tslib: 2.6.1 + dev: false + /@aws-sdk/middleware-serde@3.357.0: resolution: {integrity: sha512-bGI4kYuuEsFjlANbyJLyy4AovETnyf/SukgLOG7Qjbua+ZGuzvRhMsk21mBKKGrnsTO4PmtieJo6xClThGAN8g==} engines: {node: '>=14.0.0'} @@ -2173,6 +2566,18 @@ packages: dev: false optional: true + /@aws-sdk/middleware-signing@3.347.0: + resolution: {integrity: sha512-zVBF/4MGKnvhAE/J+oAL/VAehiyv+trs2dqSQXwHou9j8eA8Vm8HS2NdOwpkZQchIxTuwFlqSusDuPEdYFbvGw==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-sdk/property-provider': 3.347.0 + '@aws-sdk/protocol-http': 3.347.0 + '@aws-sdk/signature-v4': 3.347.0 + '@aws-sdk/types': 3.347.0 + '@aws-sdk/util-middleware': 3.347.0 + tslib: 2.6.1 + dev: false + /@aws-sdk/middleware-signing@3.357.0: resolution: {integrity: sha512-yB9ewEqI6Fw1OrmKFrUypbCqN5ijk06UGPochybamMuPxxkwMT3bnrm7eezsCA+TZbJyKhpffpyobwuv+xGNrA==} engines: {node: '>=14.0.0'} @@ -2187,6 +2592,13 @@ packages: dev: false optional: true + /@aws-sdk/middleware-stack@3.347.0: + resolution: {integrity: sha512-Izidg4rqtYMcKuvn2UzgEpPLSmyd8ub9+LQ2oIzG3mpIzCBITq7wp40jN1iNkMg+X6KEnX9vdMJIYZsPYMCYuQ==} + engines: {node: '>=14.0.0'} + dependencies: + tslib: 2.6.1 + dev: false + /@aws-sdk/middleware-stack@3.357.0: resolution: {integrity: sha512-nNV+jfwGwmbOGZujAY/U8AW3EbVlxa9DJDLz3TPp/39o6Vu5KEzHJyDDNreo2k9V/TMvV+nOzHafufgPdagv7w==} engines: {node: '>=14.0.0'} @@ -2196,6 +2608,16 @@ packages: dev: false optional: true + /@aws-sdk/middleware-user-agent@3.347.0: + resolution: {integrity: sha512-wJbGN3OE1/daVCrwk49whhIr9E0j1N4gWwN/wi4WuyYIA+5lMUfVp0aGIOvZR+878DxuFz2hQ4XcZVT4K2WvQw==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-sdk/protocol-http': 3.347.0 + '@aws-sdk/types': 3.347.0 + '@aws-sdk/util-endpoints': 3.347.0 + tslib: 2.6.1 + dev: false + /@aws-sdk/middleware-user-agent@3.357.0: resolution: {integrity: sha512-M/CsAXjGblZS4rEbMb0Dn9IXbfq4EjVaTHBfvuILU/dKRppWvjnm2lRtqCZ+LIT3ATbAjA3/dY7dWsjxQWwijA==} engines: {node: '>=14.0.0'} @@ -2208,6 +2630,16 @@ packages: dev: false optional: true + /@aws-sdk/node-config-provider@3.347.0: + resolution: {integrity: sha512-faU93d3+5uTTUcotGgMXF+sJVFjrKh+ufW+CzYKT4yUHammyaIab/IbTPWy2hIolcEGtuPeVoxXw8TXbkh/tuw==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-sdk/property-provider': 3.347.0 + '@aws-sdk/shared-ini-file-loader': 3.347.0 + '@aws-sdk/types': 3.347.0 + tslib: 2.6.1 + dev: false + /@aws-sdk/node-config-provider@3.357.0: resolution: {integrity: sha512-kwBIzKCaW3UWqLdELhy7TcN8itNMOjbzga530nalFILMvn2IxrkdKQhNgxGBXy6QK6kCOtH6OmcrG3/oZkLwig==} engines: {node: '>=14.0.0'} @@ -2220,6 +2652,17 @@ packages: dev: false optional: true + /@aws-sdk/node-http-handler@3.347.0: + resolution: {integrity: sha512-eluPf3CeeEaPbETsPw7ee0Rb0FP79amu8vdLMrQmkrD+KP4owupUXOEI4drxWJgBSd+3PRowPWCDA8wUtraHKg==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-sdk/abort-controller': 3.347.0 + '@aws-sdk/protocol-http': 3.347.0 + '@aws-sdk/querystring-builder': 3.347.0 + '@aws-sdk/types': 3.347.0 + tslib: 2.6.1 + dev: false + /@aws-sdk/node-http-handler@3.360.0: resolution: {integrity: sha512-oMsXdMmNwHpUbebETO44bq0N4SocEMGfPjYNUTRs8md7ita5fuFd2qFuvf+ZRt6iVcGWluIqmF8DidD+b7d+TA==} engines: {node: '>=14.0.0'} @@ -2233,6 +2676,14 @@ packages: dev: false optional: true + /@aws-sdk/property-provider@3.347.0: + resolution: {integrity: sha512-t3nJ8CYPLKAF2v9nIHOHOlF0CviQbTvbFc2L4a+A+EVd/rM4PzL3+3n8ZJsr0h7f6uD04+b5YRFgKgnaqLXlEg==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-sdk/types': 3.347.0 + tslib: 2.6.1 + dev: false + /@aws-sdk/property-provider@3.357.0: resolution: {integrity: sha512-im4W0u8WaYxG7J7ko4Xl3OEzK3Mrm1Rz6/txTGe6hTIHlyUISu1ekOQJXK6XYPqNMn8v1G3BiQREoRXUEJFbHg==} engines: {node: '>=14.0.0'} @@ -2243,6 +2694,14 @@ packages: dev: false optional: true + /@aws-sdk/protocol-http@3.347.0: + resolution: {integrity: sha512-2YdBhc02Wvy03YjhGwUxF0UQgrPWEy8Iq75pfS42N+/0B/+eWX1aQgfjFxIpLg7YSjT5eKtYOQGlYd4MFTgj9g==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-sdk/types': 3.347.0 + tslib: 2.6.1 + dev: false + /@aws-sdk/protocol-http@3.357.0: resolution: {integrity: sha512-w1JHiI50VEea7duDeAspUiKJmmdIQblvRyjVMOqWA6FIQAyDVuEiPX7/MdQr0ScxhtRQxHbP0I4MFyl7ctRQvA==} engines: {node: '>=14.0.0'} @@ -2253,6 +2712,15 @@ packages: dev: false optional: true + /@aws-sdk/querystring-builder@3.347.0: + resolution: {integrity: sha512-phtKTe6FXoV02MoPkIVV6owXI8Mwr5IBN3bPoxhcPvJG2AjEmnetSIrhb8kwc4oNhlwfZwH6Jo5ARW/VEWbZtg==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-sdk/types': 3.347.0 + '@aws-sdk/util-uri-escape': 3.310.0 + tslib: 2.6.1 + dev: false + /@aws-sdk/querystring-builder@3.357.0: resolution: {integrity: sha512-aQcicqB6Y2cNaXPPwunz612a01SMiQQPsdz632F/3Lzn0ua82BJKobHOtaiTUlmVJ5Q4/EAeNfwZgL7tTUNtDQ==} engines: {node: '>=14.0.0'} @@ -2264,6 +2732,14 @@ packages: dev: false optional: true + /@aws-sdk/querystring-parser@3.347.0: + resolution: {integrity: sha512-5VXOhfZz78T2W7SuXf2avfjKglx1VZgZgp9Zfhrt/Rq+MTu2D+PZc5zmJHhYigD7x83jLSLogpuInQpFMA9LgA==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-sdk/types': 3.347.0 + tslib: 2.6.1 + dev: false + /@aws-sdk/querystring-parser@3.357.0: resolution: {integrity: sha512-Svvq+atRNP9s2VxiklcUNgCzmt3T5kfs7X2C+yjmxHvOQTPjLNaNGbfC/vhjOK7aoXw0h+lBac48r5ymx1PbQA==} engines: {node: '>=14.0.0'} @@ -2274,6 +2750,11 @@ packages: dev: false optional: true + /@aws-sdk/service-error-classification@3.347.0: + resolution: {integrity: sha512-xZ3MqSY81Oy2gh5g0fCtooAbahqh9VhsF8vcKjVX8+XPbGC8y+kej82+MsMg4gYL8gRFB9u4hgYbNgIS6JTAvg==} + engines: {node: '>=14.0.0'} + dev: false + /@aws-sdk/service-error-classification@3.357.0: resolution: {integrity: sha512-VuXeL4g5vKO9HjgCZlxmH8Uv1FcqUSjmbPpQkbNtYIDck6u0qzM0rG+n0/1EjyQbPSr3MhW/pkWs5nx2Nljlyg==} engines: {node: '>=14.0.0'} @@ -2281,6 +2762,14 @@ packages: dev: false optional: true + /@aws-sdk/shared-ini-file-loader@3.347.0: + resolution: {integrity: sha512-Xw+zAZQVLb+xMNHChXQ29tzzLqm3AEHsD8JJnlkeFjeMnWQtXdUfOARl5s8NzAppcKQNlVe2gPzjaKjoy2jz1Q==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-sdk/types': 3.347.0 + tslib: 2.6.1 + dev: false + /@aws-sdk/shared-ini-file-loader@3.357.0: resolution: {integrity: sha512-ceyqM4XxQe0Plb/oQAD2t1UOV2Iy4PFe1oAGM8dfJzYrRKu7zvMwru7/WaB3NYq+/mIY6RU+jjhRmjQ3GySVqA==} engines: {node: '>=14.0.0'} @@ -2291,6 +2780,20 @@ packages: dev: false optional: true + /@aws-sdk/signature-v4@3.347.0: + resolution: {integrity: sha512-58Uq1do+VsTHYkP11dTK+DF53fguoNNJL9rHRWhzP+OcYv3/mBMLoS2WPz/x9FO5mBg4ESFsug0I6mXbd36tjw==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-sdk/eventstream-codec': 3.347.0 + '@aws-sdk/is-array-buffer': 3.310.0 + '@aws-sdk/types': 3.347.0 + '@aws-sdk/util-hex-encoding': 3.310.0 + '@aws-sdk/util-middleware': 3.347.0 + '@aws-sdk/util-uri-escape': 3.310.0 + '@aws-sdk/util-utf8': 3.310.0 + tslib: 2.6.1 + dev: false + /@aws-sdk/signature-v4@3.357.0: resolution: {integrity: sha512-itt4/Jh9FqnzK30qIjXFBvM4J7zN4S/AAqsRMnaX7U4f/MV+1YxQHmzimpdMnsCXXs2jqFqKVRu6DewxJ3nbxg==} engines: {node: '>=14.0.0'} @@ -2307,6 +2810,15 @@ packages: dev: false optional: true + /@aws-sdk/smithy-client@3.347.0: + resolution: {integrity: sha512-PaGTDsJLGK0sTjA6YdYQzILRlPRN3uVFyqeBUkfltXssvUzkm8z2t1lz2H4VyJLAhwnG5ZuZTNEV/2mcWrU7JQ==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-sdk/middleware-stack': 3.347.0 + '@aws-sdk/types': 3.347.0 + tslib: 2.6.1 + dev: false + /@aws-sdk/smithy-client@3.360.0: resolution: {integrity: sha512-R7wbT2SkgWNEAxMekOTNcPcvBszabW2+qHjrcelbbVJNjx/2yK+MbpZI4WRSncByQMeeoW+aSUP+JgsbpiOWfw==} engines: {node: '>=14.0.0'} @@ -2320,6 +2832,19 @@ packages: dev: false optional: true + /@aws-sdk/token-providers@3.347.0: + resolution: {integrity: sha512-DZS9UWEy105zsaBJTgcvv1U+0jl7j1OzfMpnLf/lEYjEvx/4FqY2Ue/OZUACJorZgm/dWNqrhY17tZXtS/S3ew==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-sdk/client-sso-oidc': 3.347.0 + '@aws-sdk/property-provider': 3.347.0 + '@aws-sdk/shared-ini-file-loader': 3.347.0 + '@aws-sdk/types': 3.347.0 + tslib: 2.6.1 + transitivePeerDependencies: + - aws-crt + dev: false + /@aws-sdk/token-providers@3.362.0: resolution: {integrity: sha512-w7NTeB2j1CRdvDa7m08KQr12HN6qrOknXhGEMmf67bfdfAdmPWsJXIbxcKH8eze+acOzoimbqv8KyCVmyX/pCQ==} engines: {node: '>=14.0.0'} @@ -2335,6 +2860,13 @@ packages: dev: false optional: true + /@aws-sdk/types@3.347.0: + resolution: {integrity: sha512-GkCMy79mdjU9OTIe5KT58fI/6uqdf8UmMdWqVHmFJ+UpEzOci7L/uw4sOXWo7xpPzLs6cJ7s5ouGZW4GRPmHFA==} + engines: {node: '>=14.0.0'} + dependencies: + tslib: 2.6.1 + dev: false + /@aws-sdk/types@3.357.0: resolution: {integrity: sha512-/riCRaXg3p71BeWnShrai0y0QTdXcouPSM0Cn1olZbzTf7s71aLEewrc96qFrL70XhY4XvnxMpqQh+r43XIL3g==} engines: {node: '>=14.0.0'} @@ -2342,7 +2874,14 @@ packages: dependencies: tslib: 2.6.1 dev: false - optional: true + + /@aws-sdk/url-parser@3.347.0: + resolution: {integrity: sha512-lhrnVjxdV7hl+yCnJfDZOaVLSqKjxN20MIOiijRiqaWGLGEAiSqBreMhL89X1WKCifxAs4zZf9YB9SbdziRpAA==} + dependencies: + '@aws-sdk/querystring-parser': 3.347.0 + '@aws-sdk/types': 3.347.0 + tslib: 2.6.1 + dev: false /@aws-sdk/url-parser@3.357.0: resolution: {integrity: sha512-fAaU6cFsaAba01lCRsRJiYR/LfXvX2wudyEyutBVglE4dWSoSeu3QJNxImIzTBULfbiFhz59++NQ1JUVx88IVg==} @@ -2362,7 +2901,6 @@ packages: '@aws-sdk/util-buffer-from': 3.310.0 tslib: 2.6.1 dev: false - optional: true /@aws-sdk/util-body-length-browser@3.310.0: resolution: {integrity: sha512-sxsC3lPBGfpHtNTUoGXMQXLwjmR0zVpx0rSvzTPAuoVILVsp5AU/w5FphNPxD5OVIjNbZv9KsKTuvNTiZjDp9g==} @@ -2370,7 +2908,6 @@ packages: dependencies: tslib: 2.6.1 dev: false - optional: true /@aws-sdk/util-body-length-node@3.310.0: resolution: {integrity: sha512-2tqGXdyKhyA6w4zz7UPoS8Ip+7sayOg9BwHNidiGm2ikbDxm1YrCfYXvCBdwaJxa4hJfRVz+aL9e+d3GqPI9pQ==} @@ -2379,7 +2916,6 @@ packages: dependencies: tslib: 2.6.1 dev: false - optional: true /@aws-sdk/util-buffer-from@3.310.0: resolution: {integrity: sha512-i6LVeXFtGih5Zs8enLrt+ExXY92QV25jtEnTKHsmlFqFAuL3VBeod6boeMXkN2p9lbSVVQ1sAOOYZOHYbYkntw==} @@ -2389,7 +2925,6 @@ packages: '@aws-sdk/is-array-buffer': 3.310.0 tslib: 2.6.1 dev: false - optional: true /@aws-sdk/util-config-provider@3.310.0: resolution: {integrity: sha512-xIBaYo8dwiojCw8vnUcIL4Z5tyfb1v3yjqyJKJWV/dqKUFOOS0U591plmXbM+M/QkXyML3ypon1f8+BoaDExrg==} @@ -2398,7 +2933,16 @@ packages: dependencies: tslib: 2.6.1 dev: false - optional: true + + /@aws-sdk/util-defaults-mode-browser@3.347.0: + resolution: {integrity: sha512-+JHFA4reWnW/nMWwrLKqL2Lm/biw/Dzi/Ix54DAkRZ08C462jMKVnUlzAI+TfxQE3YLm99EIa0G7jiEA+p81Qw==} + engines: {node: '>= 10.0.0'} + dependencies: + '@aws-sdk/property-provider': 3.347.0 + '@aws-sdk/types': 3.347.0 + bowser: 2.11.0 + tslib: 2.6.1 + dev: false /@aws-sdk/util-defaults-mode-browser@3.360.0: resolution: {integrity: sha512-/GR8VlK9xo1Q5WbVYuNaZ+XfoCFdWNb4z4mpoEgvEgBH4R0GjqiAqLftUA8Ykq1tJuDAKPYVzUNzK8DC0pt7/g==} @@ -2412,6 +2956,18 @@ packages: dev: false optional: true + /@aws-sdk/util-defaults-mode-node@3.347.0: + resolution: {integrity: sha512-A8BzIVhAAZE5WEukoAN2kYebzTc99ZgncbwOmgCCbvdaYlk5tzguR/s+uoT4G0JgQGol/4hAMuJEl7elNgU6RQ==} + engines: {node: '>= 10.0.0'} + dependencies: + '@aws-sdk/config-resolver': 3.347.0 + '@aws-sdk/credential-provider-imds': 3.347.0 + '@aws-sdk/node-config-provider': 3.347.0 + '@aws-sdk/property-provider': 3.347.0 + '@aws-sdk/types': 3.347.0 + tslib: 2.6.1 + dev: false + /@aws-sdk/util-defaults-mode-node@3.360.0: resolution: {integrity: sha512-gR3Ctqpyl7SgStDJ1Jlq6qQDuw/rS9AgbAXx+s3wsmm3fm8lHKkXkDPYVvNDqd6dVXRO6q8MRx00lwkGI4qrpQ==} engines: {node: '>= 10.0.0'} @@ -2426,6 +2982,14 @@ packages: dev: false optional: true + /@aws-sdk/util-endpoints@3.347.0: + resolution: {integrity: sha512-/WUkirizeNAqwVj0zkcrqdQ9pUm1HY5kU+qy7xTR0OebkuJauglkmSTMD+56L1JPunWqHhlwCMVRaz5eaJdSEQ==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-sdk/types': 3.347.0 + tslib: 2.6.1 + dev: false + /@aws-sdk/util-endpoints@3.357.0: resolution: {integrity: sha512-XHKyS5JClT9su9hDif715jpZiWHQF9gKZXER8tW0gOizU3R9cyWc9EsJ2BRhFNhi7nt/JF/CLUEc5qDx3ETbUw==} engines: {node: '>=14.0.0'} @@ -2443,7 +3007,6 @@ packages: dependencies: tslib: 2.6.1 dev: false - optional: true /@aws-sdk/util-locate-window@3.310.0: resolution: {integrity: sha512-qo2t/vBTnoXpjKxlsC2e1gBrRm80M3bId27r0BRB2VniSSe7bL1mmzM+/HFtujm0iAxtPM+aLEflLJlJeDPg0w==} @@ -2452,7 +3015,13 @@ packages: dependencies: tslib: 2.6.1 dev: false - optional: true + + /@aws-sdk/util-middleware@3.347.0: + resolution: {integrity: sha512-8owqUA3ePufeYTUvlzdJ7Z0miLorTwx+rNol5lourGQZ9JXsVMo23+yGA7nOlFuXSGkoKpMOtn6S0BT2bcfeiw==} + engines: {node: '>=14.0.0'} + dependencies: + tslib: 2.6.1 + dev: false /@aws-sdk/util-middleware@3.357.0: resolution: {integrity: sha512-pV1krjZs7BdahZBfsCJMatE8kcor7GFsBOWrQgQDm9T0We5b5xPpOO2vxAD0RytBpY8Ky2ELs/+qXMv7l5fWIA==} @@ -2463,6 +3032,14 @@ packages: dev: false optional: true + /@aws-sdk/util-retry@3.347.0: + resolution: {integrity: sha512-NxnQA0/FHFxriQAeEgBonA43Q9/VPFQa8cfJDuT2A1YZruMasgjcltoZszi1dvoIRWSZsFTW42eY2gdOd0nffQ==} + engines: {node: '>= 14.0.0'} + dependencies: + '@aws-sdk/service-error-classification': 3.347.0 + tslib: 2.6.1 + dev: false + /@aws-sdk/util-retry@3.362.0: resolution: {integrity: sha512-LDRGKaF2EMcFEa6AlS+ilLiDEeHWyR5FN2+RHdfGQjcqn+Zdd5H6Vc0vUF5Z4PH3hXr5LPZcDh+zM7DlG22KJg==} engines: {node: '>= 14.0.0'} @@ -2496,7 +3073,14 @@ packages: dependencies: tslib: 2.6.1 dev: false - optional: true + + /@aws-sdk/util-user-agent-browser@3.347.0: + resolution: {integrity: sha512-ydxtsKVtQefgbk1Dku1q7pMkjDYThauG9/8mQkZUAVik55OUZw71Zzr3XO8J8RKvQG8lmhPXuAQ0FKAyycc0RA==} + dependencies: + '@aws-sdk/types': 3.347.0 + bowser: 2.11.0 + tslib: 2.6.1 + dev: false /@aws-sdk/util-user-agent-browser@3.357.0: resolution: {integrity: sha512-JHaWlNIUkPNvXkqeDOrqFzAlAgdwZK5mZw7FQnCRvf8tdSogpGZSkuyb9Z6rLD9gC40Srbc2nepO1cFpeMsDkA==} @@ -2508,6 +3092,20 @@ packages: dev: false optional: true + /@aws-sdk/util-user-agent-node@3.347.0: + resolution: {integrity: sha512-6X0b9qGsbD1s80PmbaB6v1/ZtLfSx6fjRX8caM7NN0y/ObuLoX8LhYnW6WlB2f1+xb4EjaCNgpP/zCf98MXosw==} + engines: {node: '>=14.0.0'} + peerDependencies: + aws-crt: '>=1.0.0' + peerDependenciesMeta: + aws-crt: + optional: true + dependencies: + '@aws-sdk/node-config-provider': 3.347.0 + '@aws-sdk/types': 3.347.0 + tslib: 2.6.1 + dev: false + /@aws-sdk/util-user-agent-node@3.357.0: resolution: {integrity: sha512-RdpQoaJWQvcS99TVgSbT451iGrlH4qpWUWFA9U1IRhxOSsmC1hz8ME7xc8nci9SREx/ZlfT3ai6LpoAzAtIEMA==} engines: {node: '>=14.0.0'} @@ -2530,7 +3128,6 @@ packages: dependencies: tslib: 2.6.1 dev: false - optional: true /@aws-sdk/util-utf8@3.310.0: resolution: {integrity: sha512-DnLfFT8uCO22uOJc0pt0DsSNau1GTisngBCDw8jQuWT5CqogMJu4b/uXmwEqfj8B3GX6Xsz8zOd6JpRlPftQoA==} @@ -2540,7 +3137,15 @@ packages: '@aws-sdk/util-buffer-from': 3.310.0 tslib: 2.6.1 dev: false - optional: true + + /@aws-sdk/util-waiter@3.347.0: + resolution: {integrity: sha512-3ze/0PkwkzUzLncukx93tZgGL0JX9NaP8DxTi6WzflnL/TEul5Z63PCruRNK0om17iZYAWKrf8q2mFoHYb4grA==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-sdk/abort-controller': 3.347.0 + '@aws-sdk/types': 3.347.0 + tslib: 2.6.1 + dev: false /@babel/cli@7.17.10(@babel/core@7.18.0): resolution: {integrity: sha512-OygVO1M2J4yPMNOW9pb+I6kFGpQK77HmG44Oz3hg8xQIl5L/2zq+ZohwAdSaqYgVwM0SfmPHZHphH4wR8qzVYw==} @@ -8699,7 +9304,6 @@ packages: '@smithy/types': 1.1.0 tslib: 2.6.1 dev: false - optional: true /@smithy/types@1.1.0: resolution: {integrity: sha512-KzmvisMmuwD2jZXuC9e65JrgsZM97y5NpDU7g347oB+Q+xQLU6hQZ5zFNNbEfwwOJHoOvEVTna+dk1h/lW7alw==} @@ -8708,7 +9312,6 @@ packages: dependencies: tslib: 2.6.1 dev: false - optional: true /@storybook/addon-a11y@6.5.16(react-dom@16.14.0)(react@16.14.0): resolution: {integrity: sha512-/e9s34o+TmEhy+Q3/YzbRJ5AJ/Sy0gjZXlvsCrcRpiQLdt5JRbN8s+Lbn/FWxy8U1Tb1wlLYlqjJ+fYi5RrS3A==} @@ -10820,6 +11423,12 @@ packages: /@types/node@8.10.66: resolution: {integrity: sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==} + /@types/nodemailer@6.4.8: + resolution: {integrity: sha512-oVsJSCkqViCn8/pEu2hfjwVO+Gb3e+eTWjg3PcjeFKRItfKpKwHphQqbYmPQrlMk+op7pNNWPbsJIEthpFN/OQ==} + dependencies: + '@types/node': 18.17.1 + dev: true + /@types/normalize-package-data@2.4.1: resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==} dev: true @@ -14240,7 +14849,6 @@ packages: resolution: {integrity: sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==} requiresBuild: true dev: false - optional: true /bowser@2.9.0: resolution: {integrity: sha512-2ld76tuLBNFekRgmJfT2+3j5MIrP6bFict8WAIT3beq+srz1gcKNAdNKMqHqauQt63NmAa88HfP1/Ypa9Er3HA==} @@ -17764,7 +18372,7 @@ packages: minimatch: 3.1.2 object.values: 1.1.6 resolve: 1.22.2 - semver: 6.3.1 + semver: 6.3.0 tsconfig-paths: 3.14.2 transitivePeerDependencies: - eslint-import-resolver-typescript @@ -18740,6 +19348,13 @@ packages: punycode: 1.4.1 dev: true + /fast-xml-parser@4.2.4: + resolution: {integrity: sha512-fbfMDvgBNIdDJLdLOwacjFAPYt67tr31H9ZhWSm45CDAxvd0I6WTlSOUo7K2P/K5sA5JgMKG64PI3DMcaFdWpQ==} + hasBin: true + dependencies: + strnum: 1.0.5 + dev: false + /fast-xml-parser@4.2.5: resolution: {integrity: sha512-B9/wizE4WngqQftFPmdaMYlXoJlJOYxGQOanC77fq9k8+Z0v5dDSVh+3glErdIROP//s/jgb7ZuxKfB8nVyo0g==} hasBin: true @@ -24249,7 +24864,7 @@ packages: loopback-datasource-juggler: 3.36.1 loopback-filters: 1.1.1 loopback-phase: 3.4.0 - nodemailer: 6.9.1 + nodemailer: 6.9.3 nodemailer-direct-transport: 3.3.2 nodemailer-stub-transport: 1.1.0 serve-favicon: 2.5.0 @@ -26000,8 +26615,8 @@ packages: resolution: {integrity: sha512-4fwl2f+647IIyuNuf6wuEMqK4oEU9FMJSYme8kPckVSr1rXIXcmI6BNcIWO+1cAK8XeexYKxYoFztam0jAwjkA==} dev: false - /nodemailer@6.9.1: - resolution: {integrity: sha512-qHw7dOiU5UKNnQpXktdgQ1d3OFgRAekuvbJLcdG5dnEo/GtcTHRYM7+UfJARdOFU9WUQO8OiIamgWPmiSFHYAA==} + /nodemailer@6.9.3: + resolution: {integrity: sha512-fy9v3NgTzBngrMFkDsKEj0r02U7jm6XfC3b52eoNV+GCrGj+s8pt5OqhiJdWKuw51zCTdiNR/IUD1z33LIIGpg==} engines: {node: '>=6.0.0'} dev: false @@ -31518,7 +32133,6 @@ packages: resolution: {integrity: sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==} requiresBuild: true dev: false - optional: true /strong-error-handler@3.5.0: resolution: {integrity: sha512-PCMOf6RYni7wMD3ytGN/TBIJdKZ/EfgItgE8tVrJNGVAf2X39L7I0r/tlDyn+1G9qfVCZL0mSeutljpkOpBy1Q==} diff --git a/sample.env b/sample.env index 02f95c31693..cbe6213935b 100644 --- a/sample.env +++ b/sample.env @@ -77,3 +77,11 @@ NODE_ENV=development PORT=3000 FCC_ENABLE_SWAGGER_UI=true FCC_ENABLE_DEV_LOGIN_MODE=true + +# Email +EMAIL_PROVIDER=nodemailer # use ses in production +# SES_ID needs to be empty for now, since the api-server will use SES in testing +# if it is set. +SES_ID= +SES_SECRET=ses_secret_from_aws +SES_REGION=us-east-1