diff options
-rw-r--r-- | README.md | 7 | ||||
-rw-r--r-- | app.js | 15 | ||||
-rw-r--r-- | app.json | 17 | ||||
-rw-r--r-- | config.json.example | 9 | ||||
-rw-r--r-- | lib/config/default.js | 6 | ||||
-rw-r--r-- | lib/config/environment.js | 6 | ||||
-rw-r--r-- | public/docs/features.md | 15 |
7 files changed, 62 insertions, 13 deletions
@@ -154,6 +154,10 @@ Environment variables (will overwrite other server configs) | HMD_S3_SECRET_ACCESS_KEY | no example | AWS secret key | | HMD_S3_REGION | `ap-northeast-1` | AWS S3 region | | HMD_S3_BUCKET | no example | AWS S3 bucket name | +| HMD_HSTS_ENABLE | ` true` | set to enable [HSTS](https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security) if HTTPS is also enabled (default is ` true`) | +| HMD_HSTS_INCLUDE_SUBDOMAINS | `true` | set to include subdomains in HSTS (default is `true`) | +| HMD_HSTS_MAX_AGE | `31536000` | max duration in seconds to tell clients to keep HSTS status (default is a year) | +| HMD_HSTS_PRELOAD | `true` | whether to allow preloading of the site's HSTS status (e.g. into browsers) | Application settings `config.json` --- @@ -166,6 +170,7 @@ Application settings `config.json` | port | `80` | web app port | | alloworigin | `['localhost']` | domain name whitelist | | usessl | `true` or `false` | set to use ssl server (if true will auto turn on `protocolusessl`) | +| hsts | `{"enable": "true", "maxAgeSeconds": "31536000", "includeSubdomains": "true", "preload": "true"}` | [HSTS](https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security) options to use with HTTPS (default is the example value, max age is a year) | | protocolusessl | `true` or `false` | set to use ssl protocol for resources path (only applied when domain is set) | | urladdport | `true` or `false` | set to add port on callback url (port 80 or 443 won't applied) (only applied when domain is set) | | usecdn | `true` or `false` | set to use CDN resources or not (default is `true`) | @@ -196,7 +201,7 @@ Application settings `config.json` | email | `true` or `false` | set to allow email signin | | allowemailregister | `true` or `false` | set to allow email register (only applied when email is set, default is `true`) | | imageUploadType | `imgur`(default), `s3` or `filesystem` | Where to upload image -| s3 | `{ "accessKeyId": "YOUR_S3_ACCESS_KEY_ID", "secretAccessKey": "YOUR_S3_ACCESS_KEY", "region": "YOUR_S3_REGION" }` | When `imageUploadType` be setted to `s3`, you would also need to setup this key, check our [S3 Image Upload Guide](docs/guides/s3-image-upload.md) | +| s3 | `{ "accessKeyId": "YOUR_S3_ACCESS_KEY_ID", "secretAccessKey": "YOUR_S3_ACCESS_KEY", "region": "YOUR_S3_REGION" }` | When `imageUploadType` be set to `s3`, you would also need to setup this key, check our [S3 Image Upload Guide](docs/guides/s3-image-upload.md) | | s3bucket | `YOUR_S3_BUCKET_NAME` | bucket name when `imageUploadType` is set to `s3` | Third-party integration api key settings @@ -97,11 +97,16 @@ var sessionStore = new SequelizeStore({ app.use(compression()) // use hsts to tell https users stick to this -app.use(helmet.hsts({ - maxAge: 31536000 * 1000, // 365 days - includeSubdomains: true, - preload: true -})) +if (config.hsts.enable) { + app.use(helmet.hsts({ + maxAge: config.hsts.maxAgeSeconds * 1000, + includeSubdomains: config.hsts.includeSubdomains, + preload: config.hsts.preload + })) +} else if (config.usessl) { + logger.info('Consider enabling HSTS for extra security:') + logger.info('https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security') +} i18n.configure({ locales: ['en', 'zh', 'fr', 'de', 'ja', 'es', 'ca', 'el', 'pt', 'it', 'tr', 'ru', 'nl', 'hr', 'pl', 'uk', 'hi', 'sv', 'eo', 'da'], @@ -23,7 +23,22 @@ "description": "Specify database type. See sequelize available databases. Default using postgres", "value": "postgres" }, - + "HMD_HSTS_ENABLE": { + "description": "whether to also use HSTS if HTTPS is enabled", + "required": false + }, + "HMD_HSTS_MAX_AGE": { + "description": "max duration, in seconds, to tell clients to keep HSTS status", + "required": false + }, + "HMD_HSTS_INCLUDE_SUBDOMAINS": { + "description": "whether to tell clients to also regard subdomains as HSTS hosts", + "required": false + }, + "HMD_HSTS_PRELOAD": { + "description": "whether to allow at all adding of the site to HSTS preloads (e.g. in browsers)", + "required": false + }, "HMD_DOMAIN": { "description": "domain name", "required": false diff --git a/config.json.example b/config.json.example index 87c04ed0..e2d774c7 100644 --- a/config.json.example +++ b/config.json.example @@ -6,6 +6,9 @@ } }, "development": { + "hsts": { + "enable": false + }, "db": { "dialect": "sqlite", "storage": "./db.hackmd.sqlite" @@ -13,6 +16,12 @@ }, "production": { "domain": "localhost", + "hsts": { + "enable": "true", + "maxAgeSeconds": "31536000", + "includeSubdomains": "true", + "preload": "true" + }, "db": { "username": "", "password": "", diff --git a/lib/config/default.js b/lib/config/default.js index a14a4294..f4c45e3d 100644 --- a/lib/config/default.js +++ b/lib/config/default.js @@ -7,6 +7,12 @@ module.exports = { urladdport: false, alloworigin: ['localhost'], usessl: false, + hsts: { + enable: true, + maxAgeSeconds: 31536000, + includeSubdomains: true, + preload: true + }, protocolusessl: false, usecdn: true, allowanonymous: true, diff --git a/lib/config/environment.js b/lib/config/environment.js index c108a6f9..40b7e09f 100644 --- a/lib/config/environment.js +++ b/lib/config/environment.js @@ -8,6 +8,12 @@ module.exports = { port: process.env.HMD_PORT, urladdport: toBooleanConfig(process.env.HMD_URL_ADDPORT), usessl: toBooleanConfig(process.env.HMD_USESSL), + hsts: { + enable: toBooleanConfig(process.env.HMD_HSTS_ENABLE), + maxAgeSeconds: process.env.HMD_HSTS_MAX_AGE, + includeSubdomains: toBooleanConfig(process.env.HMD_HSTS_INCLUDE_SUBDOMAINS), + preload: toBooleanConfig(process.env.HMD_HSTS_PRELOAD) + }, protocolusessl: toBooleanConfig(process.env.HMD_PROTOCOL_USESSL), alloworigin: process.env.HMD_ALLOW_ORIGIN ? process.env.HMD_ALLOW_ORIGIN.split(',') : undefined, usecdn: toBooleanConfig(process.env.HMD_USECDN), diff --git a/public/docs/features.md b/public/docs/features.md index b64b988e..a894c087 100644 --- a/public/docs/features.md +++ b/public/docs/features.md @@ -47,12 +47,15 @@ or import content from your **clipboard** <i class="fa fa-clipboard"></i>, and t It is possible to change the access permission to a note through the little button on the top right of the view. There are four possible options: -<i class="fa fa-leaf fa-fw"></i> **Freely**: Anyone can edit this note. -<i class="fa fa-pencil fa-fw"></i> **Editable**: A signed-in user can edit this note. -<i class="fa fa-id-card fa-fw"></i> **Limited**: People have to sign-in to view and edit this note. -<i class="fa fa-lock fa-fw"></i> **Locked**: Anyone can view this note but only the owner can edit it. -<i class="fa fa-umbrella fa-fw"></i> **Protected**: People have to sign-in to view this note but only owner can edit. -<i class="fa fa-hand-stop-o fa-fw"></i> **Private**: Only the owner can view and edit this note. +| |Owner read/write|Signed-in read|Signed-in write|Guest read|Guest write| +|:-----------------------------|:--------------:|:------------:|:-------------:|:--------:|:---------:| +|<span class="text-nowrap"><i class="fa fa-leaf fa-fw"></i> **Freely**</span> |✔|✔|✔|✔|✔| +|<span class="text-nowrap"><i class="fa fa-pencil fa-fw"></i> **Editable**</span> |✔|✔|✔|✔|✖| +|<span class="text-nowrap"><i class="fa fa-id-card fa-fw"></i> **Limited**</span> |✔|✔|✔|✖|✖| +|<span class="text-nowrap"><i class="fa fa-lock fa-fw"></i> **Locked**</span> |✔|✔|✖|✔|✖| +|<span class="text-nowrap"><i class="fa fa-umbrella fa-fw"></i> **Protected**</span> |✔|✔|✖|✖|✖| +|<span class="text-nowrap"><i class="fa fa-hand-stop-o fa-fw"></i> **Private**</span> |✔|✖|✖|✖|✖| + **Only the owner of the note can change the note's permissions.** |