Merge pull request #833 from hedgedoc/docs/develop-cleanup
|
@ -1,445 +0,0 @@
|
||||||
# Configuration
|
|
||||||
|
|
||||||
You can choose to configure HedgeDoc with either a config file or with environment variables.
|
|
||||||
|
|
||||||
Environment variables take precedence over configurations from the config files. They generally start with `CMD_` for
|
|
||||||
our own options, but we also list node-specific options you can configure this way.
|
|
||||||
|
|
||||||
- Environment variables are processed
|
|
||||||
in [`lib/config/environment.js`](https://github.com/hedgedoc/hedgedoc/tree/master/lib/config/environment.js) - so this
|
|
||||||
is the first place to look if anything is missing not obvious from this document. The default values are defined
|
|
||||||
in [`lib/config/default.js`](https://github.com/hedgedoc/hedgedoc/tree/master/lib/config/default.js), in case you
|
|
||||||
wonder if you even need to override it.
|
|
||||||
|
|
||||||
- The config file is processed
|
|
||||||
in [`lib/config/index.js`](https://github.com/hedgedoc/hedgedoc/tree/master/lib/config/index.js) - so this is the
|
|
||||||
first place to look if anything is missing not obvious from this document. The default values are defined
|
|
||||||
in [`lib/config/default.js`](https://github.com/hedgedoc/hedgedoc/tree/master/lib/config/default.js), in case you
|
|
||||||
wonder if you even need to override it. To get started, it is a good idea to take the `config.json.example` and copy
|
|
||||||
it to `config.json` before filling in your own details.
|
|
||||||
|
|
||||||
**Note:** *Due to the rename process we renamed all `HMD_`-prefix variables to be `CMD_`-prefixed. The old ones continue
|
|
||||||
to work.*
|
|
||||||
|
|
||||||
## Node.JS
|
|
||||||
|
|
||||||
| config file | environment | **
|
|
||||||
default** and example value | description | | ----------- | ----------- | ----------------------------- |
|
|
||||||
-------------------------------------------------------------------------------- | | | `NODE_ENV` | `production`
|
|
||||||
or `development` | set current environment (will apply corresponding settings in the `config.json`) | | `debug`
|
|
||||||
| `DEBUG` | `true` or `false` | set debug mode, show more logs |
|
|
||||||
|
|
||||||
## HedgeDoc basics
|
|
||||||
|
|
||||||
| config file | environment | **
|
|
||||||
default** and example value | description | | ------------------- | ------------------------ |
|
|
||||||
---------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
|
||||||
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
| | | `CMD_CONFIG_FILE` | **no default**, `/path/to/config.json`
|
|
||||||
| optional override for the path to HedgeDoc's config file | | `db` | | **`undefined`**
|
|
||||||
, `{ "dialect": "sqlite", "storage": "./db.hedgedoc.sqlite" }`
|
|
||||||
| set the db configs, [see more here](http://sequelize.readthedocs.org/en/latest/api/sequelize/)
|
|
||||||
| | `dbURL` | `CMD_DB_URL` | **`undefined`**
|
|
||||||
, `postgres://username:password@localhost:5432/hedgedoc` or `mysql://username:password@localhost:3306/hedgedoc`| Set the
|
|
||||||
db in URL style. If set, then the relevant `db` config entries will be overridden. | | `loglevel`
|
|
||||||
| `CMD_LOGLEVEL` | **`info`**, `debug` ... | Defines what kind of logs are provided to stdout. Available
|
|
||||||
options: `debug`, `verbose`, `info`, `warn`, `error`
|
|
||||||
| | `forbiddenNoteIDs` | `CMD_FORBIDDEN_NOTE_IDS`
|
|
||||||
| **`['robots.txt', 'favicon.ico', 'api', 'build', 'css', 'docs', 'fonts', 'js', 'uploads', 'vendor', 'views']`**
|
|
||||||
, `['robots.txt']` or `'robots.txt'` | disallow creation of notes, even if `allowFreeUrl` or `CMD_ALLOW_FREEURL`
|
|
||||||
is `true`
|
|
||||||
| | `imageUploadType` | `CMD_IMAGE_UPLOAD_TYPE` | **`filesystem`**, `imgur`, `s3`, `minio`, `azure`, `lutim`
|
|
||||||
| Where to upload images. For S3, see our Image Upload Guides for [S3](guides/s3-image-upload.md)
|
|
||||||
or [Minio](guides/minio-image-upload.md), also there's a whole section on their respective env vars below. |
|
|
||||||
| `sourceURL` | `CMD_SOURCE_URL` | **no default**
|
|
||||||
, `https://github.com/hedgedoc/hedgedoc/tree/<current commit>` | Provides the link to the source code of
|
|
||||||
HedgeDoc on the entry page (Please, make sure you change this when you run a modified version)
|
|
||||||
| | `tooBusyLag` | `CMD_TOOBUSY_LAG` | **`70`**
|
|
||||||
| CPU time for one event loop tick until node throttles connections. (milliseconds)
|
|
||||||
| | `staticCacheTime` | | **`1 * 24 * 60 * 60 * 1000`**
|
|
||||||
| static file cache time | | `heartbeatInterval` | | **`5000`**
|
|
||||||
| socket.io heartbeat interval | | `heartbeatTimeout` | | **`10000`**
|
|
||||||
| socket.io heartbeat timeout | | `documentMaxLength` | | **`100000`**
|
|
||||||
| note max length | | `linkifyHeaderStyle` | | **`keep-case`**, `lower-case`, `gfm`
|
|
||||||
| how is a header text converted into a link id |
|
|
||||||
|
|
||||||
## HedgeDoc paths stuff
|
|
||||||
|
|
||||||
these are rarely used for various reasons.
|
|
||||||
|
|
||||||
| config file | environment | **
|
|
||||||
default** and example values | description | | ----------------- | ----------- |
|
|
||||||
----------------------------------------------------- |
|
|
||||||
------------------------------------------------------------------------------------------------ | | `defaultNotePath` |
|
|
||||||
| **`./public/default.md`** | default note file path<sup>1</sup>, empty notes will be
|
|
||||||
created with this template. | | `dhParamPath` | | **`undefined`**, `./cert/dhparam.pem` | SSL
|
|
||||||
dhparam path<sup>1</sup> (only need when you set `useSSL`) | | `sslCAPath` |
|
|
||||||
| **`undefined`**, `['./cert/COMODORSAAddTrustCA.crt']` | SSL ca chain<sup>1</sup> (only need when you set `useSSL`)
|
|
||||||
| | `sslCertPath` | | **`undefined`**, `./cert/hedgedoc_io.crt` | SSL cert path<sup>1</sup> (only need
|
|
||||||
when you set `useSSL`) | | `sslKeyPath` | | **`undefined`**
|
|
||||||
, `./cert/client.key` | SSL key path<sup>1</sup> (only need when you set `useSSL`)
|
|
||||||
| | `tmpPath` | | **`os.tmpdir()`**, `./tmp/` | temp directory path<sup>1</sup>
|
|
||||||
| | `docsPath` | | **`./public/docs`** | docs directory path<sup>1</sup>
|
|
||||||
| | `viewPath` | | **`./public/views`** | template directory path<sup>1</sup>
|
|
||||||
| | `uploadsPath` | | **`./public/uploads`** | uploads directory<sup>1</sup> - needs
|
|
||||||
to be persistent when you use imageUploadType `filesystem` |
|
|
||||||
|
|
||||||
**Note:** *relative paths are based on HedgeDoc's base directory*
|
|
||||||
|
|
||||||
## HedgeDoc Location
|
|
||||||
|
|
||||||
| config file | environment | **
|
|
||||||
default** and example value | description | | ---------------- | --------------------- |
|
|
||||||
---------------------------------------------------------------- |
|
|
||||||
----------------------------------------------------------------------------------------------------------------- |
|
|
||||||
| `domain` | `CMD_DOMAIN` | **`null`**, `localhost`, `hedgedoc.org` | domain
|
|
||||||
name | | `urlPath` | `CMD_URL_PATH` | **`null`**, `hedgedoc` |
|
|
||||||
If HedgeDoc is run from a subdirectory like `www.example.com/<urlpath>` |
|
|
||||||
| `host` | `CMD_HOST` | **`0.0.0.0`**, `localhost` |
|
|
||||||
interface/ip to listen on | | `port` | `CMD_PORT` | **`3000`**, `80`
|
|
||||||
| port to listen on | | `path` | `CMD_PATH` | **no default**, `/var/run/hedgedoc.sock`
|
|
||||||
| path to UNIX domain socket to listen on (if specified, `host` or `CMD_HOST` and `port` or `CMD_PORT` are ignored) |
|
|
||||||
| `protocolUseSSL` | `CMD_PROTOCOL_USESSL` | **`false`** or `true` | set to
|
|
||||||
use SSL protocol for resources path (only applied when domain is set) | | `useSSL`
|
|
||||||
| | **`false`** or `true` | set to use SSL server (if `true`, will auto turn
|
|
||||||
on `protocolUseSSL`) | | `urlAddPort` | `CMD_URL_ADDPORT`
|
|
||||||
| **`false`** or `true` | set to add port on callback URL (ports `80`
|
|
||||||
or `443` won't be applied) (only applied when domain is set) | | `allowOrigin` | `CMD_ALLOW_ORIGIN`
|
|
||||||
| **`['localhost']`**, `['hedgedoc.org']`, `['localhost', 'hedgedoc.org']` | domain name whitelist (use comma to
|
|
||||||
separate) |
|
|
||||||
|
|
||||||
## Web security aspects
|
|
||||||
|
|
||||||
| config file | environment | **
|
|
||||||
default** and example value | description | | -------------- | ----------------------------- |
|
|
||||||
------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
|
||||||
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
| | `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)
|
|
||||||
| | | `CMD_HSTS_ENABLE` | **`true`** or `false`
|
|
||||||
| set to enable [HSTS](https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security) if HTTPS is also enabled (default
|
|
||||||
is ` true`)
|
|
||||||
| | | `CMD_HSTS_INCLUDE_SUBDOMAINS` | **`true`** or `false`
|
|
||||||
| set to include subdomains in HSTS (default is `true`)
|
|
||||||
| | | `CMD_HSTS_MAX_AGE` | **`31536000`**, `60 * 60 * 24 * 365`
|
|
||||||
| max duration in seconds to tell clients to keep HSTS status (default is a year)
|
|
||||||
| | | `CMD_HSTS_PRELOAD` | **`true`** or `false`
|
|
||||||
| whether to allow preloading of the site's HSTS status (e.g. into browsers)
|
|
||||||
| | `csp` |
|
|
||||||
| `{"enable": true, "directives": {"scriptSrc": "trustworthy-scripts.example.com"}, "upgradeInsecureRequests": "auto", "addDefaults": true}`
|
|
||||||
| Configures [Content Security Policy](https://helmetjs.github.io/docs/csp/). Directives are passed to Helmet -
|
|
||||||
see [their documentation](https://helmetjs.github.io/docs/csp/) for more information on the format. Some defaults are
|
|
||||||
added to the configured values so that the application doesn't break. To disable this behaviour, set `addDefaults`
|
|
||||||
to `false`. Further, if `usecdn` is on, some CDN locations are allowed too. By default (`auto`), insecure (HTTP)
|
|
||||||
requests are upgraded to HTTPS via CSP if `useSSL` is on. To change this behaviour, set `upgradeInsecureRequests` to
|
|
||||||
either `true` or `false`. | | | `CMD_CSP_ENABLE` | **`true`** or `false`
|
|
||||||
| whether to enable Content Security Policy (directives cannot be configured with environment variables)
|
|
||||||
| | | `CMD_CSP_REPORTURI` | **`undefined`**, `https://<someid>.report-uri.com/r/d/csp/enforce`
|
|
||||||
| Allows to add a URL for CSP reports in case of violations | | `cookiePolicy` | `CMD_COOKIE_POLICY`
|
|
||||||
| **`lax`**, `strict` or `none`
|
|
||||||
| Set a SameSite policy whether cookies are send from cross-origin. Be careful: setting a SameSite value of none without
|
|
||||||
https breaks the editor |
|
|
||||||
|
|
||||||
## Privacy and External Requests
|
|
||||||
|
|
||||||
| config file | environment | **
|
|
||||||
default** and example value | description | | --------------- | -------------------- | ----------------------------- |
|
|
||||||
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
| | `allowGravatar` | `CMD_ALLOW_GRAVATAR` | **`true`** or `false` | set to `false` to
|
|
||||||
disable [Libravatar](https://www.libravatar.org/) as profile picture source on your instance. Libravatar is a federated
|
|
||||||
open-source alternative to Gravatar. | | `useCDN` | `CMD_USECDN` | **`false`** or `true` | set to
|
|
||||||
use CDN resources or not (default is `false`)
|
|
||||||
|
|
|
||||||
|
|
||||||
## Users and Privileges
|
|
||||||
|
|
||||||
| config file | environment | **
|
|
||||||
default** and example value | description | | --------------------- | --------------------------- |
|
|
||||||
----------------------------------------------------------------------- |
|
|
||||||
--------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
| | `allowAnonymous` | `CMD_ALLOW_ANONYMOUS` | **`true`** or `false`
|
|
||||||
| Set to allow anonymous usage (default is `true`). | | `allowAnonymousEdits` | `CMD_ALLOW_ANONYMOUS_EDITS`
|
|
||||||
| **`false`** or `true` | If `allowAnonymous` is `false`: allow users
|
|
||||||
to select `freely` permission, allowing guests to edit existing notes (default is `false`). | | `allowFreeURL`
|
|
||||||
| `CMD_ALLOW_FREEURL` | **`false`** or `true` | Set to allow
|
|
||||||
new note creation by accessing a nonexistent note URL. This is the behavior familiar
|
|
||||||
from [Etherpad](https://github.com/ether/etherpad-lite). | | `defaultPermission` | `CMD_DEFAULT_PERMISSION`
|
|
||||||
| **`editable`**, `freely`, `limited`, `locked`, `protected` or `private` | Set notes default permission (only applied
|
|
||||||
on signed-in users). | | `sessionName` | | **`connect.sid`**
|
|
||||||
| Cookie session name. | | `sessionLife` | `CMD_SESSION_LIFE` | **`14 * 24 * 60 * 60 * 1000`**
|
|
||||||
, `1209600000` (14 days) | Cookie session life time in milliseconds. | | `sessionSecret`
|
|
||||||
| `CMD_SESSION_SECRET` | **`secret`** | Cookie session
|
|
||||||
secret used to sign the session cookie. If none is set, one will randomly generated on each startup, meaning all your
|
|
||||||
users will be logged out. |
|
|
||||||
|
|
||||||
## Login methods
|
|
||||||
|
|
||||||
### Email (local account)
|
|
||||||
|
|
||||||
| config file | environment | **
|
|
||||||
default** and example value | description | | -------------------- | -------------------------- |
|
|
||||||
----------------------------- |
|
|
||||||
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
| | `email` | `CMD_EMAIL` | **`true`** or `false` | Set to allow email sign-in. The
|
|
||||||
default is `true`. | | `allowEmailRegister` | `CMD_ALLOW_EMAIL_REGISTER` | **`true`** or `false` | Set to allow
|
|
||||||
registration of new accounts using an email address. If set to `false`, you can still create accounts using the command
|
|
||||||
line - see `bin/manage_users` for details (In production mode, remember to run it with `NODE_ENV` set as `production` in
|
|
||||||
the enviroment). This setting has no effect if `email` or `CMD_EMAIL` is `false`. The default for `allowEmailRegister`
|
|
||||||
or `CMD_ALLOW_EMAIL_REGISTER` is `true`. |
|
|
||||||
|
|
||||||
### Dropbox Login
|
|
||||||
|
|
||||||
| config file | environment | **
|
|
||||||
default** and example value | description | | ----------- | -------------------------- |
|
|
||||||
------------------------------------ |
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
| | `dropbox` | | `{clientID: ..., clientSecret: ...}` | An object containing the client ID and the client secret
|
|
||||||
obtained by the [Dropbox developer tools](https://www.dropbox.com/developers/apps) | | | `CMD_DROPBOX_CLIENTID` | **
|
|
||||||
no default** | Dropbox API client id | | | `CMD_DROPBOX_CLIENTSECRET` | **no default**
|
|
||||||
| Dropbox API client secret |
|
|
||||||
|
|
||||||
### Facebook Login
|
|
||||||
|
|
||||||
| config file | environment | **
|
|
||||||
default** and example value | description | | ----------- | --------------------------- |
|
|
||||||
------------------------------------ |
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
| | `facebook` | | `{clientID: ..., clientSecret: ...}` | An object containing the client ID and the client secret
|
|
||||||
obtained by the [Facebook app console](https://developers.facebook.com/apps) | | | `CMD_FACEBOOK_CLIENTID` | **no
|
|
||||||
default** | Facebook API client id | | | `CMD_FACEBOOK_CLIENTSECRET` | **no default**
|
|
||||||
| Facebook API client secret |
|
|
||||||
|
|
||||||
### GitHub Login
|
|
||||||
|
|
||||||
| config file | environment | **
|
|
||||||
default** and example value | description | | ----------- | ------------------------- |
|
|
||||||
------------------------------------ |
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
| | `github` | | `{clientID: ..., clientSecret: ...}` | An object containing the client ID and the client secret
|
|
||||||
obtained by the GitHub developer page. For more details have a look at the [GitHub auth guide](guides/auth/github.md). |
|
|
||||||
| | `CMD_GITHUB_CLIENTID` | **no default** | GitHub API client id | |
|
|
||||||
| `CMD_GITHUB_CLIENTSECRET` | **no default** | GitHub API client secret |
|
|
||||||
|
|
||||||
### GitLab Login
|
|
||||||
|
|
||||||
| config file | environment | **
|
|
||||||
default** and example value | description | | ----------- | ------------------------- |
|
|
||||||
---------------------------------------------------------------------------- |
|
|
||||||
-----------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
| | `gitlab` | | `{baseURL: ..., scope: ..., version: ..., clientID: ..., clientSecret: ...}` | An object containing
|
|
||||||
your GitLab application data. Refer to the [GitLab guide](guides/auth/gitlab-self-hosted.md) for more details! | |
|
|
||||||
| `CMD_GITLAB_SCOPE` | **no default**, `read_user` or `api` | GitLab API
|
|
||||||
requested scope (default is `api`) (GitLab snippet import/export need `api` scope)
|
|
||||||
| | | `CMD_GITLAB_BASEURL` | **no default** | GitLab
|
|
||||||
authentication endpoint, set to use other endpoint than GitLab.com (optional)
|
|
||||||
| | | `CMD_GITLAB_CLIENTID` | **no default** | GitLab
|
|
||||||
API client id | | | `CMD_GITLAB_CLIENTSECRET` | **no default**
|
|
||||||
| GitLab API client secret | | | `CMD_GITLAB_VERSION` | **`v4`**
|
|
||||||
| GitLab API version (v3 or v4)
|
|
||||||
|
|
|
||||||
|
|
||||||
### Google Login
|
|
||||||
|
|
||||||
| config file | environment | **
|
|
||||||
default** and example value | description | | ----------- | ------------------------- |
|
|
||||||
------------------------------------------------------- |
|
|
||||||
------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
| | `google` | | `{clientID: ..., clientSecret: ..., hostedDomain: ...}` | An object containing the client ID and the
|
|
||||||
client secret obtained by the [Google API console](https://console.cloud.google.com/apis) | | | `CMD_GOOGLE_CLIENTID`
|
|
||||||
| **no default** | Google API client id | | | `CMD_GOOGLE_CLIENTSECRET` | **no
|
|
||||||
default** | Google API client secret | | | `CMD_GOOGLE_HOSTEDDOMAIN` | **no
|
|
||||||
default**, `example.com` | Provided only if the user belongs to a hosted domain. default
|
|
||||||
is `undefined` |
|
|
||||||
|
|
||||||
### LDAP Login
|
|
||||||
|
|
||||||
| config file | environment | **
|
|
||||||
default** and example value | description | | ----------- | --------------------------- |
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
| --------------------------------------------------------------------------------------------------------------- |
|
|
||||||
| `ldap` |
|
|
||||||
| `{providerName: ..., url: ..., bindDn: ..., bindCredentials: ..., searchBase: ..., searchFilter: ..., searchAttributes: ..., usernameField: ..., useridField: ..., tlsca: ...}`
|
|
||||||
| An object detailing the LDAP connection. Refer to the [LDAP-AD guide](guides/auth/ldap-ad.md) for more details! | |
|
|
||||||
| `CMD_LDAP_URL` | **no default**, `ldap://example.com`
|
|
||||||
| URL of LDAP server | | | `CMD_LDAP_BINDDN` | **no default**
|
|
||||||
| bindDn for LDAP access | | | `CMD_LDAP_BINDCREDENTIALS` | **no default**, | bindCredentials for LDAP access | |
|
|
||||||
| `CMD_LDAP_SEARCHBASE` | **no default**, `o=users,dc=example,dc=com`
|
|
||||||
| LDAP directory to begin search from | | | `CMD_LDAP_SEARCHFILTER` | **no default**, `(uid={{username}})`
|
|
||||||
| LDAP filter to search with | | | `CMD_LDAP_SEARCHATTRIBUTES` | **no default**, `displayName, mail`
|
|
||||||
| LDAP attributes to search with (use comma to separate) | |
|
|
||||||
| `CMD_LDAP_USERIDFIELD` | **no default**, `uidNumber` or `uid` or `sAMAccountName`
|
|
||||||
| The LDAP field which is used uniquely identify a user on HedgeDoc | | | `CMD_LDAP_USERNAMEFIELD` | **no default**,
|
|
||||||
fallback to userid | The LDAP field which is used as the username on HedgeDoc | | | `CMD_LDAP_TLS_CA` | **no
|
|
||||||
default**, `server-cert.pem, root.pem`
|
|
||||||
| Root CA for LDAP TLS in PEM format (use comma to separate) | |
|
|
||||||
| `CMD_LDAP_PROVIDERNAME` | **no default**, `My institution`
|
|
||||||
| Optional name to be displayed at login form indicating the LDAP provider |
|
|
||||||
|
|
||||||
### Mattermost Login
|
|
||||||
|
|
||||||
| config file | environment | **
|
|
||||||
default** and example value | description | | ------------ | ----------------------------- |
|
|
||||||
-------------------------------------------------- |
|
|
||||||
---------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
| | `mattermost` | | `{baseURL: ..., clientID: ..., clientSecret: ...}` | An object containing the base URL of your
|
|
||||||
Mattermost application data. Refer to the [Mattermost guide](guides/auth/mattermost-self-hosted.md) for more details! |
|
|
||||||
| | `CMD_MATTERMOST_BASEURL` | **no default** | Mattermost authentication
|
|
||||||
endpoint for versions below 5.0. For Mattermost version 5.0 and above,
|
|
||||||
see [guide](guides/auth/mattermost-self-hosted.md). | | | `CMD_MATTERMOST_CLIENTID` | **no default**
|
|
||||||
| Mattermost API client id | | | `CMD_MATTERMOST_CLIENTSECRET` | **no default** |
|
|
||||||
Mattermost API client secret |
|
|
||||||
|
|
||||||
### OAuth2 Login
|
|
||||||
|
|
||||||
| config file | environment | **
|
|
||||||
default** and example value | description | | ----------- | ------------------------------------------- |
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
|
||||||
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
| | `oauth2` |
|
|
||||||
| `{baseURL: ..., userProfileURL: ..., userProfileUsernameAttr: ..., userProfileDisplayNameAttr: ..., userProfileEmailAttr: ..., tokenURL: ..., authorizationURL: ..., clientID: ..., clientSecret: ..., scope: ...}`
|
|
||||||
| An object detailing your OAuth2 provider. Refer to the [Mattermost](guides/auth/mattermost-self-hosted.md)
|
|
||||||
or [Nextcloud](guides/auth/nextcloud.md) examples for more details!
|
|
||||||
| | | `CMD_OAUTH2_USER_PROFILE_URL` | **no default**, `https://example.com`
|
|
||||||
| Where to retrieve information about a user after successful login. Needs to output JSON. (no default value) Refer to
|
|
||||||
the [Mattermost](guides/auth/mattermost-self-hosted.md) or [Nextcloud](guides/auth/nextcloud.md) examples for more
|
|
||||||
details on all of the `CMD_OAUTH2...` options. | | | `CMD_OAUTH2_USER_PROFILE_USERNAME_ATTR` | **no default**
|
|
||||||
, `name`
|
|
||||||
| where to find the username in the JSON from the user profile URL. (no default value)
|
|
||||||
| | | `CMD_OAUTH2_USER_PROFILE_DISPLAY_NAME_ATTR` | **no default**, `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` | **no default**, `email`
|
|
||||||
| where to find the email address in the JSON from the user profile URL. (no default value)
|
|
||||||
| | | `CMD_OAUTH2_USER_PROFILE_ID_ATTR` | **no default**, `user_uuid`
|
|
||||||
| where to find the dedicated user ID (optional, overrides `CMD_OAUTH2_USER_PROFILE_USERNAME_ATTR`)
|
|
||||||
| | | `CMD_OAUTH2_TOKEN_URL` | **no default**, `https://example.com`
|
|
||||||
| sometimes called token endpoint, please refer to the documentation of your OAuth2 provider (no default value)
|
|
||||||
| | | `CMD_OAUTH2_AUTHORIZATION_URL` | **no default**, `https://example.com`
|
|
||||||
| authorization URL of your provider, please refer to the documentation of your OAuth2 provider (no default value)
|
|
||||||
| | | `CMD_OAUTH2_CLIENT_ID` | **no default**, `afae02fckafd...`
|
|
||||||
| you will get this from your OAuth2 provider when you register HedgeDoc as OAuth2-client, (no default value)
|
|
||||||
| | | `CMD_OAUTH2_CLIENT_SECRET` | **no default**, `afae02fckafd...`
|
|
||||||
| you will get this from your OAuth2 provider when you register HedgeDoc as OAuth2-client, (no default value)
|
|
||||||
| | | `CMD_OAUTH2_PROVIDERNAME` | **no default**, `My institution`
|
|
||||||
| Optional name to be displayed at login form indicating the oAuth2 provider | | | `CMD_OAUTH2_SCOPE`
|
|
||||||
| **no default**, `openid email profile`
|
|
||||||
| Scope to request for OIDC (OpenID Connect) providers. | | | `CMD_OAUTH2_ROLES_CLAIM` | **no
|
|
||||||
default**, `roles`
|
|
||||||
| ID token claim, which is supposed to provide an array of strings of roles | | | `CMD_OAUTH2_ACCESS_ROLE`
|
|
||||||
| **no default**, `role/hedgedoc`
|
|
||||||
| The role which should be included in the ID token roles claim to grant access |
|
|
||||||
|
|
||||||
### SAML Login
|
|
||||||
|
|
||||||
| config file | environment | **
|
|
||||||
default** and example value | description | | ----------- | --------------------------------------- |
|
|
||||||
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
|
||||||
------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
| | `saml` |
|
|
||||||
| `{idpSsoUrl: ..., idpCert: ..., clientCert: ..., issuer: ..., identifierFormat: ..., disableRequestedAuthnContext: ..., groupAttribute: ..., externalGroups: [], requiredGroups: [], attribute: {id: ..., username: ..., email: ...}}`
|
|
||||||
| An object detailing your SAML provider. Refer to the [OneLogin](guides/auth/saml-onelogin.md)
|
|
||||||
and [SAML](guides/auth/saml.md) guides for more details! | | | `CMD_SAML_IDPSSOURL` | **no default**
|
|
||||||
, `https://idp.example.com/sso`
|
|
||||||
| authentication endpoint of IdP. for details, see [guide](guides/auth/saml-onelogin.md). | | | `CMD_SAML_IDPCERT`
|
|
||||||
| **no default**, `/path/to/cert.pem`
|
|
||||||
| certificate file path of IdP in PEM format | | | `CMD_SAML_CLIENTCERT` | **no default**
|
|
||||||
, `/path/to/privatecert.pem`
|
|
||||||
| certificate file path for the client in PEM format (optional)
|
|
||||||
| | | `CMD_SAML_ISSUER` | **no default**
|
|
||||||
| Issuer to supply to identity provider (optional, default: `serverURL` config)"
|
|
||||||
| | | `CMD_SAML_DISABLEREQUESTEDAUTHNCONTEXT` | **no default**, `true` or `false`
|
|
||||||
| true to allow any authentication method, false restricts to password authentication (PasswordProtectedTransport)
|
|
||||||
method (default: false) | | | `CMD_SAML_IDENTIFIERFORMAT`
|
|
||||||
| **`urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress`**
|
|
||||||
| name identifier format (optional, default: `urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress`)
|
|
||||||
| | | `CMD_SAML_GROUPATTRIBUTE` | **no default**, `memberOf`
|
|
||||||
| attribute name for group list (optional)
|
|
||||||
| | | `CMD_SAML_REQUIREDGROUPS` | **no default**, `hedgedoc-users`
|
|
||||||
| group names that allowed (use vertical bar to separate) (optional)
|
|
||||||
| | | `CMD_SAML_EXTERNALGROUPS` | **no default**, `Temporary-staff`
|
|
||||||
| group names that not allowed (use vertical bar to separate) (optional)
|
|
||||||
| | | `CMD_SAML_ATTRIBUTE_ID` | **no default**, `sAMAccountName`
|
|
||||||
| attribute map for `id` (optional, default: NameID of SAML response)
|
|
||||||
| | | `CMD_SAML_ATTRIBUTE_USERNAME` | **no default**, `mailNickname`
|
|
||||||
| attribute map for `username` (optional, default: NameID of SAML response)
|
|
||||||
| | | `CMD_SAML_ATTRIBUTE_EMAIL` | **no default**, `mail`
|
|
||||||
| attribute map for `email` (optional, default: NameID of SAML response if `CMD_SAML_IDENTIFIERFORMAT` is default)
|
|
||||||
|
|
|
||||||
|
|
||||||
### Twitter Login
|
|
||||||
|
|
||||||
| config file | environment | **
|
|
||||||
default** and example value | description | | ----------- | ---------------------------- |
|
|
||||||
----------------------------------------- |
|
|
||||||
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
| | `twitter` | | `{consumerKey: ..., consumerSecret: ...}` | An object containing the consumer key and secret
|
|
||||||
obtained by the [Twitter developer tools](https://developer.twitter.com/apps). For more details have a look at
|
|
||||||
the [Twitter auth guide](guides/auth/twitter.md) | | | `CMD_TWITTER_CONSUMERKEY` | **no default**
|
|
||||||
| Twitter API consumer key | | | `CMD_TWITTER_CONSUMERSECRET` | **no default** | Twitter API
|
|
||||||
consumer secret |
|
|
||||||
|
|
||||||
## Upload Storage
|
|
||||||
|
|
||||||
These are only relevant when they are also configured in sync with their
|
|
||||||
`CMD_IMAGE_UPLOAD_TYPE`. Also keep in mind, that `filesystem` is available, so you don't have to use either of these.
|
|
||||||
|
|
||||||
### Amazon S3
|
|
||||||
|
|
||||||
| config file | environment | **
|
|
||||||
default** and example value | description | | ----------- | -------------------------- |
|
|
||||||
----------------------------------------------------------------------------------------------------------------- |
|
|
||||||
------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
| | `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](guides/s3-image-upload.md) | | | `CMD_S3_ACCESS_KEY_ID` | **no default**
|
|
||||||
| AWS access key id | | | `CMD_S3_SECRET_ACCESS_KEY` | **no default**
|
|
||||||
| AWS secret key | | | `CMD_S3_REGION` | **no default**, `ap-northeast-1`
|
|
||||||
| AWS S3 region | | `s3bucket` | `CMD_S3_BUCKET` | **no default**
|
|
||||||
| AWS S3 bucket name | | | `CMD_S3_ENDPOINT ENV` | **no default**
|
|
||||||
| S3 API endpoint if you don't use AWS name |
|
|
||||||
|
|
||||||
### Azure Blob Storage
|
|
||||||
|
|
||||||
| config file | environment | **
|
|
||||||
default** and example value | description | | ----------- | ----------------------------- |
|
|
||||||
----------------------------- | ------------------------------------------------------------------------- | |
|
|
||||||
| `CMD_AZURE_CONNECTION_STRING` | **no default** | Azure Blob Storage connection string | |
|
|
||||||
| `CMD_AZURE_CONTAINER` | **no default** | Azure Blob Storage container name (automatically
|
|
||||||
created if non existent) |
|
|
||||||
|
|
||||||
### imgur
|
|
||||||
|
|
||||||
| config file | environment | **default** and example value | description |
|
|
||||||
| ----------- | -------------------- | ------------------------------ | ------------------- |
|
|
||||||
| | `CMD_IMGUR_CLIENTID` | **no default** | Imgur API client id |
|
|
||||||
|
|
||||||
### Minio
|
|
||||||
|
|
||||||
| config file | environment | **
|
|
||||||
default** and example value | description | | ----------- | ---------------------- |
|
|
||||||
-----------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
|
||||||
-----------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
| | `minio` |
|
|
||||||
| `{ "accessKey": "YOUR_MINIO_ACCESS_KEY", "secretKey": "YOUR_MINIO_SECRET_KEY", "endpoint": "YOUR_MINIO_HOST", port: 9000, secure: true }`
|
|
||||||
| When `imageUploadType` is set to `minio`, you need to set this key. Also check out
|
|
||||||
our [Minio Image Upload Guide](guides/minio-image-upload.md) | | | `CMD_MINIO_ACCESS_KEY` | **no default**
|
|
||||||
| Minio access key | | | `CMD_MINIO_SECRET_KEY` | **no default**
|
|
||||||
| Minio secret key | | | `CMD_MINIO_ENDPOINT` | **no default**, `minio.example.org`
|
|
||||||
| Address of your Minio endpoint/instance | | | `CMD_MINIO_PORT` | **no default**, `9000`
|
|
||||||
| Port that is used for your Minio instance | | | `CMD_MINIO_SECURE` | **no default**, `true`
|
|
||||||
| If set to `true` HTTPS is used for Minio |
|
|
||||||
|
|
||||||
### Lutim
|
|
||||||
|
|
||||||
| config file | environment | **
|
|
||||||
default** and example value | description | | ----------- | --------------- | ----------------------------- |
|
|
||||||
--------------------------------------------------------------------------- | | `lutim` |
|
|
||||||
| `{"url": "YOUR_LUTIM_URL"}` | When `imageUploadType` is set to `lutim`, you can setup the lutim url | |
|
|
||||||
| `CMD_LUTIM_URL` | **`https://framapic.org/`** | When `CMD_IMAGE_UPLOAD_TYPE` is set to `lutim`, you can setup the
|
|
||||||
lutim url |
|
|
|
@ -1,64 +0,0 @@
|
||||||
# API documentation
|
|
||||||
|
|
||||||
Several tasks of HedgeDoc can be automated through HTTP requests. The available endpoints for this api are described in
|
|
||||||
this document. For code-autogeneration there is an OpenAPIv3-compatible description available [here](openapi.yml).
|
|
||||||
|
|
||||||
## Notes
|
|
||||||
|
|
||||||
These endpoints create notes, return information about them or export them.
|
|
||||||
You have to replace *\<NOTE\>* with either the alias or id of a note you want to work on.
|
|
||||||
|
|
||||||
| Endpoint | HTTP-Method | Description |
|
|
||||||
| ---------------------------------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
||||||
| `/new` | `GET` | **Creates a new
|
|
||||||
note.**<br>A random id will be assigned and the content will equal to the template (blank by default). After note creation a redirect is issued to the created note. |
|
|
||||||
| `/new` | `POST` | **Imports some markdown data into a new
|
|
||||||
note.**<br>A random id will be assigned and the content will equal to the body of the received HTTP-request. The `Content-Type: text/markdown` header should be set on this request. |
|
|
||||||
| `/new/<ALIAS>` | `POST` | **Imports some markdown data into a new note with a
|
|
||||||
|
|
||||||
given alias.**<br>This endpoint equals to the above one except that the alias from the url will be assigned to the note
|
|
||||||
if [FreeURL-mode](../configuration.md#users-and-privileges) is enabled. | | `/<NOTE>/download`
|
|
||||||
or `/s/<SHORT-ID>/download` | `GET` | **Returns the raw markdown content of a note.**
|
|
||||||
| | `/<NOTE>/publish` | `GET` | **Redirects to the published version of the note.**
|
|
||||||
| | `/<NOTE>/slide` | `GET` | **Redirects to the slide-presentation of the
|
|
||||||
note.**<br>This is only useful on notes which are designed to be slides. | | `/<NOTE>/info`
|
|
||||||
| `GET` | **Returns metadata about the note.**<br>This includes the title and description of the note as well as
|
|
||||||
the creation date and viewcount. The data is returned as a JSON object. | | `/<NOTE>/revision`
|
|
||||||
| `GET` | **Returns a list of the available note revisions.**<br>The list is returned as a JSON object with an
|
|
||||||
array of revision-id and length associations. The revision-id equals to the timestamp when the revision was saved. |
|
|
||||||
| `/<NOTE>/revision/<REVISION-ID>` | `GET` | **Returns the revision of the note with some
|
|
||||||
metadata.**<br>The revision is returned as a JSON object with the content of the note and the authorship. |
|
|
||||||
| `/<NOTE>/gist` | `GET` | **Creates a new GitHub Gist with the note's
|
|
||||||
content.**<br>If [GitHub integration](../configuration.md#github-login) is configured, the user will be redirected to
|
|
||||||
GitHub and a new Gist with the content of the note will be created. |
|
|
||||||
|
|
||||||
## User / History
|
|
||||||
|
|
||||||
These endpoints return information about the current logged-in user and it's note history. If no user is logged-in, the
|
|
||||||
most of this requests will fail with either a HTTP 403 or a JSON object containing `{"status":"forbidden"}`.
|
|
||||||
|
|
||||||
| Endpoint | HTTP-Method | Description |
|
|
||||||
| ----------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
||||||
| `/me` | `GET` | **Returns the profile data of the current logged-in
|
|
||||||
user.**<br>The data is returned as a JSON object containing the user-id, the user's name and a url to the profile picture. |
|
|
||||||
| `/me/export` | `GET` | **Exports a zip-archive with all notes of the current
|
|
||||||
user.** |
|
|
||||||
| `/history` | `GET` | **Returns a list of the last viewed
|
|
||||||
notes.**<br>The list is returned as a JSON object with an array containing for each entry it's id, title, tags, last visit time and pinned status. |
|
|
||||||
| `/history` | `POST` | **Replace user's history with a new
|
|
||||||
one.**<br>The body must be form-encoded and contain a field `history` with a JSON-encoded array like its returned from the server when exporting the history. |
|
|
||||||
| `/history` | `DELETE` | **Deletes the user's
|
|
||||||
history.** |
|
|
||||||
| `/history/<NOTE>` | `POST` | **Toggles the pinned status in the history for a
|
|
||||||
note.**<br>The body must be form-encoded and contain a field `pinned` that is either `true` or `false`. |
|
|
||||||
| `/history/<NOTE>` | `DELETE` | **Deletes a note from the user's
|
|
||||||
history.** |
|
|
||||||
|
|
||||||
## HedgeDoc-server
|
|
||||||
|
|
||||||
These endpoints return information about the running HedgeDoc instance.
|
|
||||||
|
|
||||||
| Endpoint | HTTP-Method | Description |
|
|
||||||
| --------- | ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
||||||
| `/status` | `GET` | **Returns the current status of the HedgeDoc
|
|
||||||
instance.**<br>The data is returned as a JSON object containing the number of notes stored on the server, (distinct) online users and more. |
|
|
|
@ -1,54 +0,0 @@
|
||||||
# Getting started
|
|
||||||
|
|
||||||
## Preparing for running the code
|
|
||||||
|
|
||||||
**Notice:** *There's [specialised instructions for docker](../setup/docker.md) or [heroku](../setup/heroku.md), if you prefer running code this way!*
|
|
||||||
|
|
||||||
1. Clone the repository with `git clone https://github.com/hedgedoc/hedgedoc.git hedgedoc-server`
|
|
||||||
(cloning is the preferred way, but you can also download and unzip a release)
|
|
||||||
|
|
||||||
2. Enter the directory and run `bin/setup`, which will install npm dependencies and create configs. The setup script is
|
|
||||||
written in Bash, you would need bash as a prerequisite.
|
|
||||||
|
|
||||||
3. Setup the [config file](../configuration.md) or set up
|
|
||||||
[environment variables](../configuration.md).
|
|
||||||
|
|
||||||
## Running the Code
|
|
||||||
|
|
||||||
Now that everything is in place, we can start HedgeDoc:
|
|
||||||
|
|
||||||
1. `yarn run build` will build the frontend bundle. It uses webpack to do that.
|
|
||||||
2. Run the server with `node app.js`
|
|
||||||
|
|
||||||
## Running the Code with Auto-Reload
|
|
||||||
|
|
||||||
The commands above are fine for production, but you're a developer and surely
|
|
||||||
you want to change things. You would need to restart both commands whenever you
|
|
||||||
change something. Luckily, you can run these commands that will automatically
|
|
||||||
rebuild the frontend or restart the server if necessary.
|
|
||||||
|
|
||||||
The commands will stay active in your terminal, so you will need multiple tabs
|
|
||||||
to run both at the same time.
|
|
||||||
|
|
||||||
1. Use `yarn run dev` if you want webpack to continuously rebuild the frontend code.
|
|
||||||
|
|
||||||
2. To auto-reload the server, the easiest method is to install [nodemon](https://www.npmjs.com/package/nodemon)
|
|
||||||
and run `nodemon --watch app.js --watch lib --watch locales app.js`.
|
|
||||||
|
|
||||||
## Structure
|
|
||||||
|
|
||||||
The repository contains two parts: a server (backend) and a client (frontend).
|
|
||||||
most of the server code is in `/lib` and most of the client code is in `public`.
|
|
||||||
|
|
||||||
```text
|
|
||||||
hedgedoc-server/
|
|
||||||
├── docs/ --- documentation
|
|
||||||
├── lib/ --- server code
|
|
||||||
├── test/ --- test suite
|
|
||||||
└── public/ --- client code
|
|
||||||
├── css/ --- css styles
|
|
||||||
├── docs/ --- default documents
|
|
||||||
├── js/ --- js scripts
|
|
||||||
├── vendor/ --- vendor includes
|
|
||||||
└── views/ --- view templates
|
|
||||||
```
|
|
|
@ -1,456 +0,0 @@
|
||||||
openapi: 3.0.1
|
|
||||||
|
|
||||||
info:
|
|
||||||
title: HedgeDoc
|
|
||||||
description: HedgeDoc is an open source collaborative note editor. Several tasks of HedgeDoc can be automated through this API.
|
|
||||||
version: 1.7.1
|
|
||||||
contact:
|
|
||||||
name: HedgeDoc on GitHub
|
|
||||||
url: https://github.com/hedgedoc/hedgedoc
|
|
||||||
license:
|
|
||||||
name: AGPLv3
|
|
||||||
url: https://github.com/hedgedoc/hedgedoc/blob/master/LICENSE
|
|
||||||
|
|
||||||
externalDocs:
|
|
||||||
url: https://github.com/hedgedoc/hedgedoc/blob/master/docs/dev/api.md
|
|
||||||
|
|
||||||
|
|
||||||
paths:
|
|
||||||
|
|
||||||
/new:
|
|
||||||
get:
|
|
||||||
tags:
|
|
||||||
- note
|
|
||||||
summary: Creates a new note.
|
|
||||||
description: A random id will be assigned and the content will equal to the template (blank by default). After note creation a redirect is issued to the created note.
|
|
||||||
responses:
|
|
||||||
default:
|
|
||||||
description: Redirect to the new note
|
|
||||||
post:
|
|
||||||
tags:
|
|
||||||
- note
|
|
||||||
summary: Imports some markdown data into a new note.
|
|
||||||
description: A random id will be assigned and the content will equal to the body of the received HTTP-request.
|
|
||||||
requestBody:
|
|
||||||
required: true
|
|
||||||
description: The content of the note to be imported as markdown
|
|
||||||
content:
|
|
||||||
'text/markdown':
|
|
||||||
example: '# Some header'
|
|
||||||
responses:
|
|
||||||
default:
|
|
||||||
description: Redirect to the imported note
|
|
||||||
|
|
||||||
/new/{alias}:
|
|
||||||
post:
|
|
||||||
tags:
|
|
||||||
- note
|
|
||||||
summary: Imports some markdown data into a new note with a given alias.
|
|
||||||
description: 'This endpoint equals to the above one except that the alias from the url will be assigned to the note if [FreeURL-mode](../configuration-env-vars.md#users-and-privileges) is enabled.'
|
|
||||||
requestBody:
|
|
||||||
required: true
|
|
||||||
description: The content of the note to be imported as markdown
|
|
||||||
content:
|
|
||||||
'text/markdown':
|
|
||||||
example: '# Some heading'
|
|
||||||
responses:
|
|
||||||
default:
|
|
||||||
description: Redirect to the imported note
|
|
||||||
parameters:
|
|
||||||
- name: alias
|
|
||||||
in: path
|
|
||||||
required: true
|
|
||||||
description: The alias for the note-id under which the note will be saved
|
|
||||||
content:
|
|
||||||
'text/plain':
|
|
||||||
example: my-note
|
|
||||||
|
|
||||||
/{note}/download:
|
|
||||||
get:
|
|
||||||
tags:
|
|
||||||
- note
|
|
||||||
summary: Returns the raw markdown content of a note.
|
|
||||||
responses:
|
|
||||||
200:
|
|
||||||
description: The raw markdown content of the note
|
|
||||||
content:
|
|
||||||
'text/markdown':
|
|
||||||
example: '# Some heading'
|
|
||||||
404:
|
|
||||||
description: Note does not exist
|
|
||||||
parameters:
|
|
||||||
- name: note
|
|
||||||
in: path
|
|
||||||
required: true
|
|
||||||
description: The note which should be downloaded
|
|
||||||
content:
|
|
||||||
'text/plain':
|
|
||||||
example: my-note
|
|
||||||
|
|
||||||
/{note}/publish:
|
|
||||||
get:
|
|
||||||
tags:
|
|
||||||
- note
|
|
||||||
summary: Redirects to the published version of the note.
|
|
||||||
responses:
|
|
||||||
default:
|
|
||||||
description: Redirect to the published version of the note
|
|
||||||
404:
|
|
||||||
description: Note does not exist
|
|
||||||
parameters:
|
|
||||||
- name: note
|
|
||||||
in: path
|
|
||||||
required: true
|
|
||||||
description: The note which should be published
|
|
||||||
content:
|
|
||||||
'text/plain':
|
|
||||||
example: my-note
|
|
||||||
|
|
||||||
/{note}/slide:
|
|
||||||
get:
|
|
||||||
tags:
|
|
||||||
- note
|
|
||||||
summary: Redirects to the slide-presentation of the note.
|
|
||||||
description: This is only useful on notes which are designed to be slides.
|
|
||||||
responses:
|
|
||||||
default:
|
|
||||||
description: Redirect to the slide version of the note
|
|
||||||
404:
|
|
||||||
description: Note does not exist
|
|
||||||
parameters:
|
|
||||||
- name: note
|
|
||||||
in: path
|
|
||||||
required: true
|
|
||||||
description: The note which should be shown as slide
|
|
||||||
content:
|
|
||||||
'text/plain':
|
|
||||||
example: my-note
|
|
||||||
|
|
||||||
/{note}/info:
|
|
||||||
get:
|
|
||||||
tags:
|
|
||||||
- note
|
|
||||||
summary: Returns metadata about the note.
|
|
||||||
description: This includes the title and description of the note as well as the creation date and viewcount.
|
|
||||||
responses:
|
|
||||||
200:
|
|
||||||
description: Metadata about the note
|
|
||||||
content:
|
|
||||||
'text/json':
|
|
||||||
schema:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
title:
|
|
||||||
type: string
|
|
||||||
description: The title of the note
|
|
||||||
default: Untitled
|
|
||||||
description:
|
|
||||||
type: string
|
|
||||||
description: The description of the note or the first words from the note
|
|
||||||
viewcount:
|
|
||||||
type: integer
|
|
||||||
minimum: 0
|
|
||||||
description: How often the published version of the note was viewed
|
|
||||||
createtime:
|
|
||||||
type: string
|
|
||||||
description: The timestamp when the note was created in ISO 8601 format.
|
|
||||||
updatetime:
|
|
||||||
type: string
|
|
||||||
description: The timestamp when the note was last updated in ISO 8601 format.
|
|
||||||
404:
|
|
||||||
description: Note does not exist
|
|
||||||
parameters:
|
|
||||||
- name: note
|
|
||||||
in: path
|
|
||||||
required: true
|
|
||||||
description: The note for which the info should be shown
|
|
||||||
content:
|
|
||||||
'text/plain':
|
|
||||||
example: my-note
|
|
||||||
|
|
||||||
/{note}/revision:
|
|
||||||
get:
|
|
||||||
tags:
|
|
||||||
- note
|
|
||||||
summary: Returns a list of the available note revisions.
|
|
||||||
description: The list is returned as a JSON object with an array of revision-id and length associations. The revision-id equals to the timestamp when the revision was saved.
|
|
||||||
responses:
|
|
||||||
200:
|
|
||||||
description: Revisions of the note
|
|
||||||
content:
|
|
||||||
'text/json':
|
|
||||||
schema:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
revision:
|
|
||||||
type: array
|
|
||||||
description: Array that holds all revision-info objects
|
|
||||||
items:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
time:
|
|
||||||
type: integer
|
|
||||||
description: UNIX-timestamp of when the revision was saved. Is also the revision-id.
|
|
||||||
length:
|
|
||||||
type: integer
|
|
||||||
description: Length of the document to the timepoint the revision was saved
|
|
||||||
404:
|
|
||||||
description: Note does not exist
|
|
||||||
parameters:
|
|
||||||
- name: note
|
|
||||||
in: path
|
|
||||||
required: true
|
|
||||||
description: The note for which revisions should be shown
|
|
||||||
content:
|
|
||||||
'text/plain':
|
|
||||||
example: my-note
|
|
||||||
|
|
||||||
/{note}/revision/{revision-id}:
|
|
||||||
get:
|
|
||||||
tags:
|
|
||||||
- note
|
|
||||||
summary: Returns the revision of the note with some metadata.
|
|
||||||
description: The revision is returned as a JSON object with the content of the note and the authorship.
|
|
||||||
responses:
|
|
||||||
200:
|
|
||||||
description: Revision of the note for the given timestamp
|
|
||||||
content:
|
|
||||||
'text/json':
|
|
||||||
schema:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
content:
|
|
||||||
type: string
|
|
||||||
description: The raw markdown content of the note revision
|
|
||||||
authorship:
|
|
||||||
type: array
|
|
||||||
description: Data which gives insights about who worked on the note
|
|
||||||
items:
|
|
||||||
type: integer
|
|
||||||
description: Unique user ids and additional data
|
|
||||||
patch:
|
|
||||||
type: array
|
|
||||||
description: Data which gives insight about what changed in comparison to former revisions
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
404:
|
|
||||||
description: Note does not exist
|
|
||||||
parameters:
|
|
||||||
- name: note
|
|
||||||
in: path
|
|
||||||
required: true
|
|
||||||
description: The note for which the revision should be shown
|
|
||||||
content:
|
|
||||||
'text/plain':
|
|
||||||
example: my-note
|
|
||||||
- name: revision-id
|
|
||||||
in: path
|
|
||||||
required: true
|
|
||||||
description: The id (timestamp) of the revision to fetch
|
|
||||||
content:
|
|
||||||
'text/plain':
|
|
||||||
example: 1570921051959
|
|
||||||
|
|
||||||
/{note}/gist:
|
|
||||||
get:
|
|
||||||
tags:
|
|
||||||
- note
|
|
||||||
summary: Creates a new GitHub Gist with the note's content.
|
|
||||||
description: 'If [GitHub integration](https://github.com/hedgedoc/hedgedoc/blob/master/docs/configuration-env-vars.md#github-login) is configured, the user will be redirected to GitHub and a new Gist with the content of the note will be created.'
|
|
||||||
responses:
|
|
||||||
default:
|
|
||||||
description: Redirect to the created gist (or the GitHub authentication before)
|
|
||||||
404:
|
|
||||||
description: Note does not exist
|
|
||||||
parameters:
|
|
||||||
- name: note
|
|
||||||
in: path
|
|
||||||
required: true
|
|
||||||
description: The note which should be pasted to GitHub gist
|
|
||||||
content:
|
|
||||||
'text/plain':
|
|
||||||
example: my-note
|
|
||||||
|
|
||||||
/me:
|
|
||||||
get:
|
|
||||||
tags:
|
|
||||||
- user
|
|
||||||
summary: Returns the profile data of the current logged-in user.
|
|
||||||
description: The data is returned as a JSON object containing the user-id, the user's name and a url to the profile picture. Requires an active session of the user.
|
|
||||||
responses:
|
|
||||||
200:
|
|
||||||
description: If the user is logged-in, the user data otherwise `{"status":"forbidden"}`
|
|
||||||
content:
|
|
||||||
'text/json':
|
|
||||||
schema:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
status:
|
|
||||||
type: string
|
|
||||||
description: ok if everything works as expected, forbidden is the user is not logged-in
|
|
||||||
id:
|
|
||||||
type: string
|
|
||||||
description: Unique id of the user
|
|
||||||
name:
|
|
||||||
type: string
|
|
||||||
description: The user's display name
|
|
||||||
photo:
|
|
||||||
type: string
|
|
||||||
description: An url to the online stored user profile photo
|
|
||||||
|
|
||||||
/me/export:
|
|
||||||
get:
|
|
||||||
tags:
|
|
||||||
- user
|
|
||||||
summary: Exports a zip-archive with all notes of the current user.
|
|
||||||
responses:
|
|
||||||
default:
|
|
||||||
description: The zip-archive with all notes
|
|
||||||
|
|
||||||
/history:
|
|
||||||
get:
|
|
||||||
tags:
|
|
||||||
- user
|
|
||||||
summary: Returns a list of the last viewed notes.
|
|
||||||
description: The list is returned as a JSON object with an array containing for each entry it's id, title, tags, last visit time and pinned status.
|
|
||||||
responses:
|
|
||||||
200:
|
|
||||||
description: The list of recently viewed notes and pinned notes
|
|
||||||
content:
|
|
||||||
'text/json':
|
|
||||||
schema:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
history:
|
|
||||||
type: array
|
|
||||||
description: The array that contains history objects
|
|
||||||
items:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
id:
|
|
||||||
type: string
|
|
||||||
description: The id or alias of the note
|
|
||||||
text:
|
|
||||||
type: string
|
|
||||||
description: The title of the note
|
|
||||||
time:
|
|
||||||
type: integer
|
|
||||||
description: The UNIX-timestamp when the note was last accessed by the user
|
|
||||||
tags:
|
|
||||||
type: array
|
|
||||||
description: The tags that were added by the user to the note
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
pinned:
|
|
||||||
type: boolean
|
|
||||||
description: Whether the user has pinned this note
|
|
||||||
post:
|
|
||||||
tags:
|
|
||||||
- user
|
|
||||||
summary: Replace user's history with a new one.
|
|
||||||
description: The body must be form-encoded and contain a field `history` with a JSON-encoded array like its returned from the server when exporting the history.
|
|
||||||
requestBody:
|
|
||||||
required: true
|
|
||||||
content:
|
|
||||||
'application/x-www-form-urlencoded':
|
|
||||||
example: 'history=[{"id":"example","text":"Untitled","time":1556275442010,"tags":[],"pinned":false}]'
|
|
||||||
responses:
|
|
||||||
200:
|
|
||||||
description: History replaced
|
|
||||||
delete:
|
|
||||||
tags:
|
|
||||||
- user
|
|
||||||
summary: Deletes the user's history.
|
|
||||||
responses:
|
|
||||||
200:
|
|
||||||
description: User's history deleted
|
|
||||||
|
|
||||||
/history/{note}:
|
|
||||||
post:
|
|
||||||
tags:
|
|
||||||
- user
|
|
||||||
summary: Toggles the pinned status in the history for a note.
|
|
||||||
description: The body must be form-encoded and contain a field `pinned` that is either `true` or `false`.
|
|
||||||
requestBody:
|
|
||||||
required: true
|
|
||||||
content:
|
|
||||||
'application/x-www-form-urlencoded':
|
|
||||||
example: 'pinned=false'
|
|
||||||
responses:
|
|
||||||
200:
|
|
||||||
description: Pinned state toggled
|
|
||||||
parameters:
|
|
||||||
- name: note
|
|
||||||
in: path
|
|
||||||
required: true
|
|
||||||
description: The note for which the pinned state should be toggled
|
|
||||||
content:
|
|
||||||
'text/plain':
|
|
||||||
example: my-note
|
|
||||||
delete:
|
|
||||||
tags:
|
|
||||||
- user
|
|
||||||
summary: Deletes a note from the user's history.
|
|
||||||
responses:
|
|
||||||
200:
|
|
||||||
description: Pinned state toggled
|
|
||||||
parameters:
|
|
||||||
- name: note
|
|
||||||
in: path
|
|
||||||
required: true
|
|
||||||
description: The note for which the pinned state should be toggled
|
|
||||||
content:
|
|
||||||
'text/plain':
|
|
||||||
example: my-note
|
|
||||||
|
|
||||||
/status:
|
|
||||||
get:
|
|
||||||
tags:
|
|
||||||
- server
|
|
||||||
summary: Returns the current status of the HedgeDoc instance.
|
|
||||||
description: The data is returned as a JSON object containing the number of notes stored on the server, (distinct) online users and more.
|
|
||||||
responses:
|
|
||||||
200:
|
|
||||||
description: The server info
|
|
||||||
content:
|
|
||||||
'text/json':
|
|
||||||
schema:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
onlineNotes:
|
|
||||||
type: integer
|
|
||||||
description: How many notes are edited at the moment
|
|
||||||
onlineUsers:
|
|
||||||
type: integer
|
|
||||||
description: How many users are online at the moment
|
|
||||||
distinctOnlineUsers:
|
|
||||||
type: integer
|
|
||||||
description: How many distinct users (different machines) are online at the moment
|
|
||||||
notesCount:
|
|
||||||
type: integer
|
|
||||||
description: How many notes are stored on the server
|
|
||||||
registeredUsers:
|
|
||||||
type: integer
|
|
||||||
description: How many users are registered on the server
|
|
||||||
onlineRegisteredUsers:
|
|
||||||
type: integer
|
|
||||||
description: How many of the online users are registered on the server
|
|
||||||
distinctOnlineRegisteredUsers:
|
|
||||||
type: integer
|
|
||||||
description: How many of the distinct online users are registered on the server
|
|
||||||
isConnectionBusy:
|
|
||||||
type: boolean
|
|
||||||
connectionSocketQueueLength:
|
|
||||||
type: integer
|
|
||||||
isDisconnectBusy:
|
|
||||||
type: boolean
|
|
||||||
disconnectSocketQueueLength:
|
|
||||||
type: integer
|
|
||||||
|
|
||||||
tags:
|
|
||||||
- name: note
|
|
||||||
description: These endpoints create notes, return information about them or export them.
|
|
||||||
- name: user
|
|
||||||
description: These endpoints return information about the current logged-in user and it's note history. If no user is logged-in, the most of this requests will fail with either a HTTP 403 or a JSON object containing `{"status":"forbidden"}`.
|
|
||||||
- name: server
|
|
||||||
description: These endpoints return information about the running HedgeDoc instance.
|
|
|
@ -1,14 +0,0 @@
|
||||||
Operational Transformation
|
|
||||||
===
|
|
||||||
|
|
||||||
From 0.3.2, we started supporting operational transformation.
|
|
||||||
It makes concurrent editing safe and will not break up other users' operations.
|
|
||||||
Additionally, now can show other clients' selections.
|
|
||||||
|
|
||||||
See more at [https://operational-transformation.github.io/](https://operational-transformation.github.io/)
|
|
||||||
|
|
||||||
And even more in this 2010 article series:
|
|
||||||
|
|
||||||
* https://drive.googleblog.com/2010/09/whats-different-about-new-google-docs_21.html
|
|
||||||
* https://drive.googleblog.com/2010/09/whats-different-about-new-google-docs_22.html
|
|
||||||
* https://drive.googleblog.com/2010/09/whats-different-about-new-google-docs.html
|
|
|
@ -1,40 +0,0 @@
|
||||||
Webpack
|
|
||||||
===
|
|
||||||
|
|
||||||
Webpack is a JavaScript build system for frontend code. You can find out all
|
|
||||||
about it on [the webpack website](https://webpack.js.org/).
|
|
||||||
|
|
||||||
Here's how we're using it:
|
|
||||||
|
|
||||||
## `webpack.common.js`
|
|
||||||
This file contains all common definitions for chunks and plugins that are needed by the whole app.
|
|
||||||
|
|
||||||
The various entrypoints under the `entry` key define groups of files (npm packages or .css/.js files directly from this project) that need to be included together to be useful.
|
|
||||||
The `index` group for example bundles all javascript files and libraries used for the note editor.
|
|
||||||
|
|
||||||
Entrypoints are referenced in the `plugins` section.
|
|
||||||
The `HtmlWebpackPlugin` uses templates in `public/views/includes` to include the path to the generated resources in new templates under `public/views/build`. These templates are then used by the backend to serve HTML to the browser.
|
|
||||||
|
|
||||||
|
|
||||||
**TODO:** Document which entry points are used for what.
|
|
||||||
|
|
||||||
## `webpack.htmlexport.js`
|
|
||||||
Separate config for the "save as html" feature.
|
|
||||||
Packs all CSS from `public/js/htmlExport.js` to `build/html.min.css`.
|
|
||||||
This file is then downloaded by client-side JS and used to create the HTML.
|
|
||||||
See `exportToHTML()` in `public/js/extra.js`.
|
|
||||||
|
|
||||||
|
|
||||||
## `webpack.dev.js`
|
|
||||||
The development config uses both common configs, enables development mode and enables "cheap" source maps (lines only).
|
|
||||||
If you need more detailed source maps while developing, you might want to use the `source-maps` option.
|
|
||||||
See https://webpack.js.org/configuration/devtool/ for details.
|
|
||||||
|
|
||||||
## `webpack.prod.js`
|
|
||||||
The production config uses both common configs and enables production mode.
|
|
||||||
This automatically enables various optimizations (e.g. UglifyJS). See https://webpack.js.org/concepts/mode/ for details.
|
|
||||||
|
|
||||||
For the global app config, the name of the emitted chunks is changed to include the content hash.
|
|
||||||
See https://webpack.js.org/guides/caching/ on why this is a good idea.
|
|
||||||
|
|
||||||
For the HTML export config, CSS minification is enabled.
|
|
|
@ -1,35 +0,0 @@
|
||||||
Authentication guide - GitHub
|
|
||||||
===
|
|
||||||
|
|
||||||
**Note:** *This guide was written before the renaming. Just replace `HackMD` with `CodiMD` in your mind :smile: thanks!*
|
|
||||||
|
|
||||||
1. Sign-in or sign-up for a GitHub account
|
|
||||||
2. Navigate to developer settings in your GitHub account [here](https://github.com/settings/developers) and select the "OAuth Apps" tab
|
|
||||||
3. Click on the **New OAuth App** button, to create a new OAuth App:
|
|
||||||
![create-oauth-app](../../images/auth/create-oauth-app.png)
|
|
||||||
|
|
||||||
4. Fill out the new OAuth application registration form, and click **Register Application**
|
|
||||||
![register-oauth-application-form](../../images/auth/register-oauth-application-form.png)
|
|
||||||
|
|
||||||
**Note:** *The callback URL is <your-codimd-url>/auth/github/callback*
|
|
||||||
|
|
||||||
5. After successfully registering the application, you'll receive the Client ID and Client Secret for the application
|
|
||||||
![application-page](../../images/auth/application-page.png)
|
|
||||||
|
|
||||||
6. Add the Client ID and Client Secret to your config.json file or pass them as environment variables
|
|
||||||
* `config.json`:
|
|
||||||
```js
|
|
||||||
{
|
|
||||||
"production": {
|
|
||||||
"github": {
|
|
||||||
"clientID": "3747d30eaccXXXXXXXXX",
|
|
||||||
"clientSecret": "2a8e682948eee0c580XXXXXXXXXXXXXXXXXXXXXX"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
* environment variables:
|
|
||||||
```sh
|
|
||||||
CMD_GITHUB_CLIENTID=3747d30eaccXXXXXXXXX
|
|
||||||
CMD_GITHUB_CLIENTSECRET=2a8e682948eee0c580XXXXXXXXXXXXXXXXXXXXXX
|
|
||||||
````
|
|
|
@ -1,32 +0,0 @@
|
||||||
GitLab (self-hosted)
|
|
||||||
===
|
|
||||||
|
|
||||||
**Note:** *This guide was written before the renaming. Just replace `HackMD` with `CodiMD` in your mind :smile: thanks!*
|
|
||||||
|
|
||||||
1. Sign in to your GitLab
|
|
||||||
2. Navigate to the application management page at `https://your.gitlab.domain/admin/applications` (admin permissions required)
|
|
||||||
3. Click **New application** to create a new application and fill out the registration form:
|
|
||||||
|
|
||||||
![New GitLab application](../../images/auth/gitlab-new-application.png)
|
|
||||||
|
|
||||||
4. Click **Submit**
|
|
||||||
5. In the list of applications select **HackMD**. Leave that site open to copy the application ID and secret in the next step.
|
|
||||||
|
|
||||||
![Application: HackMD](../../images/auth/gitlab-application-details.png)
|
|
||||||
|
|
||||||
|
|
||||||
6. In the `docker-compose.yml` add the following environment variables to `app:` `environment:`
|
|
||||||
|
|
||||||
```
|
|
||||||
- CMD_DOMAIN=your.codimd.domain
|
|
||||||
- CMD_URL_ADDPORT=true
|
|
||||||
- CMD_PROTOCOL_USESSL=true
|
|
||||||
- CMD_GITLAB_BASEURL=https://your.gitlab.domain
|
|
||||||
- CMD_GITLAB_CLIENTID=23462a34example99XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
|
||||||
- CMD_GITLAB_CLIENTSECRET=5532e9dexamplXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
|
||||||
```
|
|
||||||
|
|
||||||
7. Run `docker-compose up -d` to apply your settings.
|
|
||||||
8. Sign in to your CodiMD using your GitLab ID:
|
|
||||||
|
|
||||||
![Sign in via GitLab](../../images/auth/gitlab-sign-in.png)
|
|
|
@ -1,50 +0,0 @@
|
||||||
Keycloak/Red Hat SSO (self-hosted)
|
|
||||||
===
|
|
||||||
|
|
||||||
## Prerequisites
|
|
||||||
|
|
||||||
This guide assumes you have run and configured Keycloak. If you'd like to meet this prerequisite quickly, it can be achieved by running a `jboss/keycloak` container and attaching it to your network. Set the environment variables KEYCLOAK_USER and `KEYCLOAK_PASSWORD`, and expose port 8080.
|
|
||||||
|
|
||||||
Where HTTPS is specified throughout, use HTTP instead. You may also have to specify the exposed port, 8080.
|
|
||||||
|
|
||||||
## Steps
|
|
||||||
|
|
||||||
1. Sign in to the administration portal for your Keycloak instance at https://keycloak.example.com/auth/admin/master/console
|
|
||||||
|
|
||||||
You may note that a separate realm is specified throughout this tutorial. It is best practice not to use the master realm, as it normally contains the realm-management client that federates access using the policies and permissions you can create.
|
|
||||||
|
|
||||||
2. Navigate to the client management page at `https://keycloak.example.com/auth/admin/master/console/#/realms/your-realm/clients` (admin permissions required)
|
|
||||||
3. Click **Create** to create a new client and fill out the registration form. You should set the Root URL to the fully qualified public URL of your CodiMD instance.
|
|
||||||
4. Click **Save**
|
|
||||||
5. Set the **Access Type** of the client to `confidential`. This will make your client require a client secret upon authentication.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Additional steps to circumvent generic OAuth2 issue:
|
|
||||||
|
|
||||||
1. Select Client Scopes from the sidebar, and begin to create a new client scope using the Create button.
|
|
||||||
2. Ensure that the **Name** field is set to `id`.
|
|
||||||
3. Create a new mapper under the Mappers tab. This should reference the User Property `id`. `Claim JSON Type` should be String and all switches below should be enabled. Save the mapper.
|
|
||||||
4. Go to the client you set up in the previous steps using the Clients page, then choose the Client Scopes tab. Apply the scope you've created. This should mitigate errors as seen in [codimd/server#56](https://github.com/codimd/server/issues/56), as the `/userinfo` endpoint should now bring back the user's ID under the `id` key as well as `sub`.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
6. In the `docker-compose.yml` add the following environment variables to `app:` `environment:`
|
|
||||||
|
|
||||||
```
|
|
||||||
CMD_OAUTH2_USER_PROFILE_URL=https://keycloak.example.com/auth/realms/your-realm/protocol/openid-connect/userinfo
|
|
||||||
CMD_OAUTH2_USER_PROFILE_USERNAME_ATTR=preferred_username
|
|
||||||
CMD_OAUTH2_USER_PROFILE_DISPLAY_NAME_ATTR=name
|
|
||||||
CMD_OAUTH2_USER_PROFILE_EMAIL_ATTR=email
|
|
||||||
CMD_OAUTH2_TOKEN_URL=https://keycloak.example.com/auth/realms/your-realm/protocol/openid-connect/token
|
|
||||||
CMD_OAUTH2_AUTHORIZATION_URL=https://keycloak.example.com/auth/realms/your-realm/protocol/openid-connect/auth
|
|
||||||
CMD_OAUTH2_CLIENT_ID=<your client ID>
|
|
||||||
CMD_OAUTH2_CLIENT_SECRET=<your client secret, which you can find under the Credentials tab for your client>
|
|
||||||
CMD_OAUTH2_PROVIDERNAME=Keycloak
|
|
||||||
CMD_DOMAIN=<codimd.example.com>
|
|
||||||
CMD_PROTOCOL_USESSL=true
|
|
||||||
CMD_URL_ADDPORT=false
|
|
||||||
```
|
|
||||||
|
|
||||||
7. Run `docker-compose up -d` to apply your settings.
|
|
||||||
8. Sign in to your CodiMD using your Keycloak ID
|
|
|
@ -1,38 +0,0 @@
|
||||||
# AD LDAP auth
|
|
||||||
|
|
||||||
To setup your HedgeDoc instance with Active Directory you need the following configs:
|
|
||||||
|
|
||||||
```env
|
|
||||||
CMD_LDAP_URL=ldap://internal.example.com
|
|
||||||
CMD_LDAP_BINDDN=cn=binduser,cn=Users,dc=internal,dc=example,dc=com
|
|
||||||
CMD_LDAP_BINDCREDENTIALS=<super secret password>
|
|
||||||
CMD_LDAP_SEARCHBASE=dc=internal,dc=example,dc=com
|
|
||||||
CMD_LDAP_SEARCHFILTER=(&(objectcategory=person)(objectclass=user)(|(sAMAccountName={{username}})(mail={{username}})))
|
|
||||||
CMD_LDAP_USERIDFIELD=sAMAccountName
|
|
||||||
CMD_LDAP_PROVIDERNAME=Example Inc AD
|
|
||||||
```
|
|
||||||
|
|
||||||
`CMD_LDAP_BINDDN` is either the `distinguishedName` or the `userPrincipalName`. *This can cause "username/password is invalid" when either this value or the password from `CMD_LDAP_BINDCREDENTIALS` are incorrect.*
|
|
||||||
|
|
||||||
`CMD_LDAP_SEARCHFILTER` matches on all users and uses either the email address or the `sAMAccountName` (usually the login name you also use to login to Windows).
|
|
||||||
|
|
||||||
*Only using `sAMAccountName` looks like this:* `(&(objectcategory=person)(objectclass=user)(sAMAccountName={{username}}))`
|
|
||||||
|
|
||||||
`CMD_LDAP_USERIDFIELD` says we want to use `sAMAccountName` as unique identifier for the account itself.
|
|
||||||
|
|
||||||
`CMD_LDAP_PROVIDERNAME` just the name written above the username and password field on the login page.
|
|
||||||
|
|
||||||
Same in json:
|
|
||||||
|
|
||||||
```json
|
|
||||||
"ldap": {
|
|
||||||
"url": "ldap://internal.example.com",
|
|
||||||
"bindDn": "cn=binduser,cn=Users,dc=internal,dc=example,dc=com",
|
|
||||||
"bindCredentials": "<super secret password>",
|
|
||||||
"searchBase": "dc=internal,dc=example,dc=com",
|
|
||||||
"searchFilter": "(&(objectcategory=person)(objectclass=user)(|(sAMAccountName={{username}})(mail={{username}})))",
|
|
||||||
"useridField": "sAMAccountName",
|
|
||||||
},
|
|
||||||
```
|
|
||||||
|
|
||||||
More details and example: <https://www.npmjs.com/package/passport-ldapauth>
|
|
|
@ -1,54 +0,0 @@
|
||||||
Authentication guide - Mattermost (self-hosted)
|
|
||||||
===
|
|
||||||
|
|
||||||
**Note:** *The Mattermost setup portion of this document is just a quick guide. See the [official documentation](https://docs.mattermost.com/developer/oauth-2-0-applications.html) for more details.*
|
|
||||||
|
|
||||||
This guide uses the generic OAuth2 module for compatibility with Mattermost version 5.0 and above.
|
|
||||||
|
|
||||||
1. Sign-in with an administrator account to your Mattermost instance
|
|
||||||
2. Make sure **OAuth 2.0 Service Provider** is enabled in the Main Menu (menu button next to your username in the top left corner) --> System Console --> Custom Integrations menu, which you can find at `https://your.mattermost.domain/admin_console/integrations/custom`
|
|
||||||
![mattermost-enable-oauth2](../../images/auth/mattermost-enable-oauth2.png)
|
|
||||||
|
|
||||||
3. Navigate to the OAuth integration settings through Main Menu --> Integrations --> OAuth 2.0 Applications, at `https://your.mattermost.domain/yourteam/integrations/oauth2-apps`
|
|
||||||
4. Click on the **Add OAuth 2.0 Application** button to add a new OAuth application
|
|
||||||
![mattermost-oauth-app-add](../../images/auth/mattermost-oauth-app-add.png)
|
|
||||||
|
|
||||||
5. Fill out the form and click **Save**
|
|
||||||
![mattermost-oauth-app-form](../../images/auth/mattermost-oauth-app-form.png)
|
|
||||||
|
|
||||||
*Note: The callback URL is \<your-codimd-url\>/auth/oauth2/callback*
|
|
||||||
|
|
||||||
6. After saving the application, you'll receive the Client ID and Client Secret
|
|
||||||
![mattermost-oauth-app-done](../../images/auth/mattermost-oauth-app-done.png)
|
|
||||||
|
|
||||||
7. Add the Client ID and Client Secret to your config.json file or pass them as environment variables
|
|
||||||
* `config.json`:
|
|
||||||
```javascript
|
|
||||||
{
|
|
||||||
"production": {
|
|
||||||
"oauth2": {
|
|
||||||
"baseURL": "https://your.mattermost.domain",
|
|
||||||
"userProfileURL": "https://your.mattermost.domain/api/v4/users/me",
|
|
||||||
"userProfileUsernameAttr": "id",
|
|
||||||
"userProfileDisplayNameAttr": "username",
|
|
||||||
"userProfileEmailAttr": "email",
|
|
||||||
"tokenURL": "https://your.mattermost.domain/oauth/access_token",
|
|
||||||
"authorizationURL": "https://your.mattermost.domain/oauth/authorize",
|
|
||||||
"clientID": "ii4p1u3jz7dXXXXXXXXXXXXXXX",
|
|
||||||
"clientSecret": "mqzzx6fydbXXXXXXXXXXXXXXXX"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
* environment variables:
|
|
||||||
```sh
|
|
||||||
CMD_OAUTH2_BASEURL=https://your.mattermost.domain
|
|
||||||
CMD_OAUTH2_USER_PROFILE_URL=https://your.mattermost.domain/api/v4/users/me
|
|
||||||
CMD_OAUTH2_USER_PROFILE_USERNAME_ATTR=id
|
|
||||||
CMD_OAUTH2_USER_PROFILE_DISPLAY_NAME_ATTR=username
|
|
||||||
CMD_OAUTH2_USER_PROFILE_EMAIL_ATTR=email
|
|
||||||
CMD_OAUTH2_TOKEN_URL=https://your.mattermost.domain/oauth/access_token
|
|
||||||
CMD_OAUTH2_AUTHORIZATION_URL=https://your.mattermost.domain/oauth/authorize
|
|
||||||
CMD_OAUTH2_CLIENT_ID=ii4p1u3jz7dXXXXXXXXXXXXXXX
|
|
||||||
CMD_OAUTH2_CLIENT_SECRET=mqzzx6fydbXXXXXXXXXXXXXXXX
|
|
||||||
```
|
|
|
@ -1,55 +0,0 @@
|
||||||
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 and Nextcloud 20).
|
|
||||||
|
|
||||||
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 `\<your-codimd-url\>/auth/oauth2/callback`. Click <kbd>Add</kbd>.
|
|
||||||
![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 `<your-nextcloud-domain>` with the right domain name.
|
|
||||||
* `config.json`:
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
{
|
|
||||||
"production": {
|
|
||||||
"oauth2": {
|
|
||||||
"clientID": "ii4p1u3jz7dXXXXXXXXXXXXXXX",
|
|
||||||
"clientSecret": "mqzzx6fydbXXXXXXXXXXXXXXXX",
|
|
||||||
"authorizationURL": "https://<your-nextcloud-domain>/apps/oauth2/authorize",
|
|
||||||
"tokenURL": "https://<your-nextcloud-domain>/apps/oauth2/api/v1/token",
|
|
||||||
"userProfileURL": "https://<your-nextcloud-domain>/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://<your-nextcloud-domain>/apps/oauth2/authorize
|
|
||||||
CMD_OAUTH2_TOKEN_URL=https://<your-nextcloud-domain>/apps/oauth2/api/v1/token
|
|
||||||
CMD_OAUTH2_USER_PROFILE_URL=https://<your-nextcloud-domain>/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
|
|
||||||
```
|
|
|
@ -1,11 +0,0 @@
|
||||||
# OAuth general information
|
|
||||||
|
|
||||||
| service | callback URL (after the server URL) |
|
|
||||||
| ------- | --------- |
|
|
||||||
| facebook | `/auth/facebook/callback` |
|
|
||||||
| twitter | `/auth/twitter/callback` |
|
|
||||||
| github | `/auth/github/callback` |
|
|
||||||
| gitlab | `/auth/gitlab/callback` |
|
|
||||||
| dropbox | `/auth/dropbox/callback` |
|
|
||||||
| google | `/auth/google/callback` |
|
|
||||||
| saml | `/auth/saml/callback` |
|
|
|
@ -1,143 +0,0 @@
|
||||||
# How to setup HedgeDoc SAML with Keycloak
|
|
||||||
|
|
||||||
## Configuring Keycloak
|
|
||||||
|
|
||||||
### Get the public certificate
|
|
||||||
|
|
||||||
1. Select the Realm you want to use for your HedgeDoc SAML
|
|
||||||
2. Select "Realm Settings" in left sidebar
|
|
||||||
3. Select the "Keys" tab
|
|
||||||
4. Click the button "Certificate" at `RS256` algorithm
|
|
||||||
![keycloak_idp_cert](../../images/auth/keycloak_idp_cert.png)
|
|
||||||
5. Copy this key and save it to the file specified in `saml.idpCert` property of the HedgeDoc configuration
|
|
||||||
or `CMD_SAML_IDPCERT` environment variable
|
|
||||||
|
|
||||||
### Create a new client
|
|
||||||
|
|
||||||
1. Select "Client" in left sidebar
|
|
||||||
![keycloak_clients_overview](../../images/auth/keycloak_clients_overview.png)
|
|
||||||
2. Click on the "Create" button
|
|
||||||
3. Set a Client ID and specify this in `saml.issuer` property of the HedgeDoc configuration or `CMD_SAML_ISSUER`
|
|
||||||
environment variable
|
|
||||||
4. Select `SAML` as Client Protocol
|
|
||||||
5. Set Client SAML Endpoint to `https://hedgedoc.example.com/auth/saml` (replace `https://hedgedoc.example.com` with the
|
|
||||||
base URL of your HedgeDoc installation)
|
|
||||||
![keycloak_add_client](../../images/auth/keycloak_add_client.png)
|
|
||||||
6. Leave "Client Signature Required" enabled
|
|
||||||
7. Set Root URL to `https://hedgedoc.example.com` (replace it here also with the base URL of your HedgeDoc installation)
|
|
||||||
8. Set Valid Redirect URIs to `https://hedgedoc.example.com/auth/saml/callback` (you should also define all other
|
|
||||||
domains of your HedgeDoc installtion with the suffix `/auth/saml/callback`)
|
|
||||||
9. Set Base URL to `/`
|
|
||||||
![keycloak_client_overview](../../images/auth/keycloak_client_overview.png)
|
|
||||||
10. _(optional)_ You can set which Name ID Format should be used
|
|
||||||
|
|
||||||
## Configure HedgeDoc
|
|
||||||
|
|
||||||
### Config file
|
|
||||||
|
|
||||||
You have to put the following block inside your `config.json`:
|
|
||||||
|
|
||||||
```json
|
|
||||||
"saml": {
|
|
||||||
"issuer": "hedgedoc", // Change to the "Client ID" specified in the Keycloak Client
|
|
||||||
"identifierFormat": "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified",
|
|
||||||
"idpSsoUrl": "https://keycloak.example.org/auth/realms/test/protocol/saml", // replace keycloak.example.org with the url of your keycloak server
|
|
||||||
"idpCert": "/path/to/the/cert.pem",
|
|
||||||
"clientCert": "/path/to/the/key.pem" // this one is optional, see below
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Environment Variables
|
|
||||||
|
|
||||||
- `CMD_SAML_IDPSSOURL`: `https://keycloak.example.org/auth/realms/test/protocol/saml` (replace keycloak.example.org with
|
|
||||||
the url of your keycloak server)
|
|
||||||
- `CMD_SAML_IDPCERT`: `/path/to/the/cert.pem`
|
|
||||||
- *(optional, see below)* `CMD_SAML_CLIENTCERT`: `/path/to/the/key.pem`
|
|
||||||
- `CMD_SAML_ISSUER`: `hedgedoc` (Change to the "Client ID" specified in the Keycloak Client)
|
|
||||||
- `CMD_SAML_IDENTIFIERFORMAT`: `urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified`
|
|
||||||
|
|
||||||
## Client certificate *(optional)*
|
|
||||||
|
|
||||||
If you want keycloak to be able to verify HedgeDoc, you hava to create a client certificate. There are two options for
|
|
||||||
this:
|
|
||||||
|
|
||||||
### Create Private Keys for Signing
|
|
||||||
|
|
||||||
1. Generate the private key and certificate with the following commands:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
openssl genrsa -out priv.pem 2048
|
|
||||||
openssl req -new -x509 -key priv.pem -out cert.pem
|
|
||||||
```
|
|
||||||
|
|
||||||
*execute the following steps in keycloak*
|
|
||||||
|
|
||||||
2. Select "Client" in left sidebar
|
|
||||||
3. Go to your HedgeDoc-Client
|
|
||||||
4. Select the "SAML Keys" tab
|
|
||||||
![keycloak_saml_import_cert](../../images/auth/keycloak_saml_import_cert.png)
|
|
||||||
5. Click on "Import"
|
|
||||||
6. Select `Certificate PEM` as "Archive Format"
|
|
||||||
7. Now upload the generated cert.pem (in this case named `cert.pem`)
|
|
||||||
![keycloak_saml_import_cert_details](../../images/auth/keycloak_saml_import_cert_details.png)
|
|
||||||
8. Click on "Import"
|
|
||||||
9. Move or copy this key (in this case named `key.pem`) and save it to the file specified in `saml.clientCert` property
|
|
||||||
of the HedgeDoc configuration or in the enviroment-variable `CMD_SAML_CLIENTCERT`
|
|
||||||
|
|
||||||
### Convert Private Certificate generated by KeyCloak
|
|
||||||
|
|
||||||
Instead if generating you own certificate, you can also use the one generated by keycloak.
|
|
||||||
|
|
||||||
1. Select "Client" in left sidebar
|
|
||||||
2. Go to your HedgeDoc-Client
|
|
||||||
3. Select the "SAML Keys" tab
|
|
||||||
![keycloak_saml_export_cert](../../images/auth/keycloak_saml_export_cert.png)
|
|
||||||
|
|
||||||
5. Now click on "Export"
|
|
||||||
6. Here you can select the output format, choose `PKCS12`. You also have to set a password. Choose your own.
|
|
||||||
![keycloak_saml_export_cert_details](../../images/auth/keycloak_saml_export_cert_details.png)
|
|
||||||
6. Click on "Download" and save the file somewhere on you computer
|
|
||||||
7. You now have to extract the private Key. You can do this with the following command. WHen asked, enter your password.
|
|
||||||
|
|
||||||
```shell
|
|
||||||
openssl pkcs12 -in keystore.p12 -out key.pem -nocerts -nodes
|
|
||||||
```
|
|
||||||
|
|
||||||
8. Move or copy this key (in this case named `key.pem`) and save it to the file specified in `saml.idpCert` property of
|
|
||||||
the HedgeDoc configuration or in the enviroment-variable `CMD_SAML_CLIENTCERT`
|
|
||||||
|
|
||||||
## Use Persistent Identifiers
|
|
||||||
|
|
||||||
Instead of using the username as the owner-key in the HedgeDoc database, you can also use a persistent identifier. This
|
|
||||||
allows to change the username, without them loosing access to their notes.
|
|
||||||
|
|
||||||
1. Go to the HedgeDoc-Client in keycloak. Now enable the option "Force Name ID Format" and select "persistent" as the "
|
|
||||||
Name ID Format".
|
|
||||||
![keycloak_force_idformat](../../images/auth/keycloak_force_idformat.png)
|
|
||||||
2. For HedgeDoc to be able to use the username and email configured in keycloak, you have to create the following SAML
|
|
||||||
protocol mappers:
|
|
||||||
2.1. Create a mapper with the type `User Property`. Set the Name, Property and SAML Attribute Name to `username`. Now
|
|
||||||
you can specify a friendly name (for example `Username`)
|
|
||||||
![keycloak_mapper_username](../../images/auth/keycloak_mapper_username.png)
|
|
||||||
2.2 Create a mapper with the type `User Property`. Set the Name, Property and SAML Attribute Name to `email`. Now you
|
|
||||||
can specify a friendly name (for example `E-Mail`)
|
|
||||||
![keycloak_mapper_email](../../images/auth/keycloak_mapper_email.png)
|
|
||||||
|
|
||||||
The configured mappers should look like this:
|
|
||||||
![keycloak_mapper_overview](../../images/auth/keycloak_mapper_overview.png)
|
|
||||||
|
|
||||||
3. You now have to add the following block to the saml-definition inside your `config.json`:
|
|
||||||
|
|
||||||
```json
|
|
||||||
"attribute": {
|
|
||||||
"username": "username"
|
|
||||||
"email": "email",
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
It you configure HedgeDoc with enviroment variables, these are the ones you have to set:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
CMD_SAML_ATTRIBUTE_USERNAME=username
|
|
||||||
CMD_SAML_ATTRIBUTE_EMAIL=email
|
|
||||||
```
|
|
|
@ -1,48 +0,0 @@
|
||||||
Authentication guide - SAML (OneLogin)
|
|
||||||
===
|
|
||||||
|
|
||||||
**Note:** *This guide was written before the renaming. Just replace `HackMD` with `CodiMD` in your mind :smile: thanks!*
|
|
||||||
|
|
||||||
1. Sign-in or sign-up for an OneLogin account. (available free trial for 2 weeks)
|
|
||||||
2. Go to the administration page.
|
|
||||||
3. Select the **APPS** menu and click on the **Add Apps**.
|
|
||||||
![onelogin-add-app](../../images/auth/onelogin-add-app.png)
|
|
||||||
|
|
||||||
4. Find "SAML Test Connector (SP)" for template of settings and select it.
|
|
||||||
![onelogin-select-template](../../images/auth/onelogin-select-template.png)
|
|
||||||
|
|
||||||
5. Edit display name and icons for OneLogin dashboard as you want, and click **SAVE**.
|
|
||||||
![onelogin-edit-app-name](../../images/auth/onelogin-edit-app-name.png)
|
|
||||||
|
|
||||||
6. After that other tabs will appear, click the **Configuration**, and fill out the below items, and click **SAVE**.
|
|
||||||
* RelayState: The base URL of your CodiMD, which is issuer. (last slash is not needed)
|
|
||||||
* ACS (Consumer) URL Validator: The callback URL of your CodiMD. (serverurl + /auth/saml/callback)
|
|
||||||
* ACS (Consumer) URL: same as above.
|
|
||||||
* Login URL: login URL(SAML requester) of your CopiMD. (serverurl + /auth/saml)
|
|
||||||
![onelogin-edit-sp-metadata](../../images/auth/onelogin-edit-sp-metadata.png)
|
|
||||||
|
|
||||||
7. The registration is completed. Next, click **SSO** and copy or download the items below.
|
|
||||||
* X.509 Certificate: Click **View Details** and **DOWNLOAD** or copy the content of certificate ....(A)
|
|
||||||
* SAML 2.0 Endpoint (HTTP): Copy the URL ....(B)
|
|
||||||
![onelogin-copy-idp-metadata](../../images/auth/onelogin-copy-idp-metadata.png)
|
|
||||||
|
|
||||||
8. In your CodiMD server, create IdP certificate file from (A)
|
|
||||||
9. Add the IdP URL (B) and the Idp certificate file path to your config.json file or pass them as environment variables.
|
|
||||||
* `config.json`:
|
|
||||||
```javascript
|
|
||||||
{
|
|
||||||
"production": {
|
|
||||||
"saml": {
|
|
||||||
"idpSsoUrl": "https://*******.onelogin.com/trust/saml2/http-post/sso/******",
|
|
||||||
"idpCert": "/path/to/idp_cert.pem"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
* environment variables
|
|
||||||
```sh
|
|
||||||
CMD_SAML_IDPSSOURL=https://*******.onelogin.com/trust/saml2/http-post/sso/******
|
|
||||||
CMD_SAML_IDPCERT=/path/to/idp_cert.pem
|
|
||||||
```
|
|
||||||
10. Try sign-in with SAML from your CodiMD sign-in button or OneLogin dashboard (like the screenshot below).
|
|
||||||
![onelogin-use-dashboard](../../images/auth/onelogin-use-dashboard.png)
|
|
|
@ -1,85 +0,0 @@
|
||||||
Authentication guide - SAML
|
|
||||||
===
|
|
||||||
|
|
||||||
**Note:** *This guide was written before the renaming. Just replace `HackMD` with `CodiMD` in your mind :smile: thanks!*
|
|
||||||
|
|
||||||
The basic procedure is the same as the case of OneLogin which is mentioned in [OneLogin-Guide](./saml-onelogin.md). If you want to match your IdP, you can use more configurations as below.
|
|
||||||
|
|
||||||
* If your IdP accepts metadata XML of the service provider to ease configuration, use this url to download metadata XML.
|
|
||||||
* {{your-serverurl}}/auth/saml/metadata
|
|
||||||
* _Note: If not accessible from IdP, download to local once and upload to IdP._
|
|
||||||
* Change the value of `issuer`, `identifierFormat` to match your IdP.
|
|
||||||
* `issuer`: A unique id to identify the application to the IdP, which is the base URL of your CodiMD as default
|
|
||||||
* `identifierFormat`: A format of unique id to identify the user of IdP, which is the format based on email address as default. It is recommend that you use as below.
|
|
||||||
* urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress (default)
|
|
||||||
* urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified
|
|
||||||
* `config.json`:
|
|
||||||
```javascript
|
|
||||||
{
|
|
||||||
"production": {
|
|
||||||
"saml": {
|
|
||||||
/* omitted */
|
|
||||||
"issuer": "mycodimd"
|
|
||||||
"identifierFormat": "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
* environment variables
|
|
||||||
```
|
|
||||||
CMD_SAML_ISSUER=mycodimd
|
|
||||||
CMD_SAML_IDENTIFIERFORMAT=urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified
|
|
||||||
```
|
|
||||||
|
|
||||||
* Change mapping of attribute names to customize the displaying user name and email address to match your IdP.
|
|
||||||
* `attribute`: A dictionary to map attribute names
|
|
||||||
* `attribute.id`: A primary key of user table for your CodiMD
|
|
||||||
* `attribute.username`: Attribute name of displaying user name on CodiMD
|
|
||||||
* `attribute.email`: Attribute name of email address, which will be also used for Gravatar
|
|
||||||
* _Note: Default value of all attributes is NameID of SAML response, which is email address if `identifierFormat` is default._
|
|
||||||
* `config.json`:
|
|
||||||
```javascript
|
|
||||||
{
|
|
||||||
"production": {
|
|
||||||
"saml": {
|
|
||||||
/* omitted */
|
|
||||||
"attribute": {
|
|
||||||
"id": "sAMAccountName",
|
|
||||||
"username": "displayName",
|
|
||||||
"email": "mail"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
* environment variables
|
|
||||||
```sh
|
|
||||||
CMD_SAML_ATTRIBUTE_ID=sAMAccountName
|
|
||||||
CMD_SAML_ATTRIBUTE_USERNAME=nickName
|
|
||||||
CMD_SAML_ATTRIBUTE_EMAIL=mail
|
|
||||||
```
|
|
||||||
|
|
||||||
* If you want to control permission by group membership, add group attribute name and required group (allowed) or external group (not allowed).
|
|
||||||
* `groupAttribute`: An attribute name of group membership
|
|
||||||
* `requiredGroups`: Group names array for allowed access to CodiMD. Use vertical bar to separate for environment variables.
|
|
||||||
* `externalGroups`: Group names array for not allowed access to CodiMD. Use vertical bar to separate for environment variables.
|
|
||||||
* _Note: Evaluates `externalGroups` first_
|
|
||||||
* `config.json`:
|
|
||||||
```javascript
|
|
||||||
{
|
|
||||||
"production": {
|
|
||||||
"saml": {
|
|
||||||
/* omitted */
|
|
||||||
"groupAttribute": "memberOf",
|
|
||||||
"requiredGroups": [ "codimd-users", "board-members" ],
|
|
||||||
"externalGroups": [ "temporary-staff" ]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
* environment variables
|
|
||||||
```sh
|
|
||||||
CMD_SAML_GROUPATTRIBUTE=memberOf
|
|
||||||
CMD_SAML_REQUIREDGROUPS=codimd-users|board-members
|
|
||||||
CMD_SAML_EXTERNALGROUPS=temporary-staff
|
|
||||||
```
|
|
|
@ -1,40 +0,0 @@
|
||||||
Authentication guide - Twitter
|
|
||||||
===
|
|
||||||
|
|
||||||
**Note:** *This guide was written before the renaming. Just replace `HackMD` with `CodiMD` in your mind :smile: thanks!*
|
|
||||||
|
|
||||||
1. Sign-in or sign-up for a Twitter account
|
|
||||||
2. Go to the Twitter Application management page [here](https://apps.twitter.com/)
|
|
||||||
3. Click on the **Create New App** button to create a new Twitter app:
|
|
||||||
![create-twitter-app](../../images/auth/create-twitter-app.png)
|
|
||||||
|
|
||||||
4. Fill out the create application form, check the developer agreement box, and click **Create Your Twitter Application**
|
|
||||||
![register-twitter-application](../../images/auth/register-twitter-application.png)
|
|
||||||
|
|
||||||
*Note: you may have to register your phone number with Twitter to create a Twitter application*
|
|
||||||
|
|
||||||
To do this Click your profile icon --> Settings and privacy --> Mobile --> Select Country/region --> Enter phone number --> Click Continue
|
|
||||||
|
|
||||||
5. After you receive confirmation that the Twitter application was created, click **Keys and Access Tokens**
|
|
||||||
![twitter-app-confirmation](../../images/auth/twitter-app-confirmation.png)
|
|
||||||
|
|
||||||
6. Obtain your Twitter Consumer Key and Consumer Secret
|
|
||||||
![twitter-app-keys](../../images/auth/twitter-app-keys.png)
|
|
||||||
|
|
||||||
7. Add your Consumer Key and Consumer Secret to your `config.json` file or pass them as environment variables:
|
|
||||||
* `config.json`:
|
|
||||||
```javascript
|
|
||||||
{
|
|
||||||
"production": {
|
|
||||||
"twitter": {
|
|
||||||
"consumerKey": "esTCJFXXXXXXXXXXXXXXXXXXX",
|
|
||||||
"consumerSecret": "zpCs4tU86pRVXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
* environment variables:
|
|
||||||
```sh
|
|
||||||
CMD_TWITTER_CONSUMERKEY=esTCJFXXXXXXXXXXXXXXXXXXX
|
|
||||||
CMD_TWITTER_CONSUMERSECRET=zpCs4tU86pRVXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
|
||||||
```
|
|
|
@ -1,131 +0,0 @@
|
||||||
Pad migration guide from etherpad-lite
|
|
||||||
===
|
|
||||||
|
|
||||||
The goal of this migration is to do a "dumb" import from all the pads in Etherpad, to notes in
|
|
||||||
CodiMD. In particular, the url locations of the pads in Etherpad will be lost. Furthermore, any
|
|
||||||
metadata in Etherpad, such as revisions, author data and also formatted text will not be migrated
|
|
||||||
to CodiMD (only the plain text contents).
|
|
||||||
|
|
||||||
Note that this guide is not really meant as a support guide. I migrated my own Etherpad to CodiMD,
|
|
||||||
and it turned out to be quite easy in my opinion. In this guide I share my experience. Stuff may
|
|
||||||
require some creativity to work properly in your case. When I wrote this guide, I was using
|
|
||||||
[Etherpad 1.7.0] and [CodiMD 1.2.1]. Good luck!
|
|
||||||
|
|
||||||
[Etherpad 1.7.0]: https://github.com/ether/etherpad-lite/tree/1.7.0
|
|
||||||
[CodiMD 1.2.1]: https://github.com/codimd/server/tree/1.2.1
|
|
||||||
|
|
||||||
## 0. Requirements
|
|
||||||
|
|
||||||
- `curl`
|
|
||||||
- running Etherpad server
|
|
||||||
- running CodiMD server
|
|
||||||
- [codimd-cli]
|
|
||||||
|
|
||||||
[codimd-cli]: https://github.com/codimd/cli/blob/master/bin/codimd
|
|
||||||
|
|
||||||
## 1. Retrieve the list of pads
|
|
||||||
|
|
||||||
First, compose a list of all the pads that you want to have migrated from your Etherpad. Other than
|
|
||||||
the admin interface, Etherpad does not have a dedicated function to dump a list of all the pads.
|
|
||||||
However, the Etherpad wiki explains how to list all the pads by [talking directly to the
|
|
||||||
database][howtolistallpads].
|
|
||||||
|
|
||||||
You will end up with a file containing a pad name on each line:
|
|
||||||
|
|
||||||
```
|
|
||||||
date-ideas
|
|
||||||
groceries
|
|
||||||
london
|
|
||||||
weddingchecklist
|
|
||||||
(...)
|
|
||||||
```
|
|
||||||
|
|
||||||
[howtolistallpads]: https://github.com/ether/etherpad-lite/wiki/How-to-list-all-pads/49701ecdcbe07aea7ad27ffa23aed0d99c2e17db
|
|
||||||
|
|
||||||
## 2. Run the migration
|
|
||||||
|
|
||||||
Download [codimd-cli] and put the script in the same directory as the file containing the pad names.
|
|
||||||
Add to this directory the file listed below, I called it `migrate-etherpad.sh`. Modify at least the
|
|
||||||
configuration settings `ETHERPAD_SERVER` and `CODIMD_SERVER`.
|
|
||||||
|
|
||||||
```shell
|
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
# migrate-etherpad.sh
|
|
||||||
#
|
|
||||||
# Description: Migrate pads from etherpad to codimd
|
|
||||||
# Author: Daan Sprenkels <hello@dsprenkels.com>
|
|
||||||
|
|
||||||
# This script uses the codimd command line script[1] to import a list of pads from
|
|
||||||
# [1]: https://github.com/codimd/cli/blob/master/bin/codimd
|
|
||||||
|
|
||||||
# The base url to where etherpad is hosted
|
|
||||||
ETHERPAD_SERVER="https://etherpad.example.com"
|
|
||||||
|
|
||||||
# The base url where codimd is hosted
|
|
||||||
CODIMD_SERVER="https://codimd.example.com"
|
|
||||||
|
|
||||||
# Write a list of pads and the urls which they were migrated to
|
|
||||||
REDIRECTS_FILE="redirects.txt"
|
|
||||||
|
|
||||||
|
|
||||||
# Fail if not called correctly
|
|
||||||
if (( $# != 1 )); then
|
|
||||||
echo "Usage: $0 PAD_NAMES_FILE"
|
|
||||||
exit 2
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Do the migration
|
|
||||||
for PAD_NAME in $1; do
|
|
||||||
# Download the pad
|
|
||||||
PAD_FILE="$(mktemp)"
|
|
||||||
curl "$ETHERPAD_SERVER/p/$PAD_NAME/export/txt" >"$PAD_FILE"
|
|
||||||
|
|
||||||
# Import the pad into codimd
|
|
||||||
OUTPUT="$(./codimd import "$PAD_FILE")"
|
|
||||||
echo "$PAD_NAME -> $OUTPUT" >>"$REDIRECTS_FILE"
|
|
||||||
done
|
|
||||||
```
|
|
||||||
|
|
||||||
Call this file like this:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
./migrate-etherpad.sh pad_names.txt
|
|
||||||
```
|
|
||||||
|
|
||||||
This will download all the pads in `pad_names.txt` and put them on CodiMD. They will get assigned
|
|
||||||
random ids, so you won't be able to find them. The script will save the mappings to a file though
|
|
||||||
(in my case `redirects.txt`). You can use this file to redirect your users when they visit your
|
|
||||||
etherpad using a `301 Permanent Redirect` status code (see the next section).
|
|
||||||
|
|
||||||
## 3. Setup redirects (optional)
|
|
||||||
|
|
||||||
I got a `redirects.txt` file that looked a bit like this:
|
|
||||||
|
|
||||||
```
|
|
||||||
date-ideas -> Found. Redirecting to https://codimd.example.com/mPt0KfiKSBOTQ3mNcdfn
|
|
||||||
groceries -> Found. Redirecting to https://codimd.example.com/UukqgwLfhYyUUtARlcJ2_y
|
|
||||||
london -> Found. Redirecting to https://codimd.example.com/_d3wa-BE8t4Swv5w7O2_9R
|
|
||||||
weddingchecklist -> Found. Redirecting to https://codimd.example.com/XcQGqlBjl0u40wfT0N8TzQ
|
|
||||||
(...)
|
|
||||||
```
|
|
||||||
|
|
||||||
Using some `sed` magic, I changed it to an nginx config snippet:
|
|
||||||
|
|
||||||
```
|
|
||||||
location = /p/date-ideas {
|
|
||||||
return 301 https://codimd.example.com/mPt0M1KfiKSBOTQ3mNcdfn;
|
|
||||||
}
|
|
||||||
location = /p/groceries {
|
|
||||||
return 301 https://codimd.example.com/UukqgwLfhYyUUtARlcJ2_y;
|
|
||||||
}
|
|
||||||
location = /p/london {
|
|
||||||
return 301 https://codimd.example.com/_d3wa-BE8t4Swv5w7O2_9R;
|
|
||||||
}
|
|
||||||
location = /p/weddingchecklist {
|
|
||||||
return 301 https://codimd.example.com/XcQGqlBjl0u40wfT0N8TzQ;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
I put this file into my `etherpad.example.com` nginx config, such that all the users would be
|
|
||||||
redirected accordingly.
|
|
|
@ -1,56 +0,0 @@
|
||||||
Migrations and Notable Changes
|
|
||||||
===
|
|
||||||
|
|
||||||
## Migrating to 1.4.0
|
|
||||||
|
|
||||||
We dropped support for node 6 with this version. If you have any trouble running this version, please double check that you are running at least node 8!
|
|
||||||
|
|
||||||
## Migrating to 1.3.2
|
|
||||||
|
|
||||||
This is not a breaking change, but to stay up to date with the community
|
|
||||||
repository, you may need to update a few urls. This is not a breaking change.
|
|
||||||
|
|
||||||
See more at [issue #10](https://github.com/codimd/server/issues/10)
|
|
||||||
|
|
||||||
**Native setup using git:**
|
|
||||||
|
|
||||||
Change the upstream remote using `git remote set-url origin https://github.com/codimd/server.git`.
|
|
||||||
|
|
||||||
**Docker:**
|
|
||||||
|
|
||||||
When you use our [container repository](https://github.com/codimd/container)
|
|
||||||
(which was previously `codimd-container`) all you can simply run `git pull` and
|
|
||||||
your `docker-compose.yml` will be updated.
|
|
||||||
|
|
||||||
When you setup things yourself, make sure you use the new image:
|
|
||||||
[`quay.io/codimd/server`](https://quay.io/repository/codimd/server?tab=tags).
|
|
||||||
|
|
||||||
**Heroku:**
|
|
||||||
|
|
||||||
All you need to do is [disconnect GitHub](https://devcenter.heroku.com/articles/github-integration#disconnecting-from-github)
|
|
||||||
and [reconnect it](https://devcenter.heroku.com/articles/github-integration#enabling-github-integration)
|
|
||||||
with this new repository.
|
|
||||||
|
|
||||||
Or you can use our Heroku button and redeploy your instance and link the old
|
|
||||||
database again.
|
|
||||||
|
|
||||||
## Migrating to 1.1.0
|
|
||||||
|
|
||||||
We deprecated the older lower case config style and moved on to camel case style. Please have a look at the current `config.json.example` and check the warnings on startup.
|
|
||||||
|
|
||||||
*Notice: This is not a breaking change right now but will be in the future*
|
|
||||||
|
|
||||||
## Migrating to 0.5.0
|
|
||||||
|
|
||||||
[migration-to-0.5.0 migration tool](https://github.com/hackmdio/migration-to-0.5.0)
|
|
||||||
|
|
||||||
We don't use LZString to compress socket.io data and DB data after version 0.5.0.
|
|
||||||
Please run the migration tool if you're upgrading from the old version.
|
|
||||||
|
|
||||||
## Migrating to 0.4.0
|
|
||||||
|
|
||||||
[migration-to-0.4.0 migration tool](https://github.com/hackmdio/migration-to-0.4.0)
|
|
||||||
|
|
||||||
We've dropped MongoDB after version 0.4.0.
|
|
||||||
So here is the migration tool for you to transfer the old DB data to the new DB.
|
|
||||||
This tool is also used for official service.
|
|
|
@ -1,85 +0,0 @@
|
||||||
Minio Guide for CodiMD
|
|
||||||
===
|
|
||||||
|
|
||||||
**Note:** *This guide was written before the renaming. Just replace `HackMD` with `CodiMD` in your mind :smile: thanks!*
|
|
||||||
|
|
||||||
1. First of all you need to setup Minio itself.
|
|
||||||
|
|
||||||
Please refer to the [official Minio docs](https://docs.minio.io/) for an
|
|
||||||
production setup.
|
|
||||||
|
|
||||||
For checking it out and development purposes a non-persistent setup is enough:
|
|
||||||
```sh
|
|
||||||
docker run --name test-minio --rm -d -p 9000:9000 minio/minio server /data
|
|
||||||
```
|
|
||||||
|
|
||||||
*Please notice this is not for productive use as all your data gets lost
|
|
||||||
when you stop this container*
|
|
||||||
|
|
||||||
2. Next step is to get the credentials form the container:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
docker logs test-minio
|
|
||||||
```
|
|
||||||
|
|
||||||
![docker logs](../images/minio-image-upload/docker-logs.png)
|
|
||||||
|
|
||||||
3. Open http://localhost:9000 and login with the shown credentials.
|
|
||||||
|
|
||||||
![minio default view](../images/minio-image-upload/default-view.png)
|
|
||||||
|
|
||||||
4. Create a bucket for CodiMD
|
|
||||||
|
|
||||||
![minio create bucket](../images/minio-image-upload/create-bucket.png)
|
|
||||||
|
|
||||||
5. Add a policy for the prefix `uploads` and make it read-only.
|
|
||||||
|
|
||||||
![minio edit policy](../images/minio-image-upload/open-edit-policy.png)
|
|
||||||
*Open policy editor*
|
|
||||||
|
|
||||||
![minio policy adding](../images/minio-image-upload/create-policy.png)
|
|
||||||
*Add policy for uploads*
|
|
||||||
|
|
||||||
6. Set credentials and configs for Minio in CodiMD's `config.json`
|
|
||||||
|
|
||||||
```JSON
|
|
||||||
"minio": {
|
|
||||||
"accessKey": "888MXJ7EP4XXXXXXXXX",
|
|
||||||
"secretKey": "yQS2EbM1Y6IJrp/1BUKWq2/XXXXXXXXXXXXXXX",
|
|
||||||
"endPoint": "localhost",
|
|
||||||
"port": 9000,
|
|
||||||
"secure": false
|
|
||||||
}
|
|
||||||
```
|
|
||||||
*You have to use different values for `endpoint` and `port` for a production
|
|
||||||
setup. Keep in mind the `endpoint`-address has to be public accessible from
|
|
||||||
your browser.*
|
|
||||||
|
|
||||||
7. Set bucket name
|
|
||||||
|
|
||||||
```JSON
|
|
||||||
"s3bucket": "codimd"
|
|
||||||
```
|
|
||||||
|
|
||||||
8. Set upload type.
|
|
||||||
|
|
||||||
```JSON
|
|
||||||
"imageuploadtype": "minio"
|
|
||||||
```
|
|
||||||
|
|
||||||
9. Review your config.
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
// all your other config…
|
|
||||||
"minio": {
|
|
||||||
"accessKey": "888MXJ7EP4XXXXXXXXX",
|
|
||||||
"secretKey": "yQS2EbM1Y6IJrp/1BUKWq2/XXXXXXXXXXXXXXX",
|
|
||||||
"endPoint": "localhost",
|
|
||||||
"port": 9000,
|
|
||||||
"secure": false
|
|
||||||
},
|
|
||||||
"s3bucket": "codimd",
|
|
||||||
"imageuploadtype": "minio"
|
|
||||||
}
|
|
||||||
```
|
|
|
@ -1,26 +0,0 @@
|
||||||
Setup your terms of use
|
|
||||||
===
|
|
||||||
|
|
||||||
To setup your terms of use, you need to provide a document called `terms-of-use.md` which contains them. Of course written in Markdown.
|
|
||||||
|
|
||||||
It has to be provided under `./public/docs/` and will be automatically turned into a CodiMD document. It will also automatically updated as soon as you change the document on disk.
|
|
||||||
|
|
||||||
As soon as the file exists a link will show up in the bottom part along with the release notes and link to them.
|
|
||||||
|
|
||||||
Setup your privacy policy
|
|
||||||
===
|
|
||||||
|
|
||||||
To add a privacy policy you can use the same technique as for the terms of use. The main difference is that the document is called `privacy.md`.
|
|
||||||
|
|
||||||
See our example file `./public/docs/privacy.md.example` container some useful hints for writing your own privacy policy.
|
|
||||||
|
|
||||||
As with the terms of use, a link to the privacy notices will show up in the area where the release notes are provided on the index page.
|
|
||||||
|
|
||||||
Setup your imprint
|
|
||||||
===
|
|
||||||
|
|
||||||
To add an imprint you can use the same technique as for the terms of use. The main difference is that the document is called `imprint.md`.
|
|
||||||
|
|
||||||
It has to be provided under `./public/docs/` and will be automatically turned into a CodiMD document. It will also automatically updated as soon as you change the document on disk.
|
|
||||||
|
|
||||||
As with the terms of use, a link to the imprint will show up in the area where the release notes are provided on the index page.
|
|
|
@ -1,84 +0,0 @@
|
||||||
Guide - Setup CodiMD S3 image upload
|
|
||||||
===
|
|
||||||
|
|
||||||
**Note:** *This guide was written before the renaming. Just replace `HackMD` with `CodiMD` in your mind :smile: thanks!*
|
|
||||||
|
|
||||||
1. Go to [AWS S3 console](https://console.aws.amazon.com/s3/home) and create a new bucket.
|
|
||||||
|
|
||||||
![create-bucket](../images/s3-image-upload/create-bucket.png)
|
|
||||||
|
|
||||||
2. Click on bucket, select **Properties** on the side panel, and find **Permission** section. Click **Edit bucket policy**.
|
|
||||||
|
|
||||||
![bucket-property](../images/s3-image-upload/bucket-property.png)
|
|
||||||
|
|
||||||
3. Enter the following policy, replace `bucket_name` with your bucket name:
|
|
||||||
|
|
||||||
![bucket-policy-editor](../images/s3-image-upload/bucket-policy-editor.png)
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"Version": "2012-10-17",
|
|
||||||
"Statement": [
|
|
||||||
{
|
|
||||||
"Effect": "Allow",
|
|
||||||
"Principal": "*",
|
|
||||||
"Action": "s3:GetObject",
|
|
||||||
"Resource": "arn:aws:s3:::bucket_name/uploads/*"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
4. Go to IAM console and create a new IAM user. Remember your user credentials(`key`/`access token`)
|
|
||||||
|
|
||||||
5. Enter user page, select **Permission** tab, look at **Inline Policies** section, and click **Create User Policy**
|
|
||||||
|
|
||||||
![iam-user](../images/s3-image-upload/iam-user.png)
|
|
||||||
|
|
||||||
6. Select **Custom Policy**
|
|
||||||
|
|
||||||
![custom-policy](../images/s3-image-upload/custom-policy.png)
|
|
||||||
|
|
||||||
7. Enter the following policy, replace `bucket_name` with your bucket name:
|
|
||||||
|
|
||||||
![review-policy](../images/s3-image-upload/review-policy.png)
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"Version": "2012-10-17",
|
|
||||||
"Statement": [
|
|
||||||
{
|
|
||||||
"Effect": "Allow",
|
|
||||||
"Action": [
|
|
||||||
"s3:*"
|
|
||||||
],
|
|
||||||
"Resource": [
|
|
||||||
"arn:aws:s3:::bucket_name/uploads/*"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
8. Edit `config.json` and set following keys:
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
{
|
|
||||||
"production": {
|
|
||||||
...
|
|
||||||
"imageuploadtype": "s3",
|
|
||||||
"s3": {
|
|
||||||
"accessKeyId": "YOUR_S3_ACCESS_KEY_ID",
|
|
||||||
"secretAccessKey": "YOUR_S3_ACCESS_KEY",
|
|
||||||
"region": "YOUR_S3_REGION" // example: ap-northeast-1
|
|
||||||
},
|
|
||||||
"s3bucket": "YOUR_S3_BUCKET_NAME"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
9. In additional to edit `config.json` directly, you could also try [environment variables](../configuration.md).
|
|
||||||
|
|
||||||
## Related Tools
|
|
||||||
|
|
||||||
* [AWS Policy Generator](http://awspolicygen.s3.amazonaws.com/policygen.html)
|
|
|
@ -1,54 +0,0 @@
|
||||||
# History of HedgeDoc
|
|
||||||
|
|
||||||
## It started with HackMD
|
|
||||||
|
|
||||||
HackMD is the origin of this project, which was mostly developed by Max Wu and
|
|
||||||
Yukai Huang. Originally, this was open source under MIT license, but was
|
|
||||||
[relicensed in October 2017 to be AGPLv3](https://github.com/hackmdio/codimd/pull/578).
|
|
||||||
At the same time, [hackmd.io](https://hackmd.io) was founded to offer a
|
|
||||||
commercial version of HackMD.
|
|
||||||
|
|
||||||
The AGPLv3-version was developed and released by the community, this was for a
|
|
||||||
while referred to as "HackMD community edition".
|
|
||||||
|
|
||||||
*For more on the splitting of the projects, please refer to [A note to our community (2017-10-11)](https://hackmd.io/c/community-news/https%3A%2F%2Fhackmd.io%2Fs%2Fr1_4j9_hZ).*
|
|
||||||
|
|
||||||
|
|
||||||
## HackMD CE became CodiMD
|
|
||||||
|
|
||||||
In June 2018, CodiMD was renamed from its former name "HackMD" and continued to
|
|
||||||
be developed under AGPLv3 by the community. We decided to change the name to
|
|
||||||
break the confusion between HackMD (enterprise offering) and CodiMD (community
|
|
||||||
project), as people mistook it for an open core development model.
|
|
||||||
|
|
||||||
*For the whole renaming story, see the [issue where the renaming was discussed](https://github.com/hackmdio/hackmd/issues/720).*
|
|
||||||
|
|
||||||
|
|
||||||
## CodiMD went independent
|
|
||||||
|
|
||||||
In March 2019, a discussion over licensing, governance and the future of CodiMD lead to the formation of a distinct
|
|
||||||
GitHub organization. Up to that point, the community project resided in the organization of hackmdio but was for the
|
|
||||||
most part self-organized.
|
|
||||||
|
|
||||||
During that debate, we did not reach an agreement that would have allowed us to move the repository, so we simply forked
|
|
||||||
it. We still welcome the HackMD team as part of our community, especially since a large portion of this code base
|
|
||||||
originated with them.
|
|
||||||
|
|
||||||
*For the debate that lead to this step, please refer to
|
|
||||||
the [governance debate](https://github.com/hackmdio/hackmd/issues/1170)
|
|
||||||
and [the announcement of the new repository](https://github.com/hedgedoc/hedgedoc/issues/10).*
|
|
||||||
|
|
||||||
## CodiMD became HedgeDoc
|
|
||||||
|
|
||||||
With two actively named forks sharing the same name,
|
|
||||||
both [insisting on being the original/actual owner of the name CodiMD](https://github.com/hackmdio/codimd/issues/1219),
|
|
||||||
people became rightfully confused about the projects sharing the same name.
|
|
||||||
|
|
||||||
After roughly a year of being stuck on the name issue, the HedgeDoc community decided to take action and started
|
|
||||||
a [renaming process in April 2020](https://community.codimd.org/t/renaming-yet-another-time/102). With a good head start
|
|
||||||
in the amount of names, it was decided that an entire rebranding should take place and therefore, after
|
|
||||||
a [name was agreed on in July 2020](https://community.codimd.org/t/codimd-becomes-hedgedoc/170), the next step was
|
|
||||||
to [find a logo](https://community.codimd.org/t/time-to-find-the-hedgedoc-logo/171).
|
|
||||||
|
|
||||||
In November of 2020, roughly 7 months after the initiative was started, a logo was found, the rebranding of the
|
|
||||||
application as well as all community pages took place and the time of name conflicts was over. (hopefully.)
|
|
Before Width: | Height: | Size: 120 KiB |
Before Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 113 KiB |
Before Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 44 KiB |
Before Width: | Height: | Size: 5.5 KiB |
Before Width: | Height: | Size: 53 KiB |
Before Width: | Height: | Size: 203 KiB |
Before Width: | Height: | Size: 77 KiB |
Before Width: | Height: | Size: 5.9 KiB |
Before Width: | Height: | Size: 73 KiB |
Before Width: | Height: | Size: 52 KiB |
Before Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 54 KiB |
Before Width: | Height: | Size: 177 KiB |
Before Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 177 KiB |
Before Width: | Height: | Size: 48 KiB |
Before Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 31 KiB |
Before Width: | Height: | Size: 61 KiB |
Before Width: | Height: | Size: 46 KiB |
Before Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 40 KiB |
Before Width: | Height: | Size: 234 KiB |
Before Width: | Height: | Size: 120 KiB |
Before Width: | Height: | Size: 180 KiB |
Before Width: | Height: | Size: 72 KiB |
Before Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 60 KiB |
Before Width: | Height: | Size: 198 KiB |
Before Width: | Height: | Size: 187 KiB |
Before Width: | Height: | Size: 159 KiB |
Before Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 72 KiB |
Before Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 53 KiB |
Before Width: | Height: | Size: 70 KiB |
Before Width: | Height: | Size: 69 KiB |
Before Width: | Height: | Size: 54 KiB |
Before Width: | Height: | Size: 89 KiB |
Before Width: | Height: | Size: 98 KiB |
|
@ -1,25 +1,11 @@
|
||||||
# Welcome to the HedgeDoc Documentation
|
# Welcome to the HedgeDoc 2 Documentation
|
||||||
|
|
||||||
![HedgeDoc Logo](images/hedgedoc_logo_horizontal.svg)
|
![HedgeDoc Logo](images/hedgedoc_logo_horizontal.svg)
|
||||||
|
|
||||||
HedgeDoc lets you create real-time collaborative markdown notes. You can test-drive it by visiting
|
🚧⚠️🚧 **HedgeDoc 2.0 is still in development!**
|
||||||
our [HedgeDoc demo server][hedgedoc-demo].
|
You are probably looking for the 1.x docs.
|
||||||
|
Find them in the `master` branch and on [docs.hedgedoc.org](https://docs.hedgedoc.org).
|
||||||
|
|
||||||
It is inspired by Hackpad, Etherpad and similar collaborative editors. This project originated with the team
|
If you want to help us to develop HedgeDoc 2, join us on [Matrix][matrix.org-url]!
|
||||||
at [HackMD](https://hackmd.io) and now forked into its own
|
|
||||||
organisation. [A longer writeup can be read in the history doc](history.md)
|
|
||||||
or [you can have a look at an explanitory graph over at our website][hedgedoc-history].
|
|
||||||
|
|
||||||
If you have any questions that aren't answered here, feel free to ask us on [Matrix][matrix.org-url], stop by
|
|
||||||
our [community forums][hedgedoc-community] or have a look at our [FAQ][hedgedoc-faq].
|
|
||||||
|
|
||||||
|
|
||||||
[hedgedoc-demo]: https://demo.hedgedoc.org
|
|
||||||
|
|
||||||
[hedgedoc-history]: https://hedgedoc.org/history
|
|
||||||
|
|
||||||
[hedgedoc-faq]: https://hedgedoc.org/faq
|
|
||||||
|
|
||||||
[matrix.org-url]: https://chat.hedgedoc.org
|
[matrix.org-url]: https://chat.hedgedoc.org
|
||||||
|
|
||||||
[hedgedoc-community]: https://community.hedgedoc.org
|
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
Cloudron
|
|
||||||
===
|
|
||||||
|
|
||||||
Install CodiMD on [Cloudron](https://cloudron.io):
|
|
||||||
|
|
||||||
[![Install](https://cloudron.io/img/button.svg)](https://cloudron.io/button.html?app=io.hackmd.cloudronapp)
|
|
|
@ -1,26 +0,0 @@
|
||||||
# LinuxServer.io HedgeDoc Image
|
|
||||||
|
|
||||||
[![Discord](https://img.shields.io/discord/354974912613449730.svg?color=94398d&labelColor=555555&logoColor=ffffff&style=for-the-badge&label=Discord&logo=discord)](https://discord.gg/YWrKVTn "realtime support / chat with the community and the team.")
|
|
||||||
[![GitHub Release](https://img.shields.io/github/release/linuxserver/docker-hedgedoc.svg?color=94398d&labelColor=555555&logoColor=ffffff&style=for-the-badge&logo=github)](https://github.com/linuxserver/docker-hedgedoc/releases)
|
|
||||||
[![GitHub Package Repository](https://img.shields.io/static/v1.svg?color=94398d&labelColor=555555&logoColor=ffffff&style=for-the-badge&label=linuxserver.io&message=GitHub%20Package&logo=github)](https://github.com/linuxserver/docker-hedgedoc/packages)
|
|
||||||
[![GitLab Container Registry](https://img.shields.io/static/v1.svg?color=94398d&labelColor=555555&logoColor=ffffff&style=for-the-badge&label=linuxserver.io&message=GitLab%20Registry&logo=gitlab)](https://gitlab.com/linuxserver.io/docker-hedgedoc/container_registry)
|
|
||||||
[![MicroBadger Layers](https://img.shields.io/microbadger/layers/linuxserver/hedgedoc.svg?color=94398d&labelColor=555555&logoColor=ffffff&style=for-the-badge)](https://microbadger.com/images/linuxserver/hedgedoc "Get your own version badge on microbadger.com")
|
|
||||||
[![Docker Pulls](https://img.shields.io/docker/pulls/linuxserver/hedgedoc.svg?color=94398d&labelColor=555555&logoColor=ffffff&style=for-the-badge&label=pulls&logo=docker)](https://hub.docker.com/r/linuxserver/hedgedoc)
|
|
||||||
[![Docker Stars](https://img.shields.io/docker/stars/linuxserver/hedgedoc.svg?color=94398d&labelColor=555555&logoColor=ffffff&style=for-the-badge&label=stars&logo=docker)](https://hub.docker.com/r/linuxserver/hedgedoc)
|
|
||||||
[![Jenkins Build](https://img.shields.io/jenkins/build?labelColor=555555&logoColor=ffffff&style=for-the-badge&jobUrl=https%3A%2F%2Fci.linuxserver.io%2Fjob%2FDocker-Pipeline-Builders%2Fjob%2Fdocker-hedgedoc%2Fjob%2Fmain%2F&logo=jenkins)](https://ci.linuxserver.io/job/Docker-Pipeline-Builders/job/docker-hedgedoc/job/main/)
|
|
||||||
[![LSIO CI](https://img.shields.io/badge/dynamic/yaml?color=94398d&labelColor=555555&logoColor=ffffff&style=for-the-badge&label=CI&query=CI&url=https%3A%2F%2Fci-tests.linuxserver.io%2Flinuxserver%2Fhedgedoc%2Flatest%2Fci-status.yml)](https://ci-tests.linuxserver.io/linuxserver/hedgedoc/latest/index.html)
|
|
||||||
|
|
||||||
[LinuxServer.io](https://linuxserver.io) have created an Ubuntu-based multi-arch container image for x86-64, arm64 and
|
|
||||||
armhf.
|
|
||||||
|
|
||||||
- It supports all the environment variables detailed in the [configuration documentation](../configuration.md) to modify
|
|
||||||
it according to your needs.
|
|
||||||
- It gets rebuilt on new releases from HedgeDoc and also weekly if necessary to update any other package changes in the
|
|
||||||
underlying container, making it easy to keep your HedgeDoc instance up to date.
|
|
||||||
- It also details how to
|
|
||||||
easily [utilize Docker networking to reverse proxy](https://github.com/linuxserver/docker-hedgedoc/#application-setup)
|
|
||||||
HedgeDoc using their [SWAG docker image](https://github.com/linuxserver/docker-swag)
|
|
||||||
|
|
||||||
In order to contribute check the LinuxServer.io [GitHub repository](https://github.com/linuxserver/docker-hedgedoc/) for
|
|
||||||
HedgeDoc. And to find all tags and versions of the image, check
|
|
||||||
the [Docker Hub repository](https://hub.docker.com/r/linuxserver/hedgedoc).
|
|
|
@ -1,23 +0,0 @@
|
||||||
CodiMD Docker Image
|
|
||||||
===
|
|
||||||
|
|
||||||
[![Try in PWD](https://cdn.rawgit.com/play-with-docker/stacks/cff22438/assets/images/button.png)](http://play-with-docker.com?stack=https://github.com/codimd/container/raw/master/docker-compose.yml&stack_name=codimd)
|
|
||||||
|
|
||||||
|
|
||||||
**Debian-based version:**
|
|
||||||
|
|
||||||
[![Docker Repository on Quay](https://quay.io/repository/codimd/server/status "Docker Repository on Quay")](https://quay.io/repository/codimd/server)
|
|
||||||
|
|
||||||
|
|
||||||
**Alpine-based version:**
|
|
||||||
|
|
||||||
[![Docker Repository on Quay](https://quay.io/repository/codimd/server/status "Docker Repository on Quay")](https://quay.io/repository/codimd/server)
|
|
||||||
|
|
||||||
The easiest way to setup CodiMD using docker are using the following three commands:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
git clone https://github.com/codimd/container.git codimd-container
|
|
||||||
cd codimd-container
|
|
||||||
docker-compose up
|
|
||||||
```
|
|
||||||
Read more about it in the [container repository](https://github.com/codimd/container).
|
|
|
@ -1,7 +0,0 @@
|
||||||
Heroku Deployment
|
|
||||||
===
|
|
||||||
|
|
||||||
You can quickly setup a sample Heroku CodiMD application by clicking the button
|
|
||||||
below.
|
|
||||||
|
|
||||||
[![Deploy on Heroku](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy?template=https://github.com/codimd/server/tree/master)
|
|
|
@ -1,6 +0,0 @@
|
||||||
Kubernetes
|
|
||||||
===
|
|
||||||
|
|
||||||
To install use `helm install stable/hackmd`.
|
|
||||||
|
|
||||||
For all further details, please check out the offical CodiMD [K8s helm chart](https://github.com/kubernetes/charts/tree/master/stable/hackmd).
|
|
|
@ -1,44 +0,0 @@
|
||||||
Manual Installation
|
|
||||||
===
|
|
||||||
|
|
||||||
## Requirements on your server
|
|
||||||
|
|
||||||
- Node.js 8.5 or up
|
|
||||||
- Database (PostgreSQL, MySQL, MariaDB, SQLite, MSSQL). Must use charset `utf8`: this is typically the
|
|
||||||
default in PostgreSQL and SQLite, while in MySQL and MariaDB utf8 might need to be set with
|
|
||||||
`alter database <DBNAME> character set utf8 collate utf8_bin;`
|
|
||||||
- npm (and its dependencies, [node-gyp](https://github.com/nodejs/node-gyp#installation))
|
|
||||||
- yarn
|
|
||||||
- Bash (for the setup script)
|
|
||||||
- For **building** CodiMD we recommend to use a machine with at least **2GB** RAM
|
|
||||||
|
|
||||||
|
|
||||||
## Instructions
|
|
||||||
|
|
||||||
1. Check if you meet the [requirements at the top of this document](#requirements-on-your-server).
|
|
||||||
2. Clone this repository (preferred) or download a release and unzip it.
|
|
||||||
3. Enter the directory and type `bin/setup`, which will install npm dependencies and create configs.
|
|
||||||
4. Modify `config.json`, see docs [here](https://github.com/codimd/server/blob/master/docs/configuration-config-file.md).
|
|
||||||
5. Instead of modifying `config.json`, it's possible to configure CodiMD through environment variables which will
|
|
||||||
overwrite the configs, see docs [here](https://github.com/codimd/server/blob/master/docs/configuration-env-vars.md).
|
|
||||||
6. Build front-end bundle by `yarn run build` (use `yarn run dev` if you are in development)
|
|
||||||
7. Modify the file named `.sequelizerc`, change the value of the variable `url` with your db connection string. For example:
|
|
||||||
- `postgres://username:password@localhost:5432/codimd`
|
|
||||||
- `mysql://username:password@localhost:3306/codimd`
|
|
||||||
- `sqlite://:memory:`
|
|
||||||
8. It is recommended to start your server manually once: `npm start --production`, this way it's easier to see warnings or errors that might occur (leave out `--production` for development).
|
|
||||||
9. Run the server as you like (node, forever, pm2, SystemD, Init-Scripts)
|
|
||||||
|
|
||||||
|
|
||||||
## How to upgrade your installation
|
|
||||||
|
|
||||||
If you are upgrading CodiMD from an older version, follow these steps:
|
|
||||||
|
|
||||||
1. Check if you meet the [requirements at the top of this document](#requirements-on-your-server).
|
|
||||||
2. Verify which version you were running before and take a look at [migrations and breaking changes](../guides/migrations-and-breaking-changes.md) to see if additional steps, or configuration changes are necessary!
|
|
||||||
3. Fully stop your old CodiMD server.
|
|
||||||
4. `git pull` or unzip a new release in the directory.
|
|
||||||
5. Run `bin/setup`. This will take care of installing dependencies. It is safe to run on an existing installation.
|
|
||||||
6. Build front-end bundle by `yarn run build` (use `yarn run dev` if you are in development).
|
|
||||||
7. It is recommended to start your server manually once: `npm start --production`, this way it's easier to see warnings or errors that might occur (leave out `--production` for development).
|
|
||||||
8. You can now restart the CodiMD server!
|
|
|
@ -1,96 +0,0 @@
|
||||||
# Using a Reverse Proxy with HedgeDoc
|
|
||||||
|
|
||||||
If you want to use a reverse proxy to serve HedgeDoc, here are the essential configs that you'll have to do.
|
|
||||||
|
|
||||||
This documentation will cover HTTPS setup, with comments for HTTP setup.
|
|
||||||
|
|
||||||
## HedgeDoc config
|
|
||||||
|
|
||||||
[Full explanation of the configuration options](../configuration.md)
|
|
||||||
|
|
||||||
| `config.json` parameter | Environment variable | Value | Example |
|
|
||||||
|-------------------------|----------------------|-------|---------|
|
|
||||||
| `domain` | `CMD_DOMAIN` | The full domain where your instance will be available | `hedgedoc.example.com` |
|
|
||||||
| `host` | `CMD_HOST` | An ip or domain name that is only available to HedgeDoc and your reverse proxy | `localhost` |
|
|
||||||
| `port` | `CMD_PORT` | An available port number on that IP | `3000` |
|
|
||||||
| `path` | `CMD_PATH` | path to UNIX domain socket to listen on (if specified, `host` or `CMD_HOST` and `port` or `CMD_PORT` are ignored) | `/var/run/hedgedoc.sock` |
|
|
||||||
| `protocolUseSSL` | `CMD_PROTOCOL_USESSL` | `true` if you want to serve your instance over SSL (HTTPS), `false` if you want to use plain HTTP | `true` |
|
|
||||||
| `useSSL` | | `false`, the communications between HedgeDoc and the proxy are unencrypted | `false` |
|
|
||||||
| `urlAddPort` | `CMD_URL_ADDPORT` | `false`, HedgeDoc should not append its port to the URLs it links | `false` |
|
|
||||||
| `hsts.enable` | `CMD_HSTS_ENABLE` | `true` if you host over SSL, `false` otherwise | `true` |
|
|
||||||
|
|
||||||
## Reverse Proxy config
|
|
||||||
|
|
||||||
### Generic
|
|
||||||
|
|
||||||
The reverse proxy must allow websocket `Upgrade` requests at path `/sockets.io/`.
|
|
||||||
|
|
||||||
It must pass through the scheme used by the client (http or https).
|
|
||||||
|
|
||||||
### Nginx
|
|
||||||
|
|
||||||
Here is an example configuration for Nginx.
|
|
||||||
|
|
||||||
```
|
|
||||||
map $http_upgrade $connection_upgrade {
|
|
||||||
default upgrade;
|
|
||||||
'' close;
|
|
||||||
}
|
|
||||||
server {
|
|
||||||
server_name hedgedoc.example.com;
|
|
||||||
|
|
||||||
location / {
|
|
||||||
proxy_pass http://127.0.0.1:3000;
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
|
||||||
}
|
|
||||||
|
|
||||||
location /socket.io/ {
|
|
||||||
proxy_pass http://127.0.0.1:3000;
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
|
||||||
proxy_set_header Connection $connection_upgrade;
|
|
||||||
}
|
|
||||||
|
|
||||||
listen [::]:443 ssl http2;
|
|
||||||
listen 443 ssl http2;
|
|
||||||
ssl_certificate fullchain.pem;
|
|
||||||
ssl_certificate_key privkey.pem;
|
|
||||||
include options-ssl-nginx.conf;
|
|
||||||
ssl_dhparam ssl-dhparams.pem;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Apache
|
|
||||||
|
|
||||||
You will need these modules enabled: `proxy`, `proxy_http` and `proxy_wstunnel`.
|
|
||||||
Here is an example config snippet:
|
|
||||||
|
|
||||||
```
|
|
||||||
<VirtualHost *:443>
|
|
||||||
ServerName hedgedoc.example.com
|
|
||||||
|
|
||||||
RewriteEngine on
|
|
||||||
RewriteCond %{REQUEST_URI} ^/socket.io [NC]
|
|
||||||
RewriteCond %{HTTP:Upgrade} =websocket [NC]
|
|
||||||
RewriteRule /(.*) ws://127.0.0.1:3000/$1 [P,L]
|
|
||||||
|
|
||||||
ProxyPass / http://127.0.0.1:3000/
|
|
||||||
ProxyPassReverse / http://127.0.0.1:3000/
|
|
||||||
|
|
||||||
RequestHeader set "X-Forwarded-Proto" expr=%{REQUEST_SCHEME}
|
|
||||||
|
|
||||||
ErrorLog ${APACHE_LOG_DIR}/error.log
|
|
||||||
CustomLog ${APACHE_LOG_DIR}/access.log combined
|
|
||||||
|
|
||||||
SSLCertificateFile /etc/letsencrypt/live/hedgedoc.example.com/fullchain.pem
|
|
||||||
SSLCertificateKeyFile /etc/letsencrypt/live/hedgedoc.example.com/privkey.pem
|
|
||||||
Include /etc/letsencrypt/options-ssl-apache.conf
|
|
||||||
</VirtualHost>
|
|
||||||
```
|
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
YunoHost
|
|
||||||
===
|
|
||||||
|
|
||||||
HedgeDoc is available as a 1-click install on [YunoHost](https://yunohost.org/). YunoHost is a Debian GNU/Linux based
|
|
||||||
distribution packaged with free software that automates the installation of a personal web server.
|
|
||||||
|
|
||||||
[![Install HedgeDoc with YunoHost](https://install-app.yunohost.org/install-with-yunohost.svg)](https://install-app.yunohost.org/?app=hedgedoc)
|
|
||||||
|
|
||||||
The source code for the package can be found [here](https://github.com/YunoHost-Apps/hedgedoc_ynh).
|
|
|
@ -1,161 +0,0 @@
|
||||||
Slide Separators
|
|
||||||
===
|
|
||||||
|
|
||||||
If you're getting started with reveal.js slides, there are a few things you need to know.
|
|
||||||
|
|
||||||
There are two types of slides, those that transition horizontally and those that transition vertically (subslides).
|
|
||||||
|
|
||||||
The following separators are used for each in the CodiMD syntax:
|
|
||||||
```
|
|
||||||
# First Slide
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Next slide
|
|
||||||
|
|
||||||
----
|
|
||||||
|
|
||||||
## Subslide
|
|
||||||
```
|
|
||||||
as you can see, horizontal transitions are separated by `---` and vertical transitions by `----`
|
|
||||||
|
|
||||||
## Basic YAML header
|
|
||||||
It's possible to customise the slide options using the YAML header in the slide markdown.
|
|
||||||
|
|
||||||
eg:
|
|
||||||
```
|
|
||||||
---
|
|
||||||
title: Example Slide
|
|
||||||
tags: presentation
|
|
||||||
slideOptions:
|
|
||||||
theme: solarized
|
|
||||||
transition: 'fade'
|
|
||||||
# parallaxBackgroundImage: 'https://s3.amazonaws.com/hakim-static/reveal-js/reveal-parallax-1.jpg'
|
|
||||||
---
|
|
||||||
```
|
|
||||||
make sure to have two spaces only at the start of the listed slide options.
|
|
||||||
|
|
||||||
you can comment out options with a `#`
|
|
||||||
|
|
||||||
### Some other options
|
|
||||||
```
|
|
||||||
# Display controls in the bottom right corner
|
|
||||||
controls: true
|
|
||||||
|
|
||||||
# Display a presentation progress bar
|
|
||||||
progress: true
|
|
||||||
|
|
||||||
# Set default timing of 2 minutes per slide
|
|
||||||
defaultTiming: 120
|
|
||||||
|
|
||||||
# Display the page number of the current slide
|
|
||||||
slideNumber: false
|
|
||||||
|
|
||||||
# Push each slide change to the browser history
|
|
||||||
history: false
|
|
||||||
|
|
||||||
# Enable keyboard shortcuts for navigation
|
|
||||||
keyboard: true
|
|
||||||
|
|
||||||
# Enable the slide overview mode
|
|
||||||
overview: true
|
|
||||||
|
|
||||||
# Vertical centering of slides
|
|
||||||
center: true
|
|
||||||
|
|
||||||
# Enables touch navigation on devices with touch input
|
|
||||||
touch: true
|
|
||||||
|
|
||||||
# Loop the presentation
|
|
||||||
loop: false
|
|
||||||
|
|
||||||
# Change the presentation direction to be RTL
|
|
||||||
rtl: false
|
|
||||||
|
|
||||||
# Randomizes the order of slides each time the presentation loads
|
|
||||||
shuffle: false
|
|
||||||
|
|
||||||
# Turns fragments on and off globally
|
|
||||||
fragments: true
|
|
||||||
|
|
||||||
# Flags if the presentation is running in an embedded mode,
|
|
||||||
# i.e. contained within a limited portion of the screen
|
|
||||||
embedded: false
|
|
||||||
|
|
||||||
# Flags if we should show a help overlay when the questionmark
|
|
||||||
# key is pressed
|
|
||||||
help: true
|
|
||||||
|
|
||||||
# Flags if speaker notes should be visible to all viewers
|
|
||||||
showNotes: false
|
|
||||||
|
|
||||||
# Global override for autolaying embedded media (video/audio/iframe)
|
|
||||||
# - null: Media will only autoplay if data-autoplay is present
|
|
||||||
# - true: All media will autoplay, regardless of individual setting
|
|
||||||
# - false: No media will autoplay, regardless of individual setting
|
|
||||||
autoPlayMedia: null
|
|
||||||
|
|
||||||
# Number of milliseconds between automatically proceeding to the
|
|
||||||
# next slide, disabled when set to 0, this value can be overwritten
|
|
||||||
# by using a data-autoslide attribute on your slides
|
|
||||||
autoSlide: 0
|
|
||||||
|
|
||||||
# Stop auto-sliding after user input
|
|
||||||
autoSlideStoppable: true
|
|
||||||
|
|
||||||
# Use this method for navigation when auto-sliding
|
|
||||||
autoSlideMethod: Reveal.navigateNext
|
|
||||||
|
|
||||||
# Enable slide navigation via mouse wheel
|
|
||||||
mouseWheel: false
|
|
||||||
|
|
||||||
# Hides the address bar on mobile devices
|
|
||||||
hideAddressBar: true
|
|
||||||
|
|
||||||
# Opens links in an iframe preview overlay
|
|
||||||
previewLinks: false
|
|
||||||
|
|
||||||
# Transition style
|
|
||||||
transition: 'slide'
|
|
||||||
# none/fade/slide/convex/concave/zoom
|
|
||||||
|
|
||||||
# Transition speed
|
|
||||||
transitionSpeed: 'default'
|
|
||||||
# default/fast/slow
|
|
||||||
|
|
||||||
# Transition style for full page slide backgrounds
|
|
||||||
backgroundTransition: 'fade'
|
|
||||||
# none/fade/slide/convex/concave/zoom
|
|
||||||
|
|
||||||
# Number of slides away from the current that are visible
|
|
||||||
viewDistance: 3
|
|
||||||
|
|
||||||
# Parallax background image
|
|
||||||
parallaxBackgroundImage: ''
|
|
||||||
# e.g. "'https://s3.amazonaws.com/hakim-static/reveal-js/reveal-parallax-1.jpg'"
|
|
||||||
|
|
||||||
# Parallax background size
|
|
||||||
parallaxBackgroundSize: ''
|
|
||||||
# CSS syntax, e.g. "2100px 900px"
|
|
||||||
|
|
||||||
# Number of pixels to move the parallax background per slide
|
|
||||||
# - Calculated automatically unless specified
|
|
||||||
# - Set to 0 to disable movement along an axis
|
|
||||||
parallaxBackgroundHorizontal: null
|
|
||||||
parallaxBackgroundVertical: null
|
|
||||||
|
|
||||||
# The display mode that will be used to show slides
|
|
||||||
display: 'block'
|
|
||||||
```
|
|
||||||
|
|
||||||
## Customising individual slides
|
|
||||||
|
|
||||||
custom background image:
|
|
||||||
```
|
|
||||||
---
|
|
||||||
|
|
||||||
<!-- .slide: data-background="https://s3.amazonaws.com/hakim-static/reveal-js/reveal-parallax-1.jpg" -->
|
|
||||||
#### testslide
|
|
||||||
|
|
||||||
---
|
|
||||||
```
|
|
|
@ -1,39 +0,0 @@
|
||||||
# URL scheme
|
|
||||||
|
|
||||||
HedgeDoc has three different modes for viewing a stored note. Each mode has a slightly different URL for accessing it.
|
|
||||||
This document gives an overview about these URLs.
|
|
||||||
We assume that you replace `pad.example.com` with the domain of your instance.
|
|
||||||
|
|
||||||
## Default (random)
|
|
||||||
|
|
||||||
When you create a new note by clicking the "New note" button, your note is given a long random id and a random short-id.
|
|
||||||
The long id is needed for accessing the editor and the live-update view. The short-id is used for the "published"
|
|
||||||
version of a note that is read-only and does not update in realtime as well as for the presentation mode.
|
|
||||||
|
|
||||||
| example URL | prefix | mode | content updates |
|
|
||||||
| -------------------------------------- | ------ | ----------------- | --------------- |
|
|
||||||
| pad.example.com/Ndmv3oCyREKZMjSGR9uhnQ | *none* | editor | in realtime |
|
|
||||||
| pad.example.com/s/ByXF7k-YI | s/ | read-only version | on reload |
|
|
||||||
| pad.example.com/p/ByXF7k-YI | p/ | presentation mode | on reload |
|
|
||||||
|
|
||||||
## FreeURL mode
|
|
||||||
|
|
||||||
If the setting `CMD_ALLOW_FREEURL` is enabled, users may create notes with a custom alias URL by just visiting the
|
|
||||||
editor version of a custom alias. The published version and the presentation mode may also be accessed with the custom
|
|
||||||
alias.
|
|
||||||
|
|
||||||
| example URL | prefix | mode | content updates |
|
|
||||||
| --------------------------------- | ------ | ----------------- | --------------- |
|
|
||||||
| pad.example.com/my-awesome-note | *none* | editor | in realtime |
|
|
||||||
| pad.example.com/s/my-awesome-note | s/ | read-only version | on reload |
|
|
||||||
| pad.example.com/p/my-awesome-note | p/ | presentation mode | on reload |
|
|
||||||
|
|
||||||
## Different editor modes
|
|
||||||
|
|
||||||
The editor has three different sub-modes. All of these update the content in realtime.
|
|
||||||
|
|
||||||
| example URL | icon in the navbar | behaviour |
|
|
||||||
| ------------------------------- | -------------------| ----------------------------------------------- |
|
|
||||||
| pad.example.com/longnoteid?edit | pencil | Full-screen markdown editor for the content |
|
|
||||||
| pad.example.com/longnoteid?view | eye | Full-screen view of the note without the editor |
|
|
||||||
| pad.example.com/longnoteid?both | columns | markdown editor and view mode side-by-side |
|
|
|
@ -1,3 +0,0 @@
|
||||||
SPDX-FileCopyrightText: 2004, 2006 The Linux Foundation and its contributors.
|
|
||||||
|
|
||||||
SPDX-License-Identifier: LicenseRef-DCO
|
|
|
@ -7,43 +7,15 @@ docs_dir: content
|
||||||
edit_uri: https://github.com/hedgedoc/hedgedoc/edit/master/docs/content/
|
edit_uri: https://github.com/hedgedoc/hedgedoc/edit/master/docs/content/
|
||||||
nav:
|
nav:
|
||||||
- Home: index.md
|
- Home: index.md
|
||||||
- Installation:
|
|
||||||
- 'Manual Installation': setup/manual-setup.md
|
|
||||||
- 'Reverse Proxy': setup/reverse-proxy.md
|
|
||||||
- Docker: setup/docker.md
|
|
||||||
- Cloudron: setup/cloudron.md
|
|
||||||
- Heroku: setup/heroku.md
|
|
||||||
- LinuxServer: setup/docker-linuxserver.md
|
|
||||||
- Yunohost: setup/yunohost.md
|
|
||||||
- Guides:
|
|
||||||
- Authentication:
|
|
||||||
- LDAP: guides/auth/ldap-ad.md
|
|
||||||
- OAuth: guides/auth/oauth.md
|
|
||||||
- SAML: guides/auth/saml.md
|
|
||||||
- SAML Keycloak: guides/auth/saml-keycloak.md
|
|
||||||
- SAML Onelogin: guides/auth/saml-onelogin.md
|
|
||||||
- GitHub: guides/auth/github.md
|
|
||||||
- GitLab: guides/auth/gitlab-self-hosted.md
|
|
||||||
- Keycloak: guides/auth/keycloak.md
|
|
||||||
- NextCloud: guides/auth/nextcloud.md
|
|
||||||
- Twitter: guides/auth/twitter.md
|
|
||||||
- Migrate from Etherpad: guides/migrate-etherpad.md
|
|
||||||
- Breaking Changes: guides/migrations-and-breaking-changes.md
|
|
||||||
- Media Backend:
|
|
||||||
- Minion: guides/minio-image-upload.md
|
|
||||||
- S3: guides/s3-image-upload.md
|
|
||||||
- Setting Terms: guides/providing-terms.md
|
|
||||||
- Configuration: configuration.md
|
|
||||||
- Developer:
|
- Developer:
|
||||||
- 'Getting Started': dev/getting-started.md
|
- '2.0 Development': dev/2.0.md
|
||||||
- API: dev/api.md
|
|
||||||
- 'Operational Transformation': dev/ot.md
|
|
||||||
- Webpack: dev/webpack.md
|
|
||||||
- 'Documentation': dev/documentation.md
|
- 'Documentation': dev/documentation.md
|
||||||
- FAQ: https://hedgedoc.org/faq
|
- FAQ: https://hedgedoc.org/faq
|
||||||
markdown_extensions:
|
markdown_extensions:
|
||||||
- toc:
|
- toc:
|
||||||
permalink: true
|
permalink: true
|
||||||
|
- admonition
|
||||||
|
- attr_list
|
||||||
theme:
|
theme:
|
||||||
name: 'material'
|
name: 'material'
|
||||||
language: en
|
language: en
|
||||||
|
|