From 23dd28b81215d794e3ce65745cf311329c34b7a9 Mon Sep 17 00:00:00 2001 From: Olli Vanhapiha Date: Tue, 13 Mar 2018 14:50:07 +0200 Subject: [PATCH 1/7] Remove our local config defaults --- src/config.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/config.js b/src/config.js index 22c6fc03..c678c8da 100644 --- a/src/config.js +++ b/src/config.js @@ -32,8 +32,7 @@ const bookingUnitType = 'line-item/night'; // script, react-scripts (and the sharetribe-scripts fork of // react-scripts) require using the REACT_APP_ prefix to avoid // exposing server secrets to the client side. -const sdkClientId = - process.env.REACT_APP_SHARETRIBE_SDK_CLIENT_ID || '08ec69f6-d37e-414d-83eb-324e94afddf0'; +const sdkClientId = process.env.REACT_APP_SHARETRIBE_SDK_CLIENT_ID; const sdkBaseUrl = process.env.REACT_APP_SHARETRIBE_SDK_BASE_URL || 'http://localhost:8088'; const currency = process.env.REACT_APP_SHARETRIBE_MARKETPLACE_CURRENCY || 'USD'; @@ -57,8 +56,7 @@ const currencyConfig = { maximumFractionDigits: 2, }; -const stripePublishableKey = - process.env.REACT_APP_STRIPE_PUBLISHABLE_KEY || 'pk_test_FWtdKPZvtrj37t45dIomssBI'; +const stripePublishableKey = process.env.REACT_APP_STRIPE_PUBLISHABLE_KEY; // Stripe only supports payments in certain countries, see full list // at https://stripe.com/global From 4d68f2a76697234e345aaf583f034e9aecb298ac Mon Sep 17 00:00:00 2001 From: Olli Vanhapiha Date: Tue, 13 Mar 2018 14:51:36 +0200 Subject: [PATCH 2/7] Document env variables in one place --- README.md | 3 ++- docs/env.md | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 docs/env.md diff --git a/README.md b/README.md index 494e3eee..86a17ddb 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,8 @@ To develop the application and to see changes live, start the frontend developme yarn run dev -**You also need to [configure Google Maps api key](./docs/google-maps.md)** +**You need to configure Client Id, Google Maps API key and Stripe +publishable API key via [environment variables](./docs/env.md).** **Known issues:** diff --git a/docs/env.md b/docs/env.md new file mode 100644 index 00000000..9e1a9d26 --- /dev/null +++ b/docs/env.md @@ -0,0 +1,34 @@ +# Environment configuration variables + +The following configuration variables can be set to control the +Starter App behaviour. Most of them have defaults that work for +development environment. For production deploys most should be set. + +| Variable | Must be set? | Default | Description | +| --------- | ------------ | ------------- | ------------------------ | +| REACT_APP_GOOGLE_MAPS_API_KEY | X | - | See: [Google Maps API key](./google-maps.md) | +| REACT_APP_SHARETRIBE_SDK_CLIENT_ID | X | - | Client ID (API key). You will get this from the Sharetribe team. | +| REACT_APP_STRIPE_PUBLISHABLE_KEY | X | - | Stripe publishable API key for generating tokens with Stripe API. | +| REACT_APP_SHARETRIBE_SDK_BASE_URL | | `http://localhost:8088` | The base url to access the Marketplace API. | +| REACT_APP_SHARETRIBE_MARKETPLACE_CURRENCY | | USD | The currency used in the Marketplace as ISO 4217 currency code. For example: USD, EUR, CAD, AUD, etc. | +| REACT_APP_CANONICAL_ROOT_URL | | `http://localhost:3000` | Canonical root url of the marketplace is running. Needed for social media sharing and SEO optimization. | +| NODE_ENV | | ? | Node env. Use 'dev' for development and 'production' for production. | +| REACT_APP_ENV | | production | TODO Didn't understand NODE_ENV vs this? | +| REACT_APP_SHARETRIBE_USING_SSL | | false | Redirect HTTP to HTTPS. | +| SERVER_SHARETRIBE_TRUST_PROXY | | false | Set when running the app behind a reverse proxy. | +| REACT_APP_PUBLIC_SENTRY_DSN | | - | See: [Error logging with Sentry](./sentry.md) | +| SERVER_SENTRY_DSN | | - | See: [Error logging with Sentry](./sentry.md) | +| REACT_APP_CSP | | - | See: [Content Security Policy (CSP)](./content-security-policy.md) | +| BASIC_AUTH_USERNAME | | - | Set to enable HTTP Basic Auth | +| BASIC_AUTH_PASSWORD | | - | Set to enable HTTP Basic Auth | +| REACT_APP_GOOGLE_ANALYTICS_ID | | - | See: [Google Analytics](./analytics.md) | + + +## Defining the env variables + +When the Starter App is started locally with `yarn run dev` you can +set environment variables by using the file +.env.development.local. However, the server process doesn't currently +pick up values from this file. In production it is recommended to set +the environment variables on OS level. + From bba6159b75e21ad6ba946b6a8ded135a8248e5ea Mon Sep 17 00:00:00 2001 From: Olli Vanhapiha Date: Tue, 13 Mar 2018 15:02:04 +0200 Subject: [PATCH 3/7] Format docs --- docs/colors-and-icons.md | 4 +- docs/customization-checklist.md | 66 ++++++++++++++++++--------------- docs/env.md | 17 +++------ docs/sentry.md | 11 +++--- 4 files changed, 50 insertions(+), 48 deletions(-) diff --git a/docs/colors-and-icons.md b/docs/colors-and-icons.md index 3615550a..7cd452d4 100644 --- a/docs/colors-and-icons.md +++ b/docs/colors-and-icons.md @@ -12,7 +12,9 @@ change the color variables: --marketplaceColorLight: #ff4c38; --marketplaceColorDark: #8c291e; ``` -N.B. search also from files color code `c0392b`. Some icons and background-images with data-URL are using it directly. + +N.B. search also from files color code `c0392b`. Some icons and background-images with data-URL are +using it directly. ## Icons diff --git a/docs/customization-checklist.md b/docs/customization-checklist.md index 49f05649..824b497e 100644 --- a/docs/customization-checklist.md +++ b/docs/customization-checklist.md @@ -1,36 +1,42 @@ - # Customization checklist Some generic things to update and check when starting to customize Starter app. -- [Marketplace colors](colors-and-icons.md#colors) -- [Generate app icons](colors-and-icons.md#icons) -- [Update translations](../src/translations/en.json) or [change the language](i18n.md) -- [LandingPage](../src/containers/LandingPage/LandingPage.js): update and create branded sections -- [Footer](../src/components/Footer/Footer.js) -- [AboutPage](../src/containers/AboutPage/AboutPage.js) -- [Terms of Service](terms-of-service-and-privacy-policy.md#terms-of-service) -- [Privacy Policy](terms-of-service-and-privacy-policy.md#privacy-policy) -- [Social media sharing graphics](../src/components/Page/Page.js); -- [Logo](../src/components/Logo/Logo.js) Change and check that it works on Topbar and Footer -- [Logo in CheckoutPage](../src/containers/CheckoutPage/LogoIcon.js) -- [Default background image](../src/assets/background-1440.jpg) -- [Maps Marker icon](../src/components/Map/Map/images/marker-32x32.png) -- [Config: update environment variables](../src/config.js) -- [Config: siteTitle](../src/config.js) for page schema (SEO) -- [Config: marketplace address](../src/config.js): contact details also improve SEO -- [Config: social media pages](../src/config.js) -- [Marketplace custom config](../src/marketplace-custom-config.js) -- Update [ListingPage](../src/containers/ListingPage/ListingPage.js) to show extended data (aka publicData attribute) -- Update [EditListingWizard](../src/components/EditListingWizard/EditListingWizard.js) and panels to add extended data -- Update [SearchPage](../src/containers/SearchPage/SearchPage.js) to filter with extended data -- Update [routeConfiguration](../src/routeConfiguration) if needed -- Update [Email templates](https://github.com/sharetribe/sharetribe-starter-app/tree/master/ext/mail-templates), all of them: .html, subject.txt, and text.txt -- Update [config: bookingUnitType](../src/config.js) if needed -- If `line-item/units` is used, add quantity handling -to [BookingDatesForm](../src/containers/BookingDatesForm/BookingDatesForm.js), [ListingPage](../src/containers/ListingPage/ListingPage.js), [CheckoutPage](../src/containers/CheckoutPage/CheckoutPage.js) +* [Marketplace colors](colors-and-icons.md#colors) +* [Generate app icons](colors-and-icons.md#icons) +* [Update translations](../src/translations/en.json) or [change the language](i18n.md) +* [LandingPage](../src/containers/LandingPage/LandingPage.js): update and create branded sections +* [Footer](../src/components/Footer/Footer.js) +* [AboutPage](../src/containers/AboutPage/AboutPage.js) +* [Terms of Service](terms-of-service-and-privacy-policy.md#terms-of-service) +* [Privacy Policy](terms-of-service-and-privacy-policy.md#privacy-policy) +* [Social media sharing graphics](../src/components/Page/Page.js); +* [Logo](../src/components/Logo/Logo.js) Change and check that it works on Topbar and Footer +* [Logo in CheckoutPage](../src/containers/CheckoutPage/LogoIcon.js) +* [Default background image](../src/assets/background-1440.jpg) +* [Maps Marker icon](../src/components/Map/Map/images/marker-32x32.png) +* [Config: update environment variables](../src/config.js) +* [Config: siteTitle](../src/config.js) for page schema (SEO) +* [Config: marketplace address](../src/config.js): contact details also improve SEO +* [Config: social media pages](../src/config.js) +* [Marketplace custom config](../src/marketplace-custom-config.js) +* Update [ListingPage](../src/containers/ListingPage/ListingPage.js) to show extended data (aka + publicData attribute) +* Update [EditListingWizard](../src/components/EditListingWizard/EditListingWizard.js) and panels to + add extended data +* Update [SearchPage](../src/containers/SearchPage/SearchPage.js) to filter with extended data +* Update [routeConfiguration](../src/routeConfiguration) if needed +* Update + [Email templates](https://github.com/sharetribe/sharetribe-starter-app/tree/master/ext/mail-templates), + all of them: .html, subject.txt, and text.txt +* Update [config: bookingUnitType](../src/config.js) if needed +* If `line-item/units` is used, add quantity handling to + [BookingDatesForm](../src/containers/BookingDatesForm/BookingDatesForm.js), + [ListingPage](../src/containers/ListingPage/ListingPage.js), + [CheckoutPage](../src/containers/CheckoutPage/CheckoutPage.js) ## What else -- Do you need more [static pages](static-pages.md)? -- Changes to existing pages -- Changes to transaction process (API + Web app) + +* Do you need more [static pages](static-pages.md)? +* Changes to existing pages +* Changes to transaction process (API + Web app) diff --git a/docs/env.md b/docs/env.md index 9e1a9d26..48578294 100644 --- a/docs/env.md +++ b/docs/env.md @@ -1,11 +1,10 @@ # Environment configuration variables -The following configuration variables can be set to control the -Starter App behaviour. Most of them have defaults that work for -development environment. For production deploys most should be set. +The following configuration variables can be set to control the Starter App behaviour. Most of them +have defaults that work for development environment. For production deploys most should be set. | Variable | Must be set? | Default | Description | -| --------- | ------------ | ------------- | ------------------------ | +| ----------------------------------------- | ------------ | ----------------------- | ------------------------------------------------------------------------------------------------------- | | REACT_APP_GOOGLE_MAPS_API_KEY | X | - | See: [Google Maps API key](./google-maps.md) | | REACT_APP_SHARETRIBE_SDK_CLIENT_ID | X | - | Client ID (API key). You will get this from the Sharetribe team. | | REACT_APP_STRIPE_PUBLISHABLE_KEY | X | - | Stripe publishable API key for generating tokens with Stripe API. | @@ -23,12 +22,8 @@ development environment. For production deploys most should be set. | BASIC_AUTH_PASSWORD | | - | Set to enable HTTP Basic Auth | | REACT_APP_GOOGLE_ANALYTICS_ID | | - | See: [Google Analytics](./analytics.md) | - ## Defining the env variables -When the Starter App is started locally with `yarn run dev` you can -set environment variables by using the file -.env.development.local. However, the server process doesn't currently -pick up values from this file. In production it is recommended to set -the environment variables on OS level. - +When the Starter App is started locally with `yarn run dev` you can set environment variables by +using the file .env.development.local. However, the server process doesn't currently pick up values +from this file. In production it is recommended to set the environment variables on OS level. diff --git a/docs/sentry.md b/docs/sentry.md index 936284ff..dae4509f 100644 --- a/docs/sentry.md +++ b/docs/sentry.md @@ -24,16 +24,15 @@ the logging logic in general. ## Source map retrieval -By default Sentry fetches the source maps for minified javascript files. However, this might now work -in case some sort of authentication, e.g. basic auth, is required to reach your application. To +By default Sentry fetches the source maps for minified javascript files. However, this might now +work in case some sort of authentication, e.g. basic auth, is required to reach your application. To circumvent this a security token can be configured to Sentry. Sentry then adds this token to the -source maps request header so that the server hosting Starter App can then be configured to let those -requests access the source maps. +source maps request header so that the server hosting Starter App can then be configured to let +those requests access the source maps. For basic auth the security token can be configured as follows: -In *Project > Settings > General > Client Security* set the following values +In _Project > Settings > General > Client Security_ set the following values * **Security token** - `Basic ` * **Security token header** - `Authorization` - From 5ae25e2e6291ba4cf32c95d40cbde6e7a46fb6f3 Mon Sep 17 00:00:00 2001 From: Olli Vanhapiha Date: Tue, 13 Mar 2018 15:19:33 +0200 Subject: [PATCH 4/7] Remove info about our local Heroku deployment --- README.md | 7 ------- 1 file changed, 7 deletions(-) diff --git a/README.md b/README.md index 86a17ddb..bd69c8de 100644 --- a/README.md +++ b/README.md @@ -58,13 +58,6 @@ To start the test watcher, run See more in the [testing documentation](docs/testing.md). -## Deployment - -The `master` branch is automatically deployed to Heroku. If you want to deploy a feature branch, -setup the `sharetribe-starter-app` Heroku app and push the feature branch: - - git push heroku my-feature-branch:master - ## License This project is licensed under the terms of the Apache-2.0 license. From 6380d7569f6cefa207b3d410f1a375e247300de6 Mon Sep 17 00:00:00 2001 From: Olli Vanhapiha Date: Thu, 15 Mar 2018 13:15:14 +0200 Subject: [PATCH 5/7] Harmonize client & server env handling * Remove defaults from multiple places in code. Put them to .env-template instead * Do not use imported config.js in server. Access process.env directly instead * Instruct using .env for local development, not .env.development.local --- .env-template | 33 +++++++++++++++++++++++++++++++ .env.development | 1 - .env.test | 2 +- .gitignore | 2 +- README.md | 9 ++++++--- docs/env.md | 47 +++++++++++++++++++++++++-------------------- docs/google-maps.md | 3 +-- package.json | 2 +- server/csp.js | 3 +-- server/env.js | 41 +++++++++++++++++++++++++++++++++++++++ server/importer.js | 1 - server/index.js | 12 +++++++----- server/sitemap.js | 13 ++++++------- src/config.js | 8 ++++---- 14 files changed, 128 insertions(+), 49 deletions(-) create mode 100644 .env-template create mode 100644 server/env.js diff --git a/.env-template b/.env-template new file mode 100644 index 00000000..bf58525f --- /dev/null +++ b/.env-template @@ -0,0 +1,33 @@ + +# Mandatory configuration +# +REACT_APP_SHARETRIBE_SDK_CLIENT_ID= +REACT_APP_GOOGLE_MAPS_API_KEY= +REACT_APP_STRIPE_PUBLISHABLE_KEY= + +# Defaults +# + +REACT_APP_SHARETRIBE_SDK_BASE_URL=http://localhost:8088 + +REACT_APP_SHARETRIBE_MARKETPLACE_CURRENCY=USD +REACT_APP_CANONICAL_ROOT_URL=http://localhost:3000 +PORT=4000 + +# This is overwritten by configuration in .env.development and +# .env.test. In production deployments use env variable and set it to +# 'production' +REACT_APP_ENV=production + + +# Options. Uncomment and set to test. +# + +# REACT_APP_SHARETRIBE_USING_SSL=true +# SERVER_SHARETRIBE_TRUST_PROXY=true +# REACT_APP_PUBLIC_SENTRY_DSN=change-me +# SERVER_SENTRY_DSN=change-me +# REACT_APP_CSP=report +# BASIC_AUTH_USERNAME=sharetribe +# BASIC_AUTH_PASSWORD=secret +# REACT_APP_GOOGLE_ANALYTICS_ID=change-me \ No newline at end of file diff --git a/.env.development b/.env.development index cff1ca7b..8e746630 100644 --- a/.env.development +++ b/.env.development @@ -1,2 +1 @@ -NODE_ENV=development REACT_APP_ENV=development diff --git a/.env.test b/.env.test index d8e17a78..fceacf8e 100644 --- a/.env.test +++ b/.env.test @@ -1,3 +1,3 @@ -NODE_ENV=test REACT_APP_ENV=test REACT_APP_SHARETRIBE_MARKETPLACE_CURRENCY=USD +REACT_APP_CANONICAL_ROOT_URL=http://localhost:3000 \ No newline at end of file diff --git a/.gitignore b/.gitignore index 8a687143..f25c23c5 100644 --- a/.gitignore +++ b/.gitignore @@ -13,4 +13,4 @@ build .DS_Store .env npm-debug.log -/.env.development.local +yarn-error.log diff --git a/README.md b/README.md index bd69c8de..22a4dfa6 100644 --- a/README.md +++ b/README.md @@ -24,13 +24,16 @@ Clone this repository and install dependencies: ## Development +**First, you need to configure Client Id, Google Maps API key and +Stripe publishable API key via [environment +variables](./docs/env.md).** The quickest way to do this is to copy +.env-template -> .env, and edit the file to add the three mandatory +configuration values. + To develop the application and to see changes live, start the frontend development server: yarn run dev -**You need to configure Client Id, Google Maps API key and Stripe -publishable API key via [environment variables](./docs/env.md).** - **Known issues:** * Adding/changing `import`s may not be synced properly with ESLint. You may see an error diff --git a/docs/env.md b/docs/env.md index 48578294..da6ecf69 100644 --- a/docs/env.md +++ b/docs/env.md @@ -3,27 +3,32 @@ The following configuration variables can be set to control the Starter App behaviour. Most of them have defaults that work for development environment. For production deploys most should be set. -| Variable | Must be set? | Default | Description | -| ----------------------------------------- | ------------ | ----------------------- | ------------------------------------------------------------------------------------------------------- | -| REACT_APP_GOOGLE_MAPS_API_KEY | X | - | See: [Google Maps API key](./google-maps.md) | -| REACT_APP_SHARETRIBE_SDK_CLIENT_ID | X | - | Client ID (API key). You will get this from the Sharetribe team. | -| REACT_APP_STRIPE_PUBLISHABLE_KEY | X | - | Stripe publishable API key for generating tokens with Stripe API. | -| REACT_APP_SHARETRIBE_SDK_BASE_URL | | `http://localhost:8088` | The base url to access the Marketplace API. | -| REACT_APP_SHARETRIBE_MARKETPLACE_CURRENCY | | USD | The currency used in the Marketplace as ISO 4217 currency code. For example: USD, EUR, CAD, AUD, etc. | -| REACT_APP_CANONICAL_ROOT_URL | | `http://localhost:3000` | Canonical root url of the marketplace is running. Needed for social media sharing and SEO optimization. | -| NODE_ENV | | ? | Node env. Use 'dev' for development and 'production' for production. | -| REACT_APP_ENV | | production | TODO Didn't understand NODE_ENV vs this? | -| REACT_APP_SHARETRIBE_USING_SSL | | false | Redirect HTTP to HTTPS. | -| SERVER_SHARETRIBE_TRUST_PROXY | | false | Set when running the app behind a reverse proxy. | -| REACT_APP_PUBLIC_SENTRY_DSN | | - | See: [Error logging with Sentry](./sentry.md) | -| SERVER_SENTRY_DSN | | - | See: [Error logging with Sentry](./sentry.md) | -| REACT_APP_CSP | | - | See: [Content Security Policy (CSP)](./content-security-policy.md) | -| BASIC_AUTH_USERNAME | | - | Set to enable HTTP Basic Auth | -| BASIC_AUTH_PASSWORD | | - | Set to enable HTTP Basic Auth | -| REACT_APP_GOOGLE_ANALYTICS_ID | | - | See: [Google Analytics](./analytics.md) | +| Variable | Must be set? | Default | Description | +| ----------------------------------------- | ------------ | --------------------- | ----------------------------------------------------------------------------------------------------------------- | +| REACT_APP_GOOGLE_MAPS_API_KEY | X | - | See: [Google Maps API key](./google-maps.md) | +| REACT_APP_SHARETRIBE_SDK_CLIENT_ID | X | - | Client ID (API key). You will get this from the Sharetribe team. | +| REACT_APP_STRIPE_PUBLISHABLE_KEY | X | - | Stripe publishable API key for generating tokens with Stripe API. Use test key (prefix pk*test*) for development. | +| REACT_APP_SHARETRIBE_SDK_BASE_URL | | http://localhost:8088 | The base url to access the Sharetribe Flex Marketplace API. | +| REACT_APP_SHARETRIBE_MARKETPLACE_CURRENCY | | USD | The currency used in the Marketplace as ISO 4217 currency code. For example: USD, EUR, CAD, AUD, etc. | +| REACT_APP_CANONICAL_ROOT_URL | | http://localhost:3000 | Canonical root url of the marketplace. Needed for social media sharing and SEO optimization. | +| NODE_ENV | | ? | Node env. Use 'development' for development and 'production' for production. | +| PORT | | 4000 | Port for server to accept connections. | +| REACT_APP_ENV | | production | Env for client side. Use the same value as with NODE_ENV. | +| REACT_APP_SHARETRIBE_USING_SSL | | false | Redirect HTTP to HTTPS? | +| SERVER_SHARETRIBE_TRUST_PROXY | | false | Set when running the app behind a reverse proxy, e.g. in Heroku. | +| REACT_APP_PUBLIC_SENTRY_DSN | | - | See: [Error logging with Sentry](./sentry.md) | +| SERVER_SENTRY_DSN | | - | See: [Error logging with Sentry](./sentry.md) | +| REACT_APP_CSP | | - | See: [Content Security Policy (CSP)](./content-security-policy.md) | +| BASIC_AUTH_USERNAME | | - | Set to enable HTTP Basic Auth | +| BASIC_AUTH_PASSWORD | | - | Set to enable HTTP Basic Auth | +| REACT_APP_GOOGLE_ANALYTICS_ID | | - | See: [Google Analytics](./analytics.md) | ## Defining the env variables -When the Starter App is started locally with `yarn run dev` you can set environment variables by -using the file .env.development.local. However, the server process doesn't currently pick up values -from this file. In production it is recommended to set the environment variables on OS level. +When the Starter App is started locally with `yarn run dev` or `yarn run dev-server`, you can set +environment variables by using the file .env file. The repository contains a template file +.env-template. Just copy that as .env and edit as necessary. + +In production, it's recommended that you set the configuration via env variables and do not deploy +an .env file. The client application will only be packaged with env variables that start with +REACT_APP. This way server secrets don't end up in client bundles. diff --git a/docs/google-maps.md b/docs/google-maps.md index 8104697b..1c9814d2 100644 --- a/docs/google-maps.md +++ b/docs/google-maps.md @@ -20,8 +20,7 @@ section of the Places library documentation to enable using the Google Places AP ## Setup the application to use the API key The application uses the `REACT_APP_GOOGLE_MAPS_API_KEY` environment variable for the key value. For -local development, you can add the variable in the Gitignored `.env.development.local` file in the -project root: +local development, you can add the variable in the Gitignored `.env` file in the project root: ``` REACT_APP_GOOGLE_MAPS_API_KEY=my-key-here diff --git a/package.json b/package.json index 3dbf651d..82bcada9 100644 --- a/package.json +++ b/package.json @@ -66,7 +66,7 @@ "test-ci": "sharetribe-scripts test --env=jsdom --runInBand", "eject": "sharetribe-scripts eject", "start": "node server/index.js", - "dev-server": "export REACT_APP_ENV=development REACT_APP_CANONICAL_ROOT_URL=http://localhost:4000&&yarn run build&&nodemon --watch server server/index.js", + "dev-server": "export NODE_ENV=development REACT_APP_CANONICAL_ROOT_URL=http://localhost:4000&&yarn run build&&nodemon --watch server server/index.js", "heroku-prebuild": "./heroku-copy-ssh-key-from-env.sh", "heroku-postbuild": "yarn run build", "audit": "nsp check --preprocessor yarn" diff --git a/server/csp.js b/server/csp.js index 6c079b38..8f160125 100644 --- a/server/csp.js +++ b/server/csp.js @@ -1,5 +1,4 @@ const helmet = require('helmet'); -const { config } = require('./importer'); const dev = process.env.REACT_APP_ENV === 'development'; const googleAnalyticsEnabled = !!process.env.REACT_APP_GOOGLE_ANALYTICS_ID; @@ -21,7 +20,7 @@ module.exports = (reportUri, enforceSsl, reportOnly) => { const self = "'self'"; const inline = "'unsafe-inline'"; const data = 'data:'; - const sharetribeApi = config.sdk.baseUrl; + const sharetribeApi = process.env.REACT_APP_SHARETRIBE_SDK_BASE_URL; const sharetribeAssets = 'https://assets-sharetribecom.sharetribe.com/'; const imgix = '*.imgix.net/'; const loremPixel = 'https://lorempixel.com/'; diff --git a/server/env.js b/server/env.js new file mode 100644 index 00000000..9fe75209 --- /dev/null +++ b/server/env.js @@ -0,0 +1,41 @@ +/** + Implements .env file loading that mimicks the way create-react-app + does it. We want this to get consistent configuration handling + between client and node server. +*/ + +const fs = require('fs'); + +const NODE_ENV = process.env.NODE_ENV; + +if (!NODE_ENV) { + throw new Error('The NODE_ENV environment variable is required but was not specified.'); +} + +// https://github.com/bkeepers/dotenv#what-other-env-files-can-i-use +var dotenvFiles = [ + `.env.${NODE_ENV}.local`, + `.env.${NODE_ENV}`, + // Don't include `.env.local` for `test` environment + // since normally you expect tests to produce the same + // results for everyone + NODE_ENV !== 'test' && `env.local`, + '.env', +].filter(Boolean); + +const configureEnv = () => { + // Load environment variables from .env* files. Suppress warnings using silent + // if this file is missing. dotenv will never modify any environment variables + // that have already been set. + // https://github.com/motdotla/dotenv + dotenvFiles.forEach(dotenvFile => { + if (fs.existsSync(dotenvFile)) { + console.log('Loading env from file:' + dotenvFile); + require('dotenv').config({ path: dotenvFile }); + } + }); +}; + +module.exports = { + configureEnv: configureEnv, +}; diff --git a/server/importer.js b/server/importer.js index f572bcac..83eb744f 100644 --- a/server/importer.js +++ b/server/importer.js @@ -17,5 +17,4 @@ module.exports = { matchPathname: mainJs.matchPathname, configureStore: mainJs.configureStore, routeConfiguration: mainJs.routeConfiguration, - config: mainJs.config, }; diff --git a/server/index.js b/server/index.js index 44c9da50..a0fd6b52 100644 --- a/server/index.js +++ b/server/index.js @@ -16,6 +16,9 @@ // This enables nice stacktraces from the minified production bundle require('source-map-support').install(); +// Configure process.env with .env.* files +require('./env').configureEnv(); + const express = require('express'); const helmet = require('helmet'); const compression = require('compression'); @@ -35,12 +38,11 @@ const { sitemapStructure } = require('./sitemap'); const csp = require('./csp'); const buildPath = path.resolve(__dirname, '..', 'build'); -const env = process.env.REACT_APP_ENV || 'production'; +const env = process.env.REACT_APP_ENV; const dev = process.env.REACT_APP_ENV === 'development'; -const PORT = process.env.PORT || 4000; -const CLIENT_ID = - process.env.REACT_APP_SHARETRIBE_SDK_CLIENT_ID || '08ec69f6-d37e-414d-83eb-324e94afddf0'; -const BASE_URL = process.env.REACT_APP_SHARETRIBE_SDK_BASE_URL || 'http://localhost:8088'; +const PORT = process.env.PORT; +const CLIENT_ID = process.env.REACT_APP_SHARETRIBE_SDK_CLIENT_ID; +const BASE_URL = process.env.REACT_APP_SHARETRIBE_SDK_BASE_URL; const USING_SSL = process.env.REACT_APP_SHARETRIBE_USING_SSL === 'true'; const TRUST_PROXY = process.env.SERVER_SHARETRIBE_TRUST_PROXY || null; const CSP = process.env.REACT_APP_CSP; diff --git a/server/sitemap.js b/server/sitemap.js index 4b9825c7..fec85b3d 100644 --- a/server/sitemap.js +++ b/server/sitemap.js @@ -1,9 +1,8 @@ const path = require('path'); const moment = require('moment'); -const { config } = require('./importer'); const buildPath = path.resolve(__dirname, '..', 'build'); -const PORT = process.env.PORT || 4000; +const PORT = process.env.PORT; const USING_SSL = process.env.REACT_APP_SHARETRIBE_USING_SSL === 'true'; /** @@ -44,17 +43,17 @@ const port = rootURL => { }; /** - * Return a structure for sitemap.xml and robots.txt to be - * used by the express-sitemap library. Uses the canonical - * URL value from config for domain and port information. + * Return a structure for sitemap.xml and robots.txt to be used by the + * express-sitemap library. Uses the canonical URL value from env + * config for domain and port information. */ exports.sitemapStructure = () => { const now = moment().format('YYYY-MM-DD'); return { - url: domain(config.canonicalRootURL), + url: domain(process.env.REACT_APP_CANONICAL_ROOT_URL), http: USING_SSL ? 'https' : 'http', - port: port(config.canonicalRootURL), + port: port(process.env.REACT_APP_CANONICAL_ROOT_URL), sitemap: path.join(buildPath, 'static', 'sitemap.xml'), robots: path.join(buildPath, 'robots.txt'), sitemapSubmission: '/static/sitemap.xml', diff --git a/src/config.js b/src/config.js index c678c8da..0d0972af 100644 --- a/src/config.js +++ b/src/config.js @@ -1,6 +1,6 @@ import * as custom from './marketplace-custom-config.js'; -const env = process.env.REACT_APP_ENV || 'production'; +const env = process.env.REACT_APP_ENV; const dev = process.env.REACT_APP_ENV === 'development'; // If you want to change the language, remember to also change the @@ -33,9 +33,9 @@ const bookingUnitType = 'line-item/night'; // react-scripts) require using the REACT_APP_ prefix to avoid // exposing server secrets to the client side. const sdkClientId = process.env.REACT_APP_SHARETRIBE_SDK_CLIENT_ID; -const sdkBaseUrl = process.env.REACT_APP_SHARETRIBE_SDK_BASE_URL || 'http://localhost:8088'; +const sdkBaseUrl = process.env.REACT_APP_SHARETRIBE_SDK_BASE_URL; -const currency = process.env.REACT_APP_SHARETRIBE_MARKETPLACE_CURRENCY || 'USD'; +const currency = process.env.REACT_APP_SHARETRIBE_MARKETPLACE_CURRENCY; // Sentry DSN (Data Source Name), a client key for authenticating calls to Sentry const sentryDsn = process.env.REACT_APP_PUBLIC_SENTRY_DSN; @@ -219,7 +219,7 @@ const postalCode = '00100'; const streetAddress = 'Bulevardi 14'; // Canonical root url is needed in social media sharing and SEO optimization purposes. -const canonicalRootURL = process.env.REACT_APP_CANONICAL_ROOT_URL || 'http://localhost:3000'; +const canonicalRootURL = process.env.REACT_APP_CANONICAL_ROOT_URL; // Site title is needed in meta tags (bots and social media sharing reads those) const siteTitle = 'Saunatime'; From d55cc7b2502edf8c81ec27c99d7f61f52297479f Mon Sep 17 00:00:00 2001 From: Olli Vanhapiha Date: Thu, 15 Mar 2018 22:25:47 +0200 Subject: [PATCH 6/7] Revert PORT handling to previous behaviour --- .env-template | 1 - .env.development | 1 + .env.test | 3 ++- README.md | 2 +- docs/env.md | 51 +++++++++++++++++++++++++++--------------------- package.json | 2 +- 6 files changed, 34 insertions(+), 26 deletions(-) diff --git a/.env-template b/.env-template index bf58525f..b639a6b6 100644 --- a/.env-template +++ b/.env-template @@ -12,7 +12,6 @@ REACT_APP_SHARETRIBE_SDK_BASE_URL=http://localhost:8088 REACT_APP_SHARETRIBE_MARKETPLACE_CURRENCY=USD REACT_APP_CANONICAL_ROOT_URL=http://localhost:3000 -PORT=4000 # This is overwritten by configuration in .env.development and # .env.test. In production deployments use env variable and set it to diff --git a/.env.development b/.env.development index 8e746630..5a86b627 100644 --- a/.env.development +++ b/.env.development @@ -1 +1,2 @@ REACT_APP_ENV=development + diff --git a/.env.test b/.env.test index fceacf8e..21dd1f79 100644 --- a/.env.test +++ b/.env.test @@ -1,3 +1,4 @@ REACT_APP_ENV=test REACT_APP_SHARETRIBE_MARKETPLACE_CURRENCY=USD -REACT_APP_CANONICAL_ROOT_URL=http://localhost:3000 \ No newline at end of file +REACT_APP_CANONICAL_ROOT_URL=http://localhost:3000 + diff --git a/README.md b/README.md index 22a4dfa6..998a6602 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ Clone this repository and install dependencies: **First, you need to configure Client Id, Google Maps API key and Stripe publishable API key via [environment variables](./docs/env.md).** The quickest way to do this is to copy -.env-template -> .env, and edit the file to add the three mandatory +`.env-template` -> `.env`, and edit the file to set the three mandatory configuration values. To develop the application and to see changes live, start the frontend development server: diff --git a/docs/env.md b/docs/env.md index da6ecf69..60c78ab2 100644 --- a/docs/env.md +++ b/docs/env.md @@ -3,32 +3,39 @@ The following configuration variables can be set to control the Starter App behaviour. Most of them have defaults that work for development environment. For production deploys most should be set. -| Variable | Must be set? | Default | Description | -| ----------------------------------------- | ------------ | --------------------- | ----------------------------------------------------------------------------------------------------------------- | -| REACT_APP_GOOGLE_MAPS_API_KEY | X | - | See: [Google Maps API key](./google-maps.md) | -| REACT_APP_SHARETRIBE_SDK_CLIENT_ID | X | - | Client ID (API key). You will get this from the Sharetribe team. | -| REACT_APP_STRIPE_PUBLISHABLE_KEY | X | - | Stripe publishable API key for generating tokens with Stripe API. Use test key (prefix pk*test*) for development. | -| REACT_APP_SHARETRIBE_SDK_BASE_URL | | http://localhost:8088 | The base url to access the Sharetribe Flex Marketplace API. | -| REACT_APP_SHARETRIBE_MARKETPLACE_CURRENCY | | USD | The currency used in the Marketplace as ISO 4217 currency code. For example: USD, EUR, CAD, AUD, etc. | -| REACT_APP_CANONICAL_ROOT_URL | | http://localhost:3000 | Canonical root url of the marketplace. Needed for social media sharing and SEO optimization. | -| NODE_ENV | | ? | Node env. Use 'development' for development and 'production' for production. | -| PORT | | 4000 | Port for server to accept connections. | -| REACT_APP_ENV | | production | Env for client side. Use the same value as with NODE_ENV. | -| REACT_APP_SHARETRIBE_USING_SSL | | false | Redirect HTTP to HTTPS? | -| SERVER_SHARETRIBE_TRUST_PROXY | | false | Set when running the app behind a reverse proxy, e.g. in Heroku. | -| REACT_APP_PUBLIC_SENTRY_DSN | | - | See: [Error logging with Sentry](./sentry.md) | -| SERVER_SENTRY_DSN | | - | See: [Error logging with Sentry](./sentry.md) | -| REACT_APP_CSP | | - | See: [Content Security Policy (CSP)](./content-security-policy.md) | -| BASIC_AUTH_USERNAME | | - | Set to enable HTTP Basic Auth | -| BASIC_AUTH_PASSWORD | | - | Set to enable HTTP Basic Auth | -| REACT_APP_GOOGLE_ANALYTICS_ID | | - | See: [Google Analytics](./analytics.md) | +| Variable | Description | +| ----------------------------------------- | ----------------------------------------------------------------------------------------------------------------- | +| REACT_APP_GOOGLE_MAPS_API_KEY | See: [Google Maps API key](./google-maps.md) | +| REACT_APP_SHARETRIBE_SDK_CLIENT_ID | Client ID (API key). You will get this from the Sharetribe team. | +| REACT_APP_STRIPE_PUBLISHABLE_KEY | Stripe publishable API key for generating tokens with Stripe API. Use test key (prefix pk*test*) for development. | +| REACT_APP_SHARETRIBE_SDK_BASE_URL | The base url to access the Sharetribe Flex Marketplace API. | +| REACT_APP_SHARETRIBE_MARKETPLACE_CURRENCY | The currency used in the Marketplace as ISO 4217 currency code. For example: USD, EUR, CAD, AUD, etc. | +| REACT_APP_CANONICAL_ROOT_URL | Canonical root url of the marketplace. Needed for social media sharing and SEO optimization. | +| NODE_ENV | Node env. Use 'development' for development and 'production' for production. | +| PORT | Port for server to accept connections. | +| REACT_APP_ENV | Env for client side. Use the same value as with NODE_ENV. | +| REACT_APP_SHARETRIBE_USING_SSL | Redirect HTTP to HTTPS? | +| SERVER_SHARETRIBE_TRUST_PROXY | Set when running the app behind a reverse proxy, e.g. in Heroku. | +| REACT_APP_PUBLIC_SENTRY_DSN | See: [Error logging with Sentry](./sentry.md) | +| SERVER_SENTRY_DSN | See: [Error logging with Sentry](./sentry.md) | +| REACT_APP_CSP | See: [Content Security Policy (CSP)](./content-security-policy.md) | +| BASIC_AUTH_USERNAME | Set to enable HTTP Basic Auth | +| BASIC_AUTH_PASSWORD | Set to enable HTTP Basic Auth | +| REACT_APP_GOOGLE_ANALYTICS_ID | See: [Google Analytics](./analytics.md) | -## Defining the env variables +## Defining configuration When the Starter App is started locally with `yarn run dev` or `yarn run dev-server`, you can set -environment variables by using the file .env file. The repository contains a template file -.env-template. Just copy that as .env and edit as necessary. +environment variables by using the (gitignored) `.env` file. The repository contains a template file +`.env-template` with default configuration. Just copy that as `.env` and edit as necessary. In production, it's recommended that you set the configuration via env variables and do not deploy an .env file. The client application will only be packaged with env variables that start with REACT_APP. This way server secrets don't end up in client bundles. + +**With deploys note that the configuration options are bundled in the +client at build time.**** The configuration of the build environment +must match run environment for things to work consistently. To apply +changes to configuration values client bundle must be rebuilt. Just +restarting the server is not enough. + diff --git a/package.json b/package.json index 82bcada9..51d916c2 100644 --- a/package.json +++ b/package.json @@ -66,7 +66,7 @@ "test-ci": "sharetribe-scripts test --env=jsdom --runInBand", "eject": "sharetribe-scripts eject", "start": "node server/index.js", - "dev-server": "export NODE_ENV=development REACT_APP_CANONICAL_ROOT_URL=http://localhost:4000&&yarn run build&&nodemon --watch server server/index.js", + "dev-server": "export NODE_ENV=development PORT=4000 REACT_APP_CANONICAL_ROOT_URL=http://localhost:4000&&yarn run build&&nodemon --watch server server/index.js", "heroku-prebuild": "./heroku-copy-ssh-key-from-env.sh", "heroku-postbuild": "yarn run build", "audit": "nsp check --preprocessor yarn" From 42aeefd48722ca0202041c571f5bc83286d55399 Mon Sep 17 00:00:00 2001 From: Olli Vanhapiha Date: Thu, 15 Mar 2018 22:30:38 +0200 Subject: [PATCH 7/7] Ensure PORT is an integer --- docs/env.md | 8 ++++---- server/index.js | 2 +- server/sitemap.js | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/env.md b/docs/env.md index 60c78ab2..33e28982 100644 --- a/docs/env.md +++ b/docs/env.md @@ -34,8 +34,8 @@ an .env file. The client application will only be packaged with env variables th REACT_APP. This way server secrets don't end up in client bundles. **With deploys note that the configuration options are bundled in the -client at build time.**** The configuration of the build environment -must match run environment for things to work consistently. To apply -changes to configuration values client bundle must be rebuilt. Just -restarting the server is not enough. +client package at build time.** The configuration of the build +environment must match run environment for things to work +consistently. To apply changes to configuration values client bundle +must be rebuilt. Just restarting the server is not enough. diff --git a/server/index.js b/server/index.js index a0fd6b52..bd9d9fac 100644 --- a/server/index.js +++ b/server/index.js @@ -40,7 +40,7 @@ const csp = require('./csp'); const buildPath = path.resolve(__dirname, '..', 'build'); const env = process.env.REACT_APP_ENV; const dev = process.env.REACT_APP_ENV === 'development'; -const PORT = process.env.PORT; +const PORT = parseInt(process.env.PORT, 10); const CLIENT_ID = process.env.REACT_APP_SHARETRIBE_SDK_CLIENT_ID; const BASE_URL = process.env.REACT_APP_SHARETRIBE_SDK_BASE_URL; const USING_SSL = process.env.REACT_APP_SHARETRIBE_USING_SSL === 'true'; diff --git a/server/sitemap.js b/server/sitemap.js index fec85b3d..e3d10139 100644 --- a/server/sitemap.js +++ b/server/sitemap.js @@ -2,7 +2,7 @@ const path = require('path'); const moment = require('moment'); const buildPath = path.resolve(__dirname, '..', 'build'); -const PORT = process.env.PORT; +const PORT = parseInt(process.env.PORT, 10); const USING_SSL = process.env.REACT_APP_SHARETRIBE_USING_SSL === 'true'; /**