doc: remove HMD related and remove docs
All docs migrate to online documentation now and store in `codimd-docs` Signed-off-by: BoHong Li <raccoon@hackmd.io>
64
app.json
|
@ -15,132 +15,132 @@
|
|||
"description": "Let npm also install development build tool",
|
||||
"value": "false"
|
||||
},
|
||||
"HMD_SESSION_SECRET": {
|
||||
"CMD_SESSION_SECRET": {
|
||||
"description": "Secret used to secure session cookies.",
|
||||
"required": false
|
||||
},
|
||||
"HMD_HSTS_ENABLE": {
|
||||
"CMD_HSTS_ENABLE": {
|
||||
"description": "whether to also use HSTS if HTTPS is enabled",
|
||||
"required": false
|
||||
},
|
||||
"HMD_HSTS_MAX_AGE": {
|
||||
"CMD_HSTS_MAX_AGE": {
|
||||
"description": "max duration, in seconds, to tell clients to keep HSTS status",
|
||||
"required": false
|
||||
},
|
||||
"HMD_HSTS_INCLUDE_SUBDOMAINS": {
|
||||
"CMD_HSTS_INCLUDE_SUBDOMAINS": {
|
||||
"description": "whether to tell clients to also regard subdomains as HSTS hosts",
|
||||
"required": false
|
||||
},
|
||||
"HMD_HSTS_PRELOAD": {
|
||||
"CMD_HSTS_PRELOAD": {
|
||||
"description": "whether to allow at all adding of the site to HSTS preloads (e.g. in browsers)",
|
||||
"required": false
|
||||
},
|
||||
"HMD_DOMAIN": {
|
||||
"CMD_DOMAIN": {
|
||||
"description": "domain name",
|
||||
"required": false
|
||||
},
|
||||
"HMD_URL_PATH": {
|
||||
"CMD_URL_PATH": {
|
||||
"description": "sub url path, like `www.example.com/<URL_PATH>`",
|
||||
"required": false
|
||||
},
|
||||
"HMD_ALLOW_ORIGIN": {
|
||||
"CMD_ALLOW_ORIGIN": {
|
||||
"description": "domain name whitelist (use comma to separate)",
|
||||
"required": false,
|
||||
"value": "localhost"
|
||||
},
|
||||
"HMD_PROTOCOL_USESSL": {
|
||||
"CMD_PROTOCOL_USESSL": {
|
||||
"description": "set to use ssl protocol for resources path (only applied when domain is set)",
|
||||
"required": false
|
||||
},
|
||||
"HMD_URL_ADDPORT": {
|
||||
"CMD_URL_ADDPORT": {
|
||||
"description": "set to add port on callback url (port 80 or 443 won't applied) (only applied when domain is set)",
|
||||
"required": false
|
||||
},
|
||||
"HMD_FACEBOOK_CLIENTID": {
|
||||
"CMD_FACEBOOK_CLIENTID": {
|
||||
"description": "Facebook API client id",
|
||||
"required": false
|
||||
},
|
||||
"HMD_FACEBOOK_CLIENTSECRET": {
|
||||
"CMD_FACEBOOK_CLIENTSECRET": {
|
||||
"description": "Facebook API client secret",
|
||||
"required": false
|
||||
},
|
||||
"HMD_TWITTER_CONSUMERKEY": {
|
||||
"CMD_TWITTER_CONSUMERKEY": {
|
||||
"description": "Twitter API consumer key",
|
||||
"required": false
|
||||
},
|
||||
"HMD_TWITTER_CONSUMERSECRET": {
|
||||
"CMD_TWITTER_CONSUMERSECRET": {
|
||||
"description": "Twitter API consumer secret",
|
||||
"required": false
|
||||
},
|
||||
"HMD_GITHUB_CLIENTID": {
|
||||
"CMD_GITHUB_CLIENTID": {
|
||||
"description": "GitHub API client id",
|
||||
"required": false
|
||||
},
|
||||
"HMD_GITHUB_CLIENTSECRET": {
|
||||
"CMD_GITHUB_CLIENTSECRET": {
|
||||
"description": "GitHub API client secret",
|
||||
"required": false
|
||||
},
|
||||
"HMD_BITBUCKET_CLIENTID": {
|
||||
"CMD_BITBUCKET_CLIENTID": {
|
||||
"description": "Bitbucket API client id",
|
||||
"required": false
|
||||
},
|
||||
"HMD_BITBUCKET_CLIENTSECRET": {
|
||||
"CMD_BITBUCKET_CLIENTSECRET": {
|
||||
"description": "Bitbucket API client secret",
|
||||
"required": false
|
||||
},
|
||||
"HMD_GITLAB_BASEURL": {
|
||||
"CMD_GITLAB_BASEURL": {
|
||||
"description": "GitLab authentication endpoint, set to use other endpoint than GitLab.com (optional)",
|
||||
"required": false
|
||||
},
|
||||
"HMD_GITLAB_CLIENTID": {
|
||||
"CMD_GITLAB_CLIENTID": {
|
||||
"description": "GitLab API client id",
|
||||
"required": false
|
||||
},
|
||||
"HMD_GITLAB_CLIENTSECRET": {
|
||||
"CMD_GITLAB_CLIENTSECRET": {
|
||||
"description": "GitLab API client secret",
|
||||
"required": false
|
||||
},
|
||||
"HMD_GITLAB_SCOPE": {
|
||||
"CMD_GITLAB_SCOPE": {
|
||||
"description": "GitLab API client scope (optional)",
|
||||
"required": false
|
||||
},
|
||||
"HMD_MATTERMOST_BASEURL": {
|
||||
"CMD_MATTERMOST_BASEURL": {
|
||||
"description": "Mattermost authentication endpoint",
|
||||
"required": false
|
||||
},
|
||||
"HMD_MATTERMOST_CLIENTID": {
|
||||
"CMD_MATTERMOST_CLIENTID": {
|
||||
"description": "Mattermost API client id",
|
||||
"required": false
|
||||
},
|
||||
"HMD_MATTERMOST_CLIENTSECRET": {
|
||||
"CMD_MATTERMOST_CLIENTSECRET": {
|
||||
"description": "Mattermost API client secret",
|
||||
"required": false
|
||||
},
|
||||
"HMD_DROPBOX_CLIENTID": {
|
||||
"CMD_DROPBOX_CLIENTID": {
|
||||
"description": "Dropbox API client id",
|
||||
"required": false
|
||||
},
|
||||
"HMD_DROPBOX_CLIENTSECRET": {
|
||||
"CMD_DROPBOX_CLIENTSECRET": {
|
||||
"description": "Dropbox API client secret",
|
||||
"required": false
|
||||
},
|
||||
"HMD_DROPBOX_APP_KEY": {
|
||||
"CMD_DROPBOX_APP_KEY": {
|
||||
"description": "Dropbox app key (for import/export)",
|
||||
"required": false
|
||||
},
|
||||
"HMD_GOOGLE_CLIENTID": {
|
||||
"CMD_GOOGLE_CLIENTID": {
|
||||
"description": "Google API client id",
|
||||
"required": false
|
||||
},
|
||||
"HMD_GOOGLE_CLIENTSECRET": {
|
||||
"CMD_GOOGLE_CLIENTSECRET": {
|
||||
"description": "Google API client secret",
|
||||
"required": false
|
||||
},
|
||||
"HMD_IMGUR_CLIENTID": {
|
||||
"CMD_IMGUR_CLIENTID": {
|
||||
"description": "Imgur API client id",
|
||||
"required": false
|
||||
},
|
||||
"HMD_ALLOW_PDF_EXPORT": {
|
||||
"CMD_ALLOW_PDF_EXPORT": {
|
||||
"description": "Enable or disable PDF exports",
|
||||
"required": false
|
||||
}
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
# Webpack Docs
|
||||
## `webpack.common.js`
|
||||
This file contains all common definition for chunks and plugins, that are needed by the whole app.
|
||||
|
||||
**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,38 +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-hackmd-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:
|
||||
````javascript
|
||||
{
|
||||
"production": {
|
||||
"github": {
|
||||
"clientID": "3747d30eaccXXXXXXXXX",
|
||||
"clientSecret": "2a8e682948eee0c580XXXXXXXXXXXXXXXXXXXXXX"
|
||||
}
|
||||
}
|
||||
}
|
||||
````
|
||||
* environment variables:
|
||||
````
|
||||
HMD_GITHUB_CLIENTID=3747d30eaccXXXXXXXXX
|
||||
HMD_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:`
|
||||
|
||||
```
|
||||
- HMD_DOMAIN=your.hackmd.domain
|
||||
- HMD_URL_ADDPORT=443
|
||||
- HMD_PROTOCOL_USESSL=true
|
||||
- HMD_GITLAB_BASEURL=https://your.gitlab.domain
|
||||
- HMD_GITLAB_CLIENTID=23462a34example99XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
- HMD_GITLAB_CLIENTSECRET=5532e9dexamplXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
```
|
||||
|
||||
7. Run `docker-compose up -d` to apply your settings.
|
||||
8. Sign in to your HackMD using your GitLab ID:
|
||||
|
||||
![Sign in via GitLab](../images/auth/gitlab-sign-in.png)
|
|
@ -1,42 +0,0 @@
|
|||
AD LDAP auth
|
||||
===
|
||||
|
||||
|
||||
To setup your CodiMD instance with Active Directory you need the following configs:
|
||||
|
||||
```
|
||||
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,58 +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:
|
||||
````
|
||||
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,52 +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).
|
||||
|
||||
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,54 +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 hackmd, which is issuer. (last slash is not needed)
|
||||
* ACS (Consumer) URL Validator: The callback URL of your hackmd. (serverurl + /auth/saml/callback)
|
||||
* ACS (Consumer) URL: same as above.
|
||||
* Login URL: login URL(SAML requester) of your hackmd. (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 hackmd 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
|
||||
````
|
||||
HMD_SAML_IDPSSOURL=https://*******.onelogin.com/trust/saml2/http-post/sso/******
|
||||
HMD_SAML_IDPCERT=/path/to/idp_cert.pem
|
||||
````
|
||||
10. Try sign-in with SAML from your hackmd 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 HackMD 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": "myhackmd"
|
||||
"identifierFormat": "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"
|
||||
}
|
||||
}
|
||||
}
|
||||
````
|
||||
* environment variables
|
||||
````
|
||||
HMD_SAML_ISSUER=myhackmd
|
||||
HMD_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 HackMD
|
||||
* `attribute.username`: Attribute name of displaying user name on HackMD
|
||||
* `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
|
||||
````
|
||||
HMD_SAML_ATTRIBUTE_ID=sAMAccountName
|
||||
HMD_SAML_ATTRIBUTE_USERNAME=nickName
|
||||
HMD_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 HackMD. Use vertical bar to separate for environment variables.
|
||||
* `externalGroups`: Group names array for not allowed access to HackMD. Use vertical bar to separate for environment variables.
|
||||
* _Note: Evaluates `externalGroups` first_
|
||||
* config.json:
|
||||
````javascript
|
||||
{
|
||||
"production": {
|
||||
"saml": {
|
||||
/* omitted */
|
||||
"groupAttribute": "memberOf",
|
||||
"requiredGroups": [ "hackmd-users", "board-members" ],
|
||||
"externalGroups": [ "temporary-staff" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
````
|
||||
* environment variables
|
||||
````
|
||||
HMD_SAML_GROUPATTRIBUTE=memberOf
|
||||
HMD_SAML_REQUIREDGROUPS=hackmd-users|board-members
|
||||
HMD_SAML_EXTERNALGROUPS=temporary-staff
|
||||
````
|
|
@ -1,44 +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:
|
||||
````
|
||||
HMD_TWITTER_CONSUMERKEY=esTCJFXXXXXXXXXXXXXXXXXXX
|
||||
HMD_TWITTER_CONSUMERSECRET=zpCs4tU86pRVXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
````
|
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: 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,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/hackmdio/codimd/tree/1.2.1
|
||||
|
||||
## 0. Requirements
|
||||
|
||||
- `curl`
|
||||
- running Etherpad server
|
||||
- running CodiMD server
|
||||
- [codimd-cli]
|
||||
|
||||
[codimd-cli]: https://github.com/hackmdio/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/hackmdio/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,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:
|
||||
```console
|
||||
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:
|
||||
|
||||
```
|
||||
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 HackMD
|
||||
|
||||
![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 HackMD'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": "hackmd"
|
||||
```
|
||||
|
||||
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": "hackmd",
|
||||
"imageuploadtype": "minio"
|
||||
}
|
||||
```
|
|
@ -1,17 +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.
|
|
@ -1,83 +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 variable](https://github.com/hackmdio/hackmd#environment-variables-will-overwrite-other-server-configs).
|
||||
|
||||
## Related Tools
|
||||
|
||||
* [AWS Policy Generator](http://awspolicygen.s3.amazonaws.com/policygen.html)
|
|
@ -156,7 +156,7 @@ for (let i = keys.length; i--;) {
|
|||
|
||||
// Notify users about the prefix change and inform them they use legacy prefix for environment variables
|
||||
if (Object.keys(process.env).toString().indexOf('HMD_') !== -1) {
|
||||
logger.warn('Using legacy HMD prefix for environment variables. Please change your variables in future. For details see: https://github.com/hackmdio/codimd#environment-variables-will-overwrite-other-server-configs')
|
||||
logger.warn('Using legacy HMD prefix for environment variables. Please change your variables in future. For details see: https://hackmd.io/c/codimd-documentation/%2F%40codimd%2Fmigrate-2-0#1-Drop-old-environment-variables-support')
|
||||
}
|
||||
|
||||
// Generate session secret if it stays on default values
|
||||
|
|