diff --git a/README.md b/README.md index e95309e3..56a45ef6 100644 --- a/README.md +++ b/README.md @@ -46,11 +46,29 @@ The following branch naming patterns are utilized for different kinds of efforts - Testing: `test/*` - Refactoring: `refactor/*` -## Operations +## Operations & Deployment + +The [GitHub Actions CI](.github/workflows/ci.yml) workflow is used to automate the deployment of the app in accordance with the branching strategy described above. The infrastructure required for an instance of the application is: + +1. A MongoDB compatible database. We use CosmosDB with MongoDB driver. +2. A NodeJS web-server environment for the [GraphQL API](packages/api). +3. A static website deployment (Azure Blob Storage/S3) for the [web application](packages/webapp). This may be CDN-hosted or self-hosted in static storage. +4. A SendGrid account for sending automated emails (e.g. password reset emails). +5. (_optional_) A Firebase account for In-App Notifications. ### Configuration -### External Dependencies +The application uses the [config](npm.im/config) package to manage configuration settings per hosted environment. The following environment variables may be defined to override configuration settings: -- Firebase -- Sendgrid +- API [environment variables](packages/api/config/custom-environment-variables.md) + + - DB*CONNECTION_STRING (\_required*): The MongoDB connection string for the database. + - JWT*SECRET (\_stronly recommended*): A secret, random string used for salting JWT tokens. + - SENDGRID*API_KEY (\_required for email*): The SendGrid API key. + - EMAIL*FROM (\_required for email*): The email address used for sending automated emails. + - CONTACT*US_EMAIL (\_required for email*): The email address used for customer support. + - PORT (_optional_): the port the application is running on. This is provided by default from the Azure App Service runtime. + +- Web App [environment variables](packages/webapp/config/custom-environment-variables.md) + - API*URL (\_required*): The URL of the GraphQL API this webapp will communicate with. + - SOCKET*URL (\_required*): The URL of the sockets API this webapp will communicate with. diff --git a/packages/api/config/custom-environment-variables.json b/packages/api/config/custom-environment-variables.json index 0f8e213d..7431aa33 100644 --- a/packages/api/config/custom-environment-variables.json +++ b/packages/api/config/custom-environment-variables.json @@ -9,15 +9,8 @@ "security": { "jwtSecret": "JWT_SECRET" }, - "smtp": { - "port": "SMTP_PORT", - "host": "SMTP_HOST", - "auth": { - "user": "SMTP_USER", - "pass": "SMTP_PASSWORD" - } - }, "email": { + "sendgridApiKey": "SENDGRID_API_KEY", "from": "EMAIL_FROM", "contactUs": "CONTACT_US_EMAIL" } diff --git a/packages/api/config/default.json b/packages/api/config/default.json index 78a40e75..66259b00 100644 --- a/packages/api/config/default.json +++ b/packages/api/config/default.json @@ -24,17 +24,8 @@ "security": { "jwtSecret": "greenlight-development" }, - "smtp": { - "pool": true, - "host": null, - "port": 465, - "secure": true, - "auth": { - "user": null, - "pass": null - } - }, "email": { + "sendgridApiKey": null, "from": null, "contactUs": null } diff --git a/packages/api/src/components/AppContextProvider.ts b/packages/api/src/components/AppContextProvider.ts index 59524e4e..b6c922c9 100644 --- a/packages/api/src/components/AppContextProvider.ts +++ b/packages/api/src/components/AppContextProvider.ts @@ -38,7 +38,7 @@ export class AppContextProvider implements AsyncProvider { const mailer = nodemailer.createTransport( sgTransport({ auth: { - api_key: config.smtpDetails.auth.pass + api_key: config.sendgridApiKey } }) ) diff --git a/packages/api/src/components/Configuration.ts b/packages/api/src/components/Configuration.ts index 67168127..b237df86 100644 --- a/packages/api/src/components/Configuration.ts +++ b/packages/api/src/components/Configuration.ts @@ -21,14 +21,8 @@ export class Configuration { if (this.jwtTokenSecret == null) { throw new Error('JWT_SECRET must be defined') } - if (!this.smtpDetails.auth.user) { - console.warn('SMTP_USER is not set, mail disabled') - } - if (!this.smtpDetails.auth.pass) { - console.warn('SMTP_PASSWORD is not set, mail disabled') - } - if (!this.smtpDetails.host) { - console.warn('SMTP_HOST is not set, mail disabled') + if (!this.sendgridApiKey) { + console.warn('SENDGRID_API_KEY is not set, mail disabled') } if (!this.defaultFromAddress) { console.warn('EMAIL_FROM is not set, mail disabled') @@ -95,8 +89,8 @@ export class Configuration { return this.c.get('security.jwtSecret') } - public get smtpDetails(): any { - return this.c.get('smtp') + public get sendgridApiKey(): any { + return this.c.get('email.sendgridApiKey') } public get defaultFromAddress(): string { diff --git a/packages/api/src/utils/isSendMailConfigured.ts b/packages/api/src/utils/isSendMailConfigured.ts index dbefc9ee..4cdf0f97 100644 --- a/packages/api/src/utils/isSendMailConfigured.ts +++ b/packages/api/src/utils/isSendMailConfigured.ts @@ -5,8 +5,5 @@ import { Configuration } from '~components' export function isSendMailConfigured(config: Configuration): boolean { - const mailConfig = config.smtpDetails - return ( - !!mailConfig?.host && !!mailConfig?.port && !!mailConfig?.auth?.user && !!mailConfig?.auth?.pass - ) + return !!config.sendgridApiKey } diff --git a/packages/webapp/config/custom-environment-variables.json b/packages/webapp/config/custom-environment-variables.json index e711ced8..8926bad9 100644 --- a/packages/webapp/config/custom-environment-variables.json +++ b/packages/webapp/config/custom-environment-variables.json @@ -1,9 +1,4 @@ { - "server": { - "port": "PORT", - "sslToken": "SSL_TOKEN", - "sslVerificationMode": "SSL_VERIFICATION_MODE" - }, "api": { "url": "API_URL", "socketUrl": "API_SOCKET_URL"