diff --git a/README.md b/README.md index ecdc8c7..25388ec 100644 --- a/README.md +++ b/README.md @@ -228,6 +228,14 @@ There are some config settings you need to change in the files below. | `CMD_SAML_ATTRIBUTE_ID` | `sAMAccountName` | attribute map for `id` (optional, default: NameID of SAML response) | | `CMD_SAML_ATTRIBUTE_USERNAME` | `mailNickname` | attribute map for `username` (optional, default: NameID of SAML response) | | `CMD_SAML_ATTRIBUTE_EMAIL` | `mail` | attribute map for `email` (optional, default: NameID of SAML response if `CMD_SAML_IDENTIFIERFORMAT` is default) | +| `CMD_OAUTH2_USER_PROFILE_URL` | `https://example.com` | where retrieve information about a user after succesful login. Needs to output JSON. (no default value) Refer to the [Mattermost](docs/guides/auth/mattermost-self-hosted.md) or [Nextcloud](docs/guides/auth/nextcloud.md) examples for more details on all of the `CMD_OAUTH2...` options. | +| `CMD_OAUTH2_USER_PROFILE_USERNAME_ATTR` | `name` | where to find the username in the JSON from the user profile URL. (no default value)| +| `CMD_OAUTH2_USER_PROFILE_DISPLAY_NAME_ATTR` | `display-name` | where to find the display-name in the JSON from the user profile URL. (no default value) | +| `CMD_OAUTH2_USER_PROFILE_EMAIL_ATTR` | `email` | where to find the email address in the JSON from the user profile URL. (no default value) | +| `CMD_OAUTH2_TOKEN_URL` | `https://example.com` | sometimes called token endpoint, please refer to the documentation of your OAuth2 provider (no default value) | +| `CMD_OAUTH2_AUTHORIZATION_URL` | `https://example.com` | authorization URL of your provider, please refer to the documentation of your OAuth2 provider (no default value) | +| `CMD_OAUTH2_CLIENT_ID` | `afae02fckafd...` | you will get this from your OAuth2 provider when you register CodiMD as OAuth2-client, (no default value) | +| `CMD_OAUTH2_CLIENT_SECRET` | `afae02fckafd...` | you will get this from your OAuth2 provider when you register CodiMD as OAuth2-client, (no default value) | | `CMD_IMGUR_CLIENTID` | no example | Imgur API client id | | `CMD_EMAIL` | `true` or `false` | set to allow email signin | | `CMD_ALLOW_PDF_EXPORT` | `true` or `false` | Enable or disable PDF exports | @@ -298,6 +306,7 @@ There are some config settings you need to change in the files below. | `heartbeatTimeout` | `10000` | socket.io heartbeat timeout | | `documentMaxLength` | `100000` | note max length | | `email` | `true` or `false` | set to allow email signin | +| `oauth2` | `{baseURL: ..., userProfileURL: ..., userProfileUsernameAttr: ..., userProfileDisplayNameAttr: ..., userProfileEmailAttr: ..., tokenURL: ..., authorizationURL: ..., clientID: ..., clientSecret: ...}` | An object detailing your OAuth2 provider. Refer to the [Mattermost](docs/guides/auth/mattermost-self-hosted.md) or [Nextcloud](docs/guides/auth/nextcloud.md) examples for more details!| | `allowEmailRegister` | `true` or `false` | set to allow email register (only applied when email is set, default is `true`. Note `bin/manage_users` might help you if registration is `false`.) | | `allowGravatar` | `true` or `false` | set to `false` to disable gravatar as profile picture source on your instance | | `imageUploadType` | `imgur`, `s3`, `minio`, `azure` or `filesystem`(default) | Where to upload images. For S3, see our Image Upload Guides for [S3](docs/guides/s3-image-upload.md) or [Minio](docs/guides/minio-image-upload.md)| diff --git a/docs/guides/auth/nextcloud.md b/docs/guides/auth/nextcloud.md new file mode 100644 index 0000000..108772d --- /dev/null +++ b/docs/guides/auth/nextcloud.md @@ -0,0 +1,52 @@ +Authentication guide - Nextcloud (self-hosted) +=== + +*This has been constructed using the [Nextcloud OAuth2 Documentation](https://docs.nextcloud.com/server/14/admin_manual/configuration_server/oauth2.html?highlight=oauth2) combined with [this issue comment on the nextcloud bugtracker](https://github.com/nextcloud/server/issues/5694#issuecomment-314761326).* + +This guide uses the generic OAuth2 module for compatibility with Nextcloud 13 and above (this guide has been tested successfully with Nextcloud 14). + +1. Sign-in with an administrator account to your Nextcloud server + +2. Navigate to the OAuth integration settings: Profile Icon (top right) --> Settings + Then choose Security Settings from the *Administration* part of the list - Don't confuse this with Personal Security Settings, where you would change your personal password! + At the top there's OAuth 2.0-Clients. + ![Where to find OAuth2 in Nextcloud](../images/auth/nextcloud-oauth2-1-settings.png) + +3. Add your CodiMD instance by giving it a *name* (perhaps CodiMD, but could be anything) and a *Redirection-URI*. The Redirection-URI will be `\/auth/oauth2/callback`. Click Add. + ![Adding a client to Nextcloud](../images/auth/nextcloud-oauth2-2-client-add.png) + + +4. You'll now see a line containing a *client identifier* and a *Secret*. + ![Successfully added OAuth2-client](../images/auth/nextcloud-oauth2-3-clientid-secret.png) + +5. That's it for Nextcloud, the rest is configured in your CodiMD `config.json` or via the `CMD_` environment variables! + +6. Add the Client ID and Client Secret to your `config.json` file or pass them as environment variables. Make sure you also replace `` with the right domain name. + * `config.json`: + ```javascript + { + "production": { + "oauth2": { + "clientID": "ii4p1u3jz7dXXXXXXXXXXXXXXX", + "clientSecret": "mqzzx6fydbXXXXXXXXXXXXXXXX", + "authorizationURL": "https:///apps/oauth2/authorize", + "tokenURL": "https:///apps/oauth2/api/v1/token", + "userProfileURL": "https:///ocs/v2.php/cloud/user?format=json", + "userProfileUsernameAttr": "ocs.data.id", + "userProfileDisplayNameAttr": "ocs.data.display-name", + "userProfileEmailAttr": "ocs.data.email" + } + } + } + ``` + * environment variables: + ```sh + CMD_OAUTH2_CLIENT_ID=ii4p1u3jz7dXXXXXXXXXXXXXXX + CMD_OAUTH2_CLIENT_SECRET=mqzzx6fydbXXXXXXXXXXXXXXXX + CMD_OAUTH2_AUTHORIZATION_URL=https:///apps/oauth2/authorize + CMD_OAUTH2_TOKEN_URL=https:///apps/oauth2/api/v1/token + CMD_OAUTH2_USER_PROFILE_URL=https:///ocs/v2.php/cloud/user?format=json + CMD_OAUTH2_USER_PROFILE_USERNAME_ATTR=ocs.data.id + CMD_OAUTH2_USER_PROFILE_DISPLAY_NAME_ATTR=ocs.data.display-name + CMD_OAUTH2_USER_PROFILE_EMAIL_ATTR=ocs.data.email + ``` diff --git a/docs/guides/images/auth/nextcloud-oauth2-1-settings.png b/docs/guides/images/auth/nextcloud-oauth2-1-settings.png new file mode 100644 index 0000000..82652a5 Binary files /dev/null and b/docs/guides/images/auth/nextcloud-oauth2-1-settings.png differ diff --git a/docs/guides/images/auth/nextcloud-oauth2-2-client-add.png b/docs/guides/images/auth/nextcloud-oauth2-2-client-add.png new file mode 100644 index 0000000..7909fa6 Binary files /dev/null and b/docs/guides/images/auth/nextcloud-oauth2-2-client-add.png differ diff --git a/docs/guides/images/auth/nextcloud-oauth2-3-clientid-secret.png b/docs/guides/images/auth/nextcloud-oauth2-3-clientid-secret.png new file mode 100644 index 0000000..b05513d Binary files /dev/null and b/docs/guides/images/auth/nextcloud-oauth2-3-clientid-secret.png differ diff --git a/package.json b/package.json index 6d46122..1217263 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "test": "npm run-script standard && npm run-script jsonlint", "jsonlint": "find . -not -path './node_modules/*' -type f -name '*.json' -o -type f -name '*.json.example' | while read json; do echo $json ; jq . $json; done", "standard": "node ./node_modules/standard/bin/cmd.js", - "dev": "webpack --config webpack.config.js --progress --colors --watch", + "dev": "webpack --config webpack.config.js --mode=production --progress --colors --watch", "build": "webpack --config webpack.production.js --progress --colors --bail", "postinstall": "bin/heroku", "start": "node app.js", diff --git a/public/js/extra.js b/public/js/extra.js index d6bbb0c..7a1077d 100644 --- a/public/js/extra.js +++ b/public/js/extra.js @@ -570,7 +570,9 @@ export function postProcess (code) { $(value).html(html) }) // link should open in new window or tab - result.find('a:not([href^="#"]):not([target])').attr('target', '_blank') + // also add noopener to prevent clickjacking + // See details: https://mathiasbynens.github.io/rel-noopener/ + result.find('a:not([href^="#"]):not([target])').attr('target', '_blank').attr('rel', 'noopener') // update continue line numbers const linenumberdivs = result.find('.gutter.linenumber').toArray() for (let i = 0; i < linenumberdivs.length; i++) { diff --git a/public/views/codimd/body.ejs b/public/views/codimd/body.ejs index d4f27a9..dc11190 100644 --- a/public/views/codimd/body.ejs +++ b/public/views/codimd/body.ejs @@ -113,7 +113,7 @@ diff --git a/public/views/shared/refresh-modal.ejs b/public/views/shared/refresh-modal.ejs index 5be41b2..6458054 100644 --- a/public/views/shared/refresh-modal.ejs +++ b/public/views/shared/refresh-modal.ejs @@ -14,7 +14,7 @@