Merge remote-tracking branch 'upstream/master' into DepauMD
|
@ -17,3 +17,9 @@ trim_trailing_whitespace = false
|
|||
[{.travis.yml,npm-shrinkwrap.json,package.json}]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[locales/*.json]
|
||||
# this is the exact style poeditor.com exports, so this should prevent churn.
|
||||
insert_final_newline = false
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
|
|
1
.gitignore
vendored
|
@ -8,7 +8,6 @@ composer.lock
|
|||
.idea/
|
||||
Thumbs.db
|
||||
npm-debug.log
|
||||
hackmd_io
|
||||
newrelic_agent.log
|
||||
logs/
|
||||
tmp/
|
||||
|
|
|
@ -30,13 +30,6 @@ jobs:
|
|||
script:
|
||||
- shellcheck bin/heroku bin/setup
|
||||
language: generic
|
||||
- env: task=doctoc
|
||||
install: npm install doctoc
|
||||
script:
|
||||
- cp README.md README.md.orig
|
||||
- npm run doctoc
|
||||
- diff -q README.md README.md.orig
|
||||
language: generic
|
||||
- env: task=json-lint
|
||||
addons:
|
||||
apt:
|
||||
|
|
7
CHANGELOG.md
Normal file
|
@ -0,0 +1,7 @@
|
|||
# CHANGELOG
|
||||
|
||||
Please refer to the release notes published under
|
||||
[`public/docs/release-notes.md`](public/docs/release-notes.md).
|
||||
|
||||
These are also available on each CodiMD instance under
|
||||
https://[domain-name]/release-notes
|
37
CODE_OF_CONDUCT.md
Normal file
|
@ -0,0 +1,37 @@
|
|||
Contributor Code of Conduct
|
||||
===
|
||||
|
||||
As contributors and maintainers of this project, and in the interest of fostering an open and
|
||||
welcoming community, we pledge to respect all people who contribute through reporting issues,
|
||||
posting feature requests, updating documentation, submitting pull requests or patches, and other
|
||||
activities.
|
||||
|
||||
We are committed to making participation in this project a harassment-free experience for everyone,
|
||||
regardless of level of experience, gender, gender identity and expression, sexual orientation,
|
||||
disability, personal appearance, body size, race, ethnicity, age, religion, or nationality.
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery
|
||||
* Personal attacks
|
||||
* Trolling or insulting/derogatory comments
|
||||
* Public or private harassment
|
||||
* Publishing other's private information, such as physical or electronic addresses, without explicit
|
||||
permission
|
||||
* Other unethical or unprofessional conduct.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits,
|
||||
code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. By
|
||||
adopting this Code of Conduct, project maintainers commit themselves to fairly and consistently
|
||||
applying these principles to every aspect of managing this project. Project maintainers who do not
|
||||
follow or enforce the Code of Conduct may be permanently removed from the project team.
|
||||
|
||||
This code of conduct applies both within project spaces and in public spaces when an individual is
|
||||
representing the project or its community.
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an
|
||||
issue or contacting one or more of the project maintainers.
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org),
|
||||
version 1.2.0, available at
|
||||
[http://contributor-covenant.org/version/1/2/0/](http://contributor-covenant.org/version/1/2/0/)
|
|
@ -3,7 +3,8 @@
|
|||
When contributing to this repository, please first discuss the change you wish to make via issue,
|
||||
email, or any other method with the owners of this repository before making a change.
|
||||
|
||||
Please note we have a code of conduct, please follow it in all your interactions with the project.
|
||||
Please note we have a [code of conduct](CODE_OF_CONDUCT.md), please follow it in all your
|
||||
interactions with the project.
|
||||
|
||||
## Pull Request Process
|
||||
1. Ensure you signed all your commits with Developer Certificate of Origin (DCO).
|
||||
|
@ -16,44 +17,7 @@ Please note we have a code of conduct, please follow it in all your interactions
|
|||
5. You may merge the Pull Request in once you have the sign-off of two other developers, or if you
|
||||
do not have permission to do that, you may request the second reviewer to merge it for you.
|
||||
|
||||
## Contributor Code of Conduct
|
||||
|
||||
As contributors and maintainers of this project, and in the interest of fostering an open and
|
||||
welcoming community, we pledge to respect all people who contribute through reporting issues,
|
||||
posting feature requests, updating documentation, submitting pull requests or patches, and other
|
||||
activities.
|
||||
|
||||
We are committed to making participation in this project a harassment-free experience for everyone,
|
||||
regardless of level of experience, gender, gender identity and expression, sexual orientation,
|
||||
disability, personal appearance, body size, race, ethnicity, age, religion, or nationality.
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery
|
||||
* Personal attacks
|
||||
* Trolling or insulting/derogatory comments
|
||||
* Public or private harassment
|
||||
* Publishing other's private information, such as physical or electronic addresses, without explicit
|
||||
permission
|
||||
* Other unethical or unprofessional conduct.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits,
|
||||
code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. By
|
||||
adopting this Code of Conduct, project maintainers commit themselves to fairly and consistently
|
||||
applying these principles to every aspect of managing this project. Project maintainers who do not
|
||||
follow or enforce the Code of Conduct may be permanently removed from the project team.
|
||||
|
||||
This code of conduct applies both within project spaces and in public spaces when an individual is
|
||||
representing the project or its community.
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an
|
||||
issue or contacting one or more of the project maintainers.
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org),
|
||||
version 1.2.0, available at
|
||||
[http://contributor-covenant.org/version/1/2/0/](http://contributor-covenant.org/version/1/2/0/)
|
||||
|
||||
### Sign your work
|
||||
## Sign your work
|
||||
|
||||
We use the Developer Certificate of Origin (DCO) as a additional safeguard
|
||||
for the CodiMD project. This is a well established and widely used
|
||||
|
|
11
LICENSE
|
@ -629,8 +629,15 @@ to attach them to the start of each source file to most effectively
|
|||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
CodiMD - Realtime collaborative markdown notes on all platforms.
|
||||
Copyright (C) 2019 Christoph (Sheogorath) Kern
|
||||
Copyright (C) 2019 Claudius Coenen
|
||||
Copyright (C) 2019 Max Wu
|
||||
Copyright (C) 2017 Yukai Huang
|
||||
And more can be found on https://github.com/codimd/server/graphs/contributors
|
||||
Or in the local AUTHORS file
|
||||
|
||||
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
|
|
399
README.md
|
@ -1,52 +1,70 @@
|
|||
CodiMD
|
||||
===
|
||||
|
||||
[![CodiMD on Gitter][gitter-image]][gitter-url]
|
||||
[![#CodiMD on matrix.org][matrix.org-image]][matrix.org-url]
|
||||
[![build status][travis-image]][travis-url]
|
||||
[![version][github-version-badge]][github-release-page]
|
||||
[![POEditor][poeditor-image]][poeditor-url]
|
||||
|
||||
CodiMD lets you create real-time collaborative markdown notes on all platforms.
|
||||
Inspired by Hackpad, with more focus on speed and flexibility, and build from [HackMD](https://hackmd.io) source code.
|
||||
Feel free to contribute.
|
||||
CodiMD lets you create real-time collaborative markdown notes. You can test-drive
|
||||
it by visiting our [CodiMD demo server][codimd-demo].
|
||||
|
||||
Thanks for using! :smile:
|
||||
It is inspired by Hackpad, Etherpad and similar collaborative editors. This
|
||||
project originated with the team at [HackMD](https://hackmd.io) and now forked
|
||||
into its own organisation. [A longer writeup can be read in the history doc](docs/history.md).
|
||||
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
# Table of Contents
|
||||
[![CodiMD 1.3.2 with its feature demonstration page open](docs/images/CodiMD-1.3.2-features.png)][codimd-demo-features]
|
||||
|
||||
- [HackMD CE became CodiMD](#hackmd-ce-became-codimd)
|
||||
- [Browsers Requirement](#browsers-requirement)
|
||||
- [Installation](#installation)
|
||||
- [Getting started (Native install)](#getting-started-native-install)
|
||||
- [Prerequisite](#prerequisite)
|
||||
- [Instructions](#instructions)
|
||||
- [Heroku Deployment](#heroku-deployment)
|
||||
- [Kubernetes](#kubernetes)
|
||||
- [Upgrade](#upgrade)
|
||||
- [Native setup](#native-setup)
|
||||
- [Configuration](#configuration)
|
||||
- [Environment variables (will overwrite other server configs)](#environment-variables-will-overwrite-other-server-configs)
|
||||
- [Application settings `config.json`](#application-settings-configjson)
|
||||
- [Third-party integration API key settings](#third-party-integration-api-key-settings)
|
||||
- [Third-party integration OAuth callback URLs](#third-party-integration-oauth-callback-urls)
|
||||
- [Developer Notes](#developer-notes)
|
||||
- [Structure](#structure)
|
||||
- [Operational Transformation](#operational-transformation)
|
||||
- [License](#license)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
## Community and Contributions
|
||||
|
||||
# HackMD CE became CodiMD
|
||||
We welcome contributions! There's a lot to do: If you would like to report bugs,
|
||||
the [issue tracker][github-issue-tracker] is the right place. If you can help
|
||||
translating, find us on [POEditor][poeditor-url]. To get started developing,
|
||||
take a look at the [docs/dev](docs/dev) directory. In any case: come talk to us,
|
||||
we'll be delighted to help you with the first steps.
|
||||
|
||||
CodiMD was recently renamed from its former name was HackMD. CodiMD is the free software version of HackMD. HackMD EE, which is a SaaS (Software as a Service) product available at [hackmd.io](https://hackmd.io).
|
||||
To stay up to date with our work or get support it's recommended to join our
|
||||
[Matrix channel][matrix.org-url], stop by our [community forums][codimd-community]
|
||||
or subscribe to the [release feed][github-release-feed]. We also engage in
|
||||
regular [community calls][codimd-community-calls] ([RSS](https://community.codimd.org/t/codimd-community-call/19.rss)) which you are very welcome to join.
|
||||
|
||||
We decided to change the name to break the confusion between HackMD and CodiMD, formally known as HackMD CE, as it never was an open core project.
|
||||
|
||||
*For the whole renaming story, see the [related issue](https://github.com/hackmdio/hackmd/issues/720)*
|
||||
## Installation / Upgrading
|
||||
|
||||
# Browsers Requirement
|
||||
You can run CodiMD in a number of ways, and we created setup instructions for
|
||||
all of these:
|
||||
|
||||
* [Docker](docs/setup/docker.md)
|
||||
* [Kubernetes](docs/setup/kubernetes.md)
|
||||
* [Cloudron](docs/setup/cloudron.md)
|
||||
* [Heroku](docs/setup/heroku.md)
|
||||
* [manual setup](docs/setup/manual-setup.md)
|
||||
|
||||
If you do not wish to run your own setup, you can find a commercial offering at
|
||||
https://hackmd.io. This is not the same codebase as this one, but it is a very
|
||||
similar project.
|
||||
|
||||
|
||||
## Configuration
|
||||
|
||||
Theres two main ways to configure your CodiMD instance:
|
||||
[Config file](docs/configuration-config-file.md) or
|
||||
[environment variables](docs/configuration-env-vars.md). You can choose what
|
||||
works best for you.
|
||||
|
||||
CodiMD can integrate with
|
||||
|
||||
* facebook, twitter, github, gitlab, mattermost, dropbox, google, ldap, saml and [oauth2](docs/guides/auth/oauth.md) **for login**
|
||||
* imgur, s3, minio, azure **for image/attachment storage** (files can also be local!)
|
||||
* dropbox **for export and import**
|
||||
|
||||
More info about that can be found in the configuration docs above.
|
||||
|
||||
|
||||
## Browser support
|
||||
|
||||
To use CodiMD, your browser should match or exceed these versions:
|
||||
|
||||
- ![Chrome](http://browserbadge.com/chrome/47/18px) Chrome >= 47, Chrome for Android >= 47
|
||||
- ![Safari](http://browserbadge.com/safari/9/18px) Safari >= 9, iOS Safari >= 8.4
|
||||
|
@ -55,309 +73,28 @@ We decided to change the name to break the confusion between HackMD and CodiMD,
|
|||
- ![Opera](http://browserbadge.com/opera/34/18px) Opera >= 34, Opera Mini not supported
|
||||
- Android Browser >= 4.4
|
||||
|
||||
# Installation
|
||||
|
||||
## Getting started (Native install)
|
||||
|
||||
### Prerequisite
|
||||
|
||||
- Node.js 6.x or up (test up to 7.5.0) and <10.x
|
||||
- Database (PostgreSQL, MySQL, MariaDB, SQLite, MSSQL) use charset `utf8`
|
||||
- npm (and its dependencies, especially [uWebSockets](https://github.com/uWebSockets/uWebSockets#nodejs-developers), [node-gyp](https://github.com/nodejs/node-gyp#installation))
|
||||
- `libssl-dev` for building scrypt (see [here](https://github.com/ml1nk/node-scrypt/blob/master/README.md#installation-instructions) for further information)
|
||||
- For **building** CodiMD we recommend to use a machine with at least **2GB** RAM
|
||||
|
||||
### Instructions
|
||||
|
||||
1. Download a release and unzip or clone into a directory
|
||||
2. Enter the directory and type `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 configs, see more below
|
||||
4. Setup environment variables which will overwrite the configs
|
||||
5. Build front-end bundle by `npm run build` (use `npm run dev` if you are in development)
|
||||
6. 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`
|
||||
7. Run `node_modules/.bin/sequelize db:migrate`, this step will migrate your db to the latest schema
|
||||
8. Run the server as you like (node, forever, pm2)
|
||||
|
||||
To stay up to date with your installation it's recommended to subscribe the [release feed][github-release-feed].
|
||||
|
||||
## 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/hackmdio/codimd/tree/master)
|
||||
|
||||
If you deploy it without the button, keep in mind to use the right buildpacks. For details check `app.json`.
|
||||
|
||||
## 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).
|
||||
|
||||
**Debian-based version:**
|
||||
|
||||
[![latest](https://images.microbadger.com/badges/version/hackmdio/hackmd:latest.svg)](https://microbadger.com/images/hackmdio/hackmd "Get your own version badge on microbadger.com") [![](https://images.microbadger.com/badges/image/hackmdio/hackmd:latest.svg)](https://microbadger.com/images/hackmdio/hackmd "Get your own image badge on microbadger.com")
|
||||
|
||||
The easiest way to setup CodiMD using docker are using the following three commands:
|
||||
|
||||
```console
|
||||
git clone https://github.com/hackmdio/docker-hackmd.git
|
||||
cd docker-hackmd
|
||||
docker-compose up
|
||||
```
|
||||
Read more about it in the [container repository…](https://github.com/hackmdio/docker-hackmd)
|
||||
|
||||
# Upgrade
|
||||
|
||||
## Native setup
|
||||
|
||||
If you are upgrading CodiMD from an older version, follow these steps:
|
||||
|
||||
1. Fully stop your old server first (important)
|
||||
2. `git pull` or do whatever that updates the files
|
||||
3. `npm install` to update dependencies
|
||||
4. Build front-end bundle by `npm run build` (use `npm run dev` if you are in development)
|
||||
5. 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`
|
||||
6. Run `node_modules/.bin/sequelize db:migrate`, this step will migrate your db to the latest schema
|
||||
7. Start your whole new server!
|
||||
|
||||
To stay up to date with your installation it's recommended to subscribe the [release feed][github-release-feed].
|
||||
|
||||
* **migrate-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 in the future*
|
||||
|
||||
* [**migration-to-0.5.0**](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.
|
||||
|
||||
* [**migration-to-0.4.0**](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.
|
||||
|
||||
# Configuration
|
||||
|
||||
There are some config settings you need to change in the files below.
|
||||
|
||||
```
|
||||
./config.json ----application settings
|
||||
```
|
||||
|
||||
## Environment variables (will overwrite other server configs)
|
||||
|
||||
| variables | example values | description |
|
||||
| --------- | ------ | ----------- |
|
||||
| `NODE_ENV` | `production` or `development` | set current environment (will apply corresponding settings in the `config.json`) |
|
||||
| `DEBUG` | `true` or `false` | set debug mode; show more logs |
|
||||
| `CMD_CONFIG_FILE` | `/path/to/config.json` | optional override for the path to CodiMD's config file |
|
||||
| `CMD_DOMAIN` | `codimd.org` | domain name |
|
||||
| `CMD_URL_PATH` | `codimd` | sub URL path, like `www.example.com/<URL_PATH>` |
|
||||
| `CMD_HOST` | `localhost` | host to listen on |
|
||||
| `CMD_PORT` | `80` | web app port |
|
||||
| `CMD_PATH` | `/var/run/codimd.sock` | path to UNIX domain socket to listen on (if specified, `CMD_HOST` and `CMD_PORT` are ignored) |
|
||||
| `CMD_LOGLEVEL` | `info` | Defines what kind of logs are provided to stdout. |
|
||||
| `CMD_ALLOW_ORIGIN` | `localhost, codimd.org` | domain name whitelist (use comma to separate) |
|
||||
| `CMD_PROTOCOL_USESSL` | `true` or `false` | set to use SSL protocol for resources path (only applied when domain is set) |
|
||||
| `CMD_URL_ADDPORT` | `true` or `false` | set to add port on callback URL (ports `80` or `443` won't be applied) (only applied when domain is set) |
|
||||
| `CMD_USECDN` | `true` or `false` | set to use CDN resources or not (default is `true`) |
|
||||
| `CMD_ALLOW_ANONYMOUS` | `true` or `false` | set to allow anonymous usage (default is `true`) |
|
||||
| `CMD_ALLOW_ANONYMOUS_EDITS` | `true` or `false` | if `allowAnonymous` is `true`, allow users to select `freely` permission, allowing guests to edit existing notes (default is `false`) |
|
||||
| `CMD_ALLOW_FREEURL` | `true` or `false` | set to allow new note creation by accessing a nonexistent note URL |
|
||||
| `CMD_FORBIDDEN_NODE_IDS` | `'robots.txt'` | disallow creation of notes, even if `CMD_ALLOW_FREEURL` is `true` |
|
||||
| `CMD_DEFAULT_PERMISSION` | `freely`, `editable`, `limited`, `locked` or `private` | set notes default permission (only applied on signed users) |
|
||||
| `CMD_DB_URL` | `mysql://localhost:3306/database` | set the database URL |
|
||||
| `CMD_SESSION_SECRET` | no example | Secret used to sign the session cookie. If non is set, one will randomly generated on startup |
|
||||
| `CMD_SESSION_LIFE` | `1209600000` | Session life time. (milliseconds) |
|
||||
| `CMD_FACEBOOK_CLIENTID` | no example | Facebook API client id |
|
||||
| `CMD_FACEBOOK_CLIENTSECRET` | no example | Facebook API client secret |
|
||||
| `CMD_TWITTER_CONSUMERKEY` | no example | Twitter API consumer key |
|
||||
| `CMD_TWITTER_CONSUMERSECRET` | no example | Twitter API consumer secret |
|
||||
| `CMD_GITHUB_CLIENTID` | no example | GitHub API client id |
|
||||
| `CMD_GITHUB_CLIENTSECRET` | no example | GitHub API client secret |
|
||||
| `CMD_GITLAB_SCOPE` | `read_user` or `api` | GitLab API requested scope (default is `api`) (GitLab snippet import/export need `api` scope) |
|
||||
| `CMD_GITLAB_BASEURL` | no example | GitLab authentication endpoint, set to use other endpoint than GitLab.com (optional) |
|
||||
| `CMD_GITLAB_CLIENTID` | no example | GitLab API client id |
|
||||
| `CMD_GITLAB_CLIENTSECRET` | no example | GitLab API client secret |
|
||||
| `CMD_GITLAB_VERSION` | no example | GitLab API version (v3 or v4) |
|
||||
| `CMD_MATTERMOST_BASEURL` | no example | Mattermost authentication endpoint for versions below 5.0. For Mattermost version 5.0 and above, see [guide](docs/guides/auth/mattermost-self-hosted.md). |
|
||||
| `CMD_MATTERMOST_CLIENTID` | no example | Mattermost API client id |
|
||||
| `CMD_MATTERMOST_CLIENTSECRET` | no example | Mattermost API client secret |
|
||||
| `CMD_DROPBOX_CLIENTID` | no example | Dropbox API client id |
|
||||
| `CMD_DROPBOX_CLIENTSECRET` | no example | Dropbox API client secret |
|
||||
| `CMD_GOOGLE_CLIENTID` | no example | Google API client id |
|
||||
| `CMD_GOOGLE_CLIENTSECRET` | no example | Google API client secret |
|
||||
| `CMD_LDAP_URL` | `ldap://example.com` | URL of LDAP server |
|
||||
| `CMD_LDAP_BINDDN` | no example | bindDn for LDAP access |
|
||||
| `CMD_LDAP_BINDCREDENTIALS` | no example | bindCredentials for LDAP access |
|
||||
| `CMD_LDAP_SEARCHBASE` | `o=users,dc=example,dc=com` | LDAP directory to begin search from |
|
||||
| `CMD_LDAP_SEARCHFILTER` | `(uid={{username}})` | LDAP filter to search with |
|
||||
| `CMD_LDAP_SEARCHATTRIBUTES` | `displayName, mail` | LDAP attributes to search with (use comma to separate) |
|
||||
| `CMD_LDAP_USERIDFIELD` | `uidNumber` or `uid` or `sAMAccountName` | The LDAP field which is used uniquely identify a user on CodiMD |
|
||||
| `CMD_LDAP_USERNAMEFIELD` | Fallback to userid | The LDAP field which is used as the username on CodiMD |
|
||||
| `CMD_LDAP_TLS_CA` | `server-cert.pem, root.pem` | Root CA for LDAP TLS in PEM format (use comma to separate) |
|
||||
| `CMD_LDAP_PROVIDERNAME` | `My institution` | Optional name to be displayed at login form indicating the LDAP provider |
|
||||
| `CMD_SAML_IDPSSOURL` | `https://idp.example.com/sso` | authentication endpoint of IdP. for details, see [guide](docs/guides/auth/saml-onelogin.md). |
|
||||
| `CMD_SAML_IDPCERT` | `/path/to/cert.pem` | certificate file path of IdP in PEM format |
|
||||
| `CMD_SAML_ISSUER` | no example | identity of the service provider (optional, default: serverurl)" |
|
||||
| `CMD_SAML_IDENTIFIERFORMAT` | no example | name identifier format (optional, default: `urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress`) |
|
||||
| `CMD_SAML_GROUPATTRIBUTE` | `memberOf` | attribute name for group list (optional) |
|
||||
| `CMD_SAML_REQUIREDGROUPS` | `Hackmd-users` | group names that allowed (use vertical bar to separate) (optional) |
|
||||
| `CMD_SAML_EXTERNALGROUPS` | `Temporary-staff` | group names that not allowed (use vertical bar to separate) (optional) |
|
||||
| `CMD_SAML_ATTRIBUTE_ID` | `sAMAccountName` | attribute map for `id` (optional, default: NameID of SAML response) |
|
||||
| `CMD_SAML_ATTRIBUTE_USERNAME` | `mailNickname` | attribute map for `username` (optional, default: NameID of SAML response) |
|
||||
| `CMD_SAML_ATTRIBUTE_EMAIL` | `mail` | attribute map for `email` (optional, default: NameID of SAML response if `CMD_SAML_IDENTIFIERFORMAT` is default) |
|
||||
| `CMD_OAUTH2_USER_PROFILE_URL` | `https://example.com` | where retrieve information about a user after succesful login. Needs to output JSON. (no default value) Refer to the [Mattermost](docs/guides/auth/mattermost-self-hosted.md) or [Nextcloud](docs/guides/auth/nextcloud.md) examples for more details on all of the `CMD_OAUTH2...` options. |
|
||||
| `CMD_OAUTH2_USER_PROFILE_USERNAME_ATTR` | `name` | where to find the username in the JSON from the user profile URL. (no default value)|
|
||||
| `CMD_OAUTH2_USER_PROFILE_DISPLAY_NAME_ATTR` | `display-name` | where to find the display-name in the JSON from the user profile URL. (no default value) |
|
||||
| `CMD_OAUTH2_USER_PROFILE_EMAIL_ATTR` | `email` | where to find the email address in the JSON from the user profile URL. (no default value) |
|
||||
| `CMD_OAUTH2_TOKEN_URL` | `https://example.com` | sometimes called token endpoint, please refer to the documentation of your OAuth2 provider (no default value) |
|
||||
| `CMD_OAUTH2_AUTHORIZATION_URL` | `https://example.com` | authorization URL of your provider, please refer to the documentation of your OAuth2 provider (no default value) |
|
||||
| `CMD_OAUTH2_CLIENT_ID` | `afae02fckafd...` | you will get this from your OAuth2 provider when you register CodiMD as OAuth2-client, (no default value) |
|
||||
| `CMD_OAUTH2_CLIENT_SECRET` | `afae02fckafd...` | you will get this from your OAuth2 provider when you register CodiMD as OAuth2-client, (no default value) |
|
||||
| `CMD_OAUTH2_PROVIDERNAME` | `My institution` | Optional name to be displayed at login form indicating the oAuth2 provider |
|
||||
| `CMD_IMGUR_CLIENTID` | no example | Imgur API client id |
|
||||
| `CMD_EMAIL` | `true` or `false` | set to allow email signin |
|
||||
| `CMD_ALLOW_PDF_EXPORT` | `true` or `false` | Enable or disable PDF exports |
|
||||
| `CMD_ALLOW_EMAIL_REGISTER` | `true` or `false` | set to allow email register (only applied when email is set, default is `true`. Note `bin/manage_users` might help you if registration is `false`.) |
|
||||
| `CMD_ALLOW_GRAVATAR` | `true` or `false` | set to `false` to disable gravatar as profile picture source on your instance |
|
||||
| `CMD_IMAGE_UPLOAD_TYPE` | `imgur`, `s3`, `minio` or `filesystem` | Where to upload images. For S3, see our Image Upload Guides for [S3](docs/guides/s3-image-upload.md) or [Minio](docs/guides/minio-image-upload.md) |
|
||||
| `CMD_S3_ACCESS_KEY_ID` | no example | AWS access key id |
|
||||
| `CMD_S3_SECRET_ACCESS_KEY` | no example | AWS secret key |
|
||||
| `CMD_S3_REGION` | `ap-northeast-1` | AWS S3 region |
|
||||
| `CMD_S3_BUCKET` | no example | AWS S3 bucket name |
|
||||
| `CMD_MINIO_ACCESS_KEY` | no example | Minio access key |
|
||||
| `CMD_MINIO_SECRET_KEY` | no example | Minio secret key |
|
||||
| `CMD_MINIO_ENDPOINT` | `minio.example.org` | Address of your Minio endpoint/instance |
|
||||
| `CMD_MINIO_PORT` | `9000` | Port that is used for your Minio instance |
|
||||
| `CMD_MINIO_SECURE` | `true` | If set to `true` HTTPS is used for Minio |
|
||||
| `CMD_AZURE_CONNECTION_STRING` | no example | Azure Blob Storage connection string |
|
||||
| `CMD_AZURE_CONTAINER` | no example | Azure Blob Storage container name (automatically created if non existent) |
|
||||
| `CMD_HSTS_ENABLE` | ` true` | 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` | set to include subdomains in HSTS (default is `true`) |
|
||||
| `CMD_HSTS_MAX_AGE` | `31536000` | max duration in seconds to tell clients to keep HSTS status (default is a year) |
|
||||
| `CMD_HSTS_PRELOAD` | `true` | whether to allow preloading of the site's HSTS status (e.g. into browsers) |
|
||||
| `CMD_CSP_ENABLE` | `true` | whether to enable Content Security Policy (directives cannot be configured with environment variables) |
|
||||
| `CMD_CSP_REPORTURI` | `https://<someid>.report-uri.com/r/d/csp/enforce` | Allows to add a URL for CSP reports in case of violations |
|
||||
| `CMD_SOURCE_URL` | `https://github.com/hackmdio/codimd/tree/<current commit>` | Provides the link to the source code of CodiMD on the entry page (Please, make sure you change this when you run a modified version) |
|
||||
|
||||
***Note:** Due to the rename process we renamed all `HMD_`-prefix variables to be `CMD_`-prefixed. The old ones continue to work.*
|
||||
|
||||
## Application settings `config.json`
|
||||
|
||||
| variables | example values | description |
|
||||
| --------- | ------ | ----------- |
|
||||
| `debug` | `true` or `false` | set debug mode, show more logs |
|
||||
| `domain` | `localhost` | domain name |
|
||||
| `urlPath` | `codimd` | sub URL path, like `www.example.com/<urlpath>` |
|
||||
| `host` | `localhost` | host to listen on |
|
||||
| `port` | `80` | web app port |
|
||||
| `path` | `/var/run/codimd.sock` | path to UNIX domain socket to listen on (if specified, `host` and `port` are ignored) |
|
||||
| `loglevel` | `info` | Defines what kind of logs are provided to stdout. |
|
||||
| `allowOrigin` | `['localhost']` | domain name whitelist |
|
||||
| `useSSL` | `true` or `false` | set to use SSL server (if `true`, will auto turn on `protocolUseSSL`) |
|
||||
| `hsts` | `{"enable": true, "maxAgeSeconds": 31536000, "includeSubdomains": true, "preload": true}` | [HSTS](https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security) options to use with HTTPS (default is the example value, max age is a year) |
|
||||
| `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`. |
|
||||
| `protocolUseSSL` | `true` or `false` | set to use SSL protocol for resources path (only applied when domain is set) |
|
||||
| `urlAddPort` | `true` or `false` | set to add port on callback URL (ports `80` or `443` won't be applied) (only applied when domain is set) |
|
||||
| `useCDN` | `true` or `false` | set to use CDN resources or not (default is `true`) |
|
||||
| `allowAnonymous` | `true` or `false` | set to allow anonymous usage (default is `true`) |
|
||||
| `allowAnonymousEdits` | `true` or `false` | if `allowAnonymous` is `true`: allow users to select `freely` permission, allowing guests to edit existing notes (default is `false`) |
|
||||
| `allowFreeURL` | `true` or `false` | set to allow new note creation by accessing a nonexistent note URL |
|
||||
| `forbiddenNoteIDs` | `['robots.txt']` | disallow creation of notes, even if `allowFreeUrl` is `true` |
|
||||
| `defaultPermission` | `freely`, `editable`, `limited`, `locked`, `protected` or `private` | set notes default permission (only applied on signed users) |
|
||||
| `dbURL` | `mysql://localhost:3306/database` | set the db URL; if set, then db config (below) won't be applied |
|
||||
| `db` | `{ "dialect": "sqlite", "storage": "./db.codimd.sqlite" }` | set the db configs, [see more here](http://sequelize.readthedocs.org/en/latest/api/sequelize/) |
|
||||
| `sslKeyPath` | `./cert/client.key` | SSL key path<sup>1</sup> (only need when you set `useSSL`) |
|
||||
| `sslCertPath` | `./cert/codimd_io.crt` | SSL cert path<sup>1</sup> (only need when you set `useSSL`) |
|
||||
| `sslCAPath` | `['./cert/COMODORSAAddTrustCA.crt']` | SSL ca chain<sup>1</sup> (only need when you set `useSSL`) |
|
||||
| `dhParamPath` | `./cert/dhparam.pem` | SSL dhparam path<sup>1</sup> (only need when you set `useSSL`) |
|
||||
| `tmpPath` | `./tmp/` | temp directory path<sup>1</sup> |
|
||||
| `defaultNotePath` | `./public/default.md` | default note file 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` |
|
||||
| `sessionName` | `connect.sid` | cookie session name |
|
||||
| `sessionSecret` | `secret` | cookie session secret |
|
||||
| `sessionLife` | `14 * 24 * 60 * 60 * 1000` | cookie session life |
|
||||
| `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 |
|
||||
| `email` | `true` or `false` | set to allow email signin |
|
||||
| `oauth2` | `{baseURL: ..., userProfileURL: ..., userProfileUsernameAttr: ..., userProfileDisplayNameAttr: ..., userProfileEmailAttr: ..., tokenURL: ..., authorizationURL: ..., clientID: ..., clientSecret: ...}` | An object detailing your OAuth2 provider. Refer to the [Mattermost](docs/guides/auth/mattermost-self-hosted.md) or [Nextcloud](docs/guides/auth/nextcloud.md) examples for more details!|
|
||||
| `allowEmailRegister` | `true` or `false` | set to allow email register (only applied when email is set, default is `true`. Note `bin/manage_users` might help you if registration is `false`.) |
|
||||
| `allowGravatar` | `true` or `false` | set to `false` to disable gravatar as profile picture source on your instance |
|
||||
| `imageUploadType` | `imgur`, `s3`, `minio`, `azure` or `filesystem`(default) | Where to upload images. For S3, see our Image Upload Guides for [S3](docs/guides/s3-image-upload.md) or [Minio](docs/guides/minio-image-upload.md)|
|
||||
| `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 checkout our [Minio Image Upload Guide](docs/guides/minio-image-upload.md) |
|
||||
| `s3` | `{ "accessKeyId": "YOUR_S3_ACCESS_KEY_ID", "secretAccessKey": "YOUR_S3_ACCESS_KEY", "region": "YOUR_S3_REGION" }` | When `imageuploadtype` be set to `s3`, you would also need to setup this key, check our [S3 Image Upload Guide](docs/guides/s3-image-upload.md) |
|
||||
| `s3bucket` | `YOUR_S3_BUCKET_NAME` | bucket name when `imageUploadType` is set to `s3` or `minio` |
|
||||
| `sourceURL` | `https://github.com/hackmdio/codimd/tree/<current commit>` | Provides the link to the source code of CodiMD on the entry page (Please, make sure you change this when you run a modified version) |
|
||||
|
||||
<sup>1</sup>: relative paths are based on CodiMD's base directory
|
||||
|
||||
## Third-party integration API key settings
|
||||
|
||||
| service | settings location | description |
|
||||
| ------- | --------- | ----------- |
|
||||
| facebook, twitter, github, gitlab, mattermost, dropbox, google, ldap, saml | environment variables or `config.json` | for signin |
|
||||
| imgur, s3, minio, azure | environment variables or `config.json` | for image upload |
|
||||
| dropbox(`dropbox/appKey`) | `config.json` | for export and import |
|
||||
|
||||
## Third-party integration OAuth callback URLs
|
||||
|
||||
| service | callback URL (after the server URL) |
|
||||
| ------- | --------- |
|
||||
| facebook | `/auth/facebook/callback` |
|
||||
| twitter | `/auth/twitter/callback` |
|
||||
| github | `/auth/github/callback` |
|
||||
| gitlab | `/auth/gitlab/callback` |
|
||||
| mattermost | `/auth/mattermost/callback` |
|
||||
| dropbox | `/auth/dropbox/callback` |
|
||||
| google | `/auth/google/callback` |
|
||||
| saml | `/auth/saml/callback` |
|
||||
|
||||
# Developer Notes
|
||||
|
||||
## Structure
|
||||
|
||||
```text
|
||||
codimd/
|
||||
├── tmp/ --- temporary files
|
||||
├── docs/ --- document files
|
||||
├── lib/ --- server libraries
|
||||
└── public/ --- client files
|
||||
├── css/ --- css styles
|
||||
├── js/ --- js scripts
|
||||
├── vendor/ --- vendor includes
|
||||
└── views/ --- view templates
|
||||
```
|
||||
|
||||
## 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 [http://operational-transformation.github.io/](http://operational-transformation.github.io/)
|
||||
## Related Tools
|
||||
|
||||
Our community has created related tools, we'd like to highlight [codimd-cli](https://github.com/codimd/cli)
|
||||
which lets you use CodiMD from the comfort of your command line.
|
||||
|
||||
|
||||
# License
|
||||
|
||||
**License under AGPL.**
|
||||
Licensed under AGPLv3. For our list of contributors, see [AUTHORS](AUTHORS).
|
||||
|
||||
[gitter-image]: https://img.shields.io/badge/gitter-hackmdio/codimd-blue.svg
|
||||
[gitter-url]: https://gitter.im/hackmdio/hackmd
|
||||
[travis-image]: https://travis-ci.org/hackmdio/codimd.svg?branch=master
|
||||
[travis-url]: https://travis-ci.org/hackmdio/codimd
|
||||
[github-version-badge]: https://img.shields.io/github/release/hackmdio/codimd.svg
|
||||
[github-release-page]: https://github.com/hackmdio/codimd/releases
|
||||
[github-release-feed]: https://github.com/hackmdio/codimd/releases.atom
|
||||
[matrix.org-image]: https://img.shields.io/badge/Matrix.org-%23CodiMD@matrix.org-green.svg
|
||||
[matrix.org-url]: https://riot.im/app/#/room/#codimd:matrix.org
|
||||
[travis-image]: https://travis-ci.org/codimd/server.svg?branch=master
|
||||
[travis-url]: https://travis-ci.org/codimd/server
|
||||
[github-version-badge]: https://img.shields.io/github/release/codimd/server.svg
|
||||
[github-release-page]: https://github.com/codimd/server/releases
|
||||
[github-release-feed]: https://github.com/codimd/server/releases.atom
|
||||
[github-issue-tracker]: https://github.com/codimd/server/issues/
|
||||
[poeditor-image]: https://img.shields.io/badge/POEditor-translate-blue.svg
|
||||
[poeditor-url]: https://poeditor.com/join/project/q0nuPWyztp
|
||||
[poeditor-url]: https://poeditor.com/join/project/1OpGjF2Jir
|
||||
[codimd-demo]: https://demo.codimd.org
|
||||
[codimd-demo-features]: https://demo.codimd.org/features
|
||||
[codimd-community]: https://community.codimd.org
|
||||
[codimd-community-calls]: https://community.codimd.org/t/codimd-community-call/19
|
||||
|
|
1
app.js
|
@ -115,6 +115,7 @@ if (config.csp.enable) {
|
|||
i18n.configure({
|
||||
locales: ['en', 'zh-CN', 'zh-TW', 'fr', 'de', 'ja', 'es', 'ca', 'el', 'pt', 'it', 'tr', 'ru', 'nl', 'hr', 'pl', 'uk', 'hi', 'sv', 'eo', 'da', 'ko', 'id', 'sr'],
|
||||
cookie: 'locale',
|
||||
indent: ' ', // this is the style poeditor.com exports it, this creates less churn
|
||||
directory: path.join(__dirname, '/locales'),
|
||||
updateFiles: config.updateI18nFiles
|
||||
})
|
||||
|
|
76
app.json
|
@ -7,14 +7,10 @@
|
|||
"Notes"
|
||||
],
|
||||
"website": "https://codimd.org",
|
||||
"repository": "https://github.com/hackmdio/codimd",
|
||||
"logo": "https://github.com/hackmdio/codimd/raw/master/public/codimd-icon-1024.png",
|
||||
"repository": "https://github.com/codimd/server",
|
||||
"logo": "https://github.com/codimd/server/raw/master/public/codimd-icon-1024.png",
|
||||
"success_url": "/",
|
||||
"env": {
|
||||
"BUILD_ASSETS": {
|
||||
"description": "Our build script variable",
|
||||
"value": "true"
|
||||
},
|
||||
"NPM_CONFIG_PRODUCTION": {
|
||||
"description": "Let npm also install development build tool",
|
||||
"value": "false"
|
||||
|
@ -23,137 +19,129 @@
|
|||
"description": "Specify database type. See sequelize available databases. Default using postgres",
|
||||
"value": "postgres"
|
||||
},
|
||||
"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_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
|
||||
}
|
||||
},
|
||||
"addons": [
|
||||
"heroku-postgresql"
|
||||
],
|
||||
"buildpacks": [
|
||||
{
|
||||
"url": "https://github.com/alex88/heroku-buildpack-vips"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/heroku/heroku-buildpack-nodejs"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
10
bin/heroku
|
@ -2,9 +2,7 @@
|
|||
|
||||
set -e
|
||||
|
||||
if [ "$BUILD_ASSETS" = true ]; then
|
||||
# setup config files
|
||||
cat << EOF > .sequelizerc
|
||||
cat << EOF > .sequelizerc
|
||||
var path = require('path');
|
||||
|
||||
module.exports = {
|
||||
|
@ -17,7 +15,7 @@ module.exports = {
|
|||
|
||||
EOF
|
||||
|
||||
cat << EOF > config.json
|
||||
cat << EOF > config.json
|
||||
|
||||
{
|
||||
"production": {
|
||||
|
@ -25,7 +23,3 @@ EOF
|
|||
}
|
||||
|
||||
EOF
|
||||
|
||||
# build app
|
||||
npm run build
|
||||
fi
|
||||
|
|
|
@ -36,7 +36,7 @@ cat << EOF
|
|||
|
||||
|
||||
Edit the following config file to setup CodiMD server and client.
|
||||
Read more info at https://github.com/hackmdio/codimd#configuration-files
|
||||
Read more info at https://github.com/codimd/server#configuration-files
|
||||
|
||||
* config.json -- CodiMD config
|
||||
* .sequelizerc -- db config
|
||||
|
|
|
@ -93,6 +93,7 @@
|
|||
"idpCert": "change: certificate file path of IdP in PEM format",
|
||||
"issuer": "change or delete: identity of the service provider (default: serverurl)",
|
||||
"identifierFormat": "change or delete: name identifier format (default: 'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress')",
|
||||
"disableRequestedAuthnContext": "change or delete: true to allow any authentication method, false restricts to password authentication method (default: false)",
|
||||
"groupAttribute": "change or delete: attribute name for group list (ex: memberOf)",
|
||||
"requiredGroups": [ "change or delete: group names that allowed" ],
|
||||
"externalGroups": [ "change or delete: group names that not allowed" ],
|
||||
|
|
153
docs/configuration-config-file.md
Normal file
|
@ -0,0 +1,153 @@
|
|||
Configuration Using Config file
|
||||
===
|
||||
|
||||
You can choose to configure CodiMD with either a config file or with
|
||||
[environment variables](configuration-env-vars.md). The config file is processed
|
||||
in [`lib/config/index.js`](../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`](../lib/config/default.js),
|
||||
in case you wonder if you even need to override it.
|
||||
|
||||
Environment variables take precedence over configurations from the config files.
|
||||
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.
|
||||
|
||||
|
||||
## Node.JS
|
||||
|
||||
| variables | example values | description |
|
||||
| --------- | ------ | ----------- |
|
||||
| `debug` | `true` or `false` | set debug mode, show more logs |
|
||||
|
||||
|
||||
## CodiMD basics
|
||||
|
||||
| variables | example values | description |
|
||||
| --------- | ------ | ----------- |
|
||||
| `allowPDFExport` | `true` | Whether or not PDF export is offered. |
|
||||
| `db` | `{ "dialect": "sqlite", "storage": "./db.codimd.sqlite" }` | set the db configs, [see more here](http://sequelize.readthedocs.org/en/latest/api/sequelize/) |
|
||||
| `dbURL` | `mysql://localhost:3306/database` | set the db URL; if set, then db config (below) won't be applied |
|
||||
| `forbiddenNoteIDs` | `['robots.txt']` | disallow creation of notes, even if `allowFreeUrl` is `true` |
|
||||
| `loglevel` | `info` | Defines what kind of logs are provided to stdout. |
|
||||
| `imageUploadType` | `imgur`, `s3`, `minio`, `azure`, `lutim` or `filesystem`(default) | 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)|
|
||||
| `sourceURL` | `https://github.com/codimd/server/tree/<current commit>` | Provides the link to the source code of CodiMD on the entry page (Please, make sure you change this when you run a modified version) |
|
||||
| `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 |
|
||||
|
||||
|
||||
## CodiMD paths stuff
|
||||
|
||||
these are rarely used for various reasons.
|
||||
|
||||
| variables | example values | description |
|
||||
| --------- | ------ | ----------- |
|
||||
| `defaultNotePath` | `./public/default.md` | default note file path<sup>1</sup>, empty notes will be created with this template. |
|
||||
| `dhParamPath` | `./cert/dhparam.pem` | SSL dhparam path<sup>1</sup> (only need when you set `useSSL`) |
|
||||
| `sslCAPath` | `['./cert/COMODORSAAddTrustCA.crt']` | SSL ca chain<sup>1</sup> (only need when you set `useSSL`) |
|
||||
| `sslCertPath` | `./cert/codimd_io.crt` | SSL cert path<sup>1</sup> (only need when you set `useSSL`) |
|
||||
| `sslKeyPath` | `./cert/client.key` | SSL key path<sup>1</sup> (only need when you set `useSSL`) |
|
||||
| `tmpPath` | `./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` |
|
||||
|
||||
|
||||
## CodiMD Location
|
||||
|
||||
| variables | example values | description |
|
||||
| --------- | ------ | ----------- |
|
||||
| `domain` | `localhost` | domain name |
|
||||
| `urlPath` | `codimd` | sub URL path, like `www.example.com/<urlpath>` |
|
||||
| `host` | `localhost` | interface/ip to listen on |
|
||||
| `port` | `80` | port to listen on |
|
||||
| `path` | `/var/run/codimd.sock` | path to UNIX domain socket to listen on (if specified, `host` and `port` are ignored) |
|
||||
| `protocolUseSSL` | `true` or `false` | set to use SSL protocol for resources path (only applied when domain is set) |
|
||||
| `useSSL` | `true` or `false` | set to use SSL server (if `true`, will auto turn on `protocolUseSSL`) |
|
||||
| `urlAddPort` | `true` or `false` | set to add port on callback URL (ports `80` or `443` won't be applied) (only applied when domain is set) |
|
||||
| `allowOrigin` | `['localhost']` | domain name whitelist |
|
||||
|
||||
|
||||
## CSP and HSTS
|
||||
|
||||
| variables | example values | 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) |
|
||||
| `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`. |
|
||||
|
||||
## Privacy and External Requests
|
||||
|
||||
| variables | example values | description |
|
||||
| --------- | ------ | ----------- |
|
||||
| `allowGravatar` | `true` or `false` | set to `false` to disable gravatar as profile picture source on your instance |
|
||||
| `useCDN` | `true` or `false` | set to use CDN resources or not (default is `true`) |
|
||||
|
||||
## Users and Privileges
|
||||
|
||||
| variables | example values | description |
|
||||
| --------- | ------ | ----------- |
|
||||
| `allowAnonymous` | `true` or `false` | set to allow anonymous usage (default is `true`) |
|
||||
| `allowAnonymousEdits` | `true` or `false` | if `allowAnonymous` is `true`: allow users to select `freely` permission, allowing guests to edit existing notes (default is `false`) |
|
||||
| `allowFreeURL` | `true` or `false` | set to allow new note creation by accessing a nonexistent note URL |
|
||||
| `defaultPermission` | `freely`, `editable`, `limited`, `locked`, `protected` or `private` | set notes default permission (only applied on signed users) |
|
||||
| `sessionName` | `connect.sid` | cookie session name |
|
||||
| `sessionLife` | `14 * 24 * 60 * 60 * 1000` | cookie session life |
|
||||
| `sessionSecret` | `secret` | cookie session secret | If none is set, one will randomly generated on each startup, meaning all your users will be logged out. |
|
||||
|
||||
|
||||
## Login methods
|
||||
|
||||
Most of these have never been documented for the config.json, feel free to expand these
|
||||
|
||||
### Email (local account)
|
||||
|
||||
| variables | example values | description |
|
||||
| --------- | ------ | ----------- |
|
||||
| `email` | `true` or `false` | set to allow email signin |
|
||||
| `allowEmailRegister` | `true` or `false` | set to allow email register (only applied when email is set, default is `true`. Note `bin/manage_users` might help you if registration is `false`.) |
|
||||
|
||||
### Dropbox Login
|
||||
### Facebook Login
|
||||
### GitHub Login
|
||||
### GitLab Login
|
||||
### Google Login
|
||||
### LDAP Login
|
||||
### Mattermost Login
|
||||
### OAuth2 Login
|
||||
|
||||
| variables | example values | description |
|
||||
| --------- | ------ | ----------- |
|
||||
| `oauth2` | `{baseURL: ..., userProfileURL: ..., userProfileUsernameAttr: ..., userProfileDisplayNameAttr: ..., userProfileEmailAttr: ..., tokenURL: ..., authorizationURL: ..., clientID: ..., clientSecret: ...}` | 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!|
|
||||
|
||||
### SAML Login
|
||||
### Twitter Login
|
||||
|
||||
|
||||
## Upload Storage
|
||||
|
||||
Most of these have never been documented for the config.json, feel free to expand these
|
||||
|
||||
|
||||
### Amazon S3
|
||||
|
||||
| variables | example values | 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) |
|
||||
| `s3bucket` | `YOUR_S3_BUCKET_NAME` | bucket name when `imageUploadType` is set to `s3` or `minio` |
|
||||
|
||||
### Azure Blob Storage
|
||||
### imgur
|
||||
### Minio
|
||||
|
||||
| variables | example values | 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) |
|
||||
|
||||
### Lutim
|
||||
|
||||
| variables | example values | description |
|
||||
| --------- | ------ | ----------- |
|
||||
|`lutim`| `{"url": "YOUR_LUTIM_URL"}`| When `imageUploadType` is set to `lutim`, you can setup the lutim url|
|
||||
|
||||
<sup>1</sup>: relative paths are based on CodiMD's base directory
|
255
docs/configuration-env-vars.md
Normal file
|
@ -0,0 +1,255 @@
|
|||
Configuration Using Environment variables
|
||||
===
|
||||
|
||||
You can choose to configure CodiMD with either a
|
||||
[config file](configuration-config-file.md) or with environment variables.
|
||||
Environment variables are processed in
|
||||
[`lib/config/environment.js`](../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`](../lib/config/default.js),
|
||||
in case you wonder if you even need to override it.
|
||||
|
||||
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.
|
||||
|
||||
|
||||
## Node.JS
|
||||
|
||||
| variable | example value | description |
|
||||
| -------- | ------------- | ----------- |
|
||||
| `NODE_ENV` | `production` or `development` | set current environment (will apply corresponding settings in the `config.json`) |
|
||||
| `DEBUG` | `true` or `false` | set debug mode; show more logs |
|
||||
|
||||
|
||||
## CodiMD basics
|
||||
|
||||
defaultNotePath can't be set from env-vars
|
||||
|
||||
| variable | example value | description |
|
||||
| -------- | ------------- | ----------- |
|
||||
| `CMD_ALLOW_PDF_EXPORT` | `true` or `false` | Enable or disable PDF exports |
|
||||
| `CMD_CONFIG_FILE` | `/path/to/config.json` | optional override for the path to CodiMD's config file |
|
||||
| `CMD_DB_URL` | `mysql://localhost:3306/database` | set the database URL |
|
||||
| `CMD_LOGLEVEL` | `info`, `debug` ... | Defines what kind of logs are provided to stdout. |
|
||||
| `CMD_FORBIDDEN_NOTE_IDS` | `'robots.txt'` | disallow creation of notes, even if `CMD_ALLOW_FREEURL` is `true` |
|
||||
| `CMD_IMAGE_UPLOAD_TYPE` | `imgur`, `s3`, `minio`, `lutim` or `filesystem` | 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. |
|
||||
| `CMD_SOURCE_URL` | `https://github.com/codimd/server/tree/<current commit>` | Provides the link to the source code of CodiMD on the entry page (Please, make sure you change this when you run a modified version) |
|
||||
|
||||
|
||||
## CodiMD Location
|
||||
|
||||
| variable | example value | description |
|
||||
| -------- | ------------- | ----------- |
|
||||
| `CMD_DOMAIN` | `codimd.org` | domain name |
|
||||
| `CMD_URL_PATH` | `codimd` | If CodiMD is run from a subdirectory like `www.example.com/<urlpath>` |
|
||||
| `CMD_HOST` | `localhost` | interface/ip to listen on |
|
||||
| `CMD_PORT` | `80` | port to listen on |
|
||||
| `CMD_PATH` | `/var/run/codimd.sock` | path to UNIX domain socket to listen on (if specified, `CMD_HOST` and `CMD_PORT` are ignored) |
|
||||
| `CMD_PROTOCOL_USESSL` | `true` or `false` | set to use SSL protocol for resources path (only applied when domain is set) |
|
||||
| `CMD_URL_ADDPORT` | `true` or `false` | set to add port on callback URL (ports `80` or `443` won't be applied) (only applied when domain is set) |
|
||||
| `CMD_ALLOW_ORIGIN` | `localhost, codimd.org` | domain name whitelist (use comma to separate) |
|
||||
|
||||
|
||||
## CSP and HSTS
|
||||
|
||||
| variable | example value | description |
|
||||
| -------- | ------------- | ----------- |
|
||||
| `CMD_CSP_ENABLE` | `true` | whether to enable Content Security Policy (directives cannot be configured with environment variables) |
|
||||
| `CMD_CSP_REPORTURI` | `https://<someid>.report-uri.com/r/d/csp/enforce` | Allows to add a URL for CSP reports in case of violations |
|
||||
| `CMD_HSTS_ENABLE` | ` true` | 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` | set to include subdomains in HSTS (default is `true`) |
|
||||
| `CMD_HSTS_MAX_AGE` | `31536000` | max duration in seconds to tell clients to keep HSTS status (default is a year) |
|
||||
| `CMD_HSTS_PRELOAD` | `true` | whether to allow preloading of the site's HSTS status (e.g. into browsers) |
|
||||
|
||||
|
||||
## Privacy and External Requests
|
||||
|
||||
| variable | example value | description |
|
||||
| -------- | ------------- | ----------- |
|
||||
| `CMD_ALLOW_GRAVATAR` | `true` or `false` | set to `false` to disable gravatar as profile picture source on your instance |
|
||||
| `CMD_USECDN` | `true` or `false` | set to use CDN resources or not|
|
||||
|
||||
|
||||
## Users and Privileges
|
||||
|
||||
| variable | example value | description |
|
||||
| -------- | ------------- | ----------- |
|
||||
| `CMD_ALLOW_ANONYMOUS` | `true` or `false` | set to allow anonymous usage (default is `true`) |
|
||||
| `CMD_ALLOW_ANONYMOUS_EDITS` | `true` or `false` | if `allowAnonymous` is `true`, allow users to select `freely` permission, allowing guests to edit existing notes (default is `false`) |
|
||||
| `CMD_ALLOW_FREEURL` | `true` or `false` | set to allow new note creation by accessing a nonexistent note URL |
|
||||
| `CMD_DEFAULT_PERMISSION` | `freely`, `editable`, `limited`, `locked` or `private` | set notes default permission (only applied on signed users) |
|
||||
| `CMD_SESSION_LIFE` | `1209600000` | Session life time. (milliseconds) |
|
||||
| `CMD_SESSION_SECRET` | no example | 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)
|
||||
|
||||
| variable | example value | description |
|
||||
| -------- | ------------- | ----------- |
|
||||
| `CMD_EMAIL` | `true` or `false` | set to allow email signin |
|
||||
| `CMD_ALLOW_EMAIL_REGISTER` | `true` or `false` | set to allow email register (only applied when email is set, default is `true`. Note `bin/manage_users` might help you if registration is `false`.) |
|
||||
|
||||
|
||||
### Dropbox Login
|
||||
|
||||
| variable | example value | description |
|
||||
| -------- | ------------- | ----------- |
|
||||
| `CMD_DROPBOX_CLIENTID` | no example | Dropbox API client id |
|
||||
| `CMD_DROPBOX_CLIENTSECRET` | no example | Dropbox API client secret |
|
||||
|
||||
|
||||
### Facebook Login
|
||||
|
||||
| variable | example value | description |
|
||||
| -------- | ------------- | ----------- |
|
||||
| `CMD_FACEBOOK_CLIENTID` | no example | Facebook API client id |
|
||||
| `CMD_FACEBOOK_CLIENTSECRET` | no example | Facebook API client secret |
|
||||
|
||||
|
||||
### GitHub Login
|
||||
|
||||
| variable | example value | description |
|
||||
| -------- | ------------- | ----------- |
|
||||
| `CMD_GITHUB_CLIENTID` | no example | GitHub API client id |
|
||||
| `CMD_GITHUB_CLIENTSECRET` | no example | GitHub API client secret |
|
||||
|
||||
|
||||
### GitLab Login
|
||||
|
||||
| variable | example value | description |
|
||||
| -------- | ------------- | ----------- |
|
||||
| `CMD_GITLAB_SCOPE` | `read_user` or `api` | GitLab API requested scope (default is `api`) (GitLab snippet import/export need `api` scope) |
|
||||
| `CMD_GITLAB_BASEURL` | no example | GitLab authentication endpoint, set to use other endpoint than GitLab.com (optional) |
|
||||
| `CMD_GITLAB_CLIENTID` | no example | GitLab API client id |
|
||||
| `CMD_GITLAB_CLIENTSECRET` | no example | GitLab API client secret |
|
||||
| `CMD_GITLAB_VERSION` | no example | GitLab API version (v3 or v4) |
|
||||
|
||||
|
||||
### Google Login
|
||||
|
||||
| variable | example value | description |
|
||||
| -------- | ------------- | ----------- |
|
||||
| `CMD_GOOGLE_CLIENTID` | no example | Google API client id |
|
||||
| `CMD_GOOGLE_CLIENTSECRET` | no example | Google API client secret |
|
||||
|
||||
|
||||
### LDAP Login
|
||||
|
||||
| variable | example value | description |
|
||||
| -------- | ------------- | ----------- |
|
||||
| `CMD_LDAP_URL` | `ldap://example.com` | URL of LDAP server |
|
||||
| `CMD_LDAP_BINDDN` | no example | bindDn for LDAP access |
|
||||
| `CMD_LDAP_BINDCREDENTIALS` | no example | bindCredentials for LDAP access |
|
||||
| `CMD_LDAP_SEARCHBASE` | `o=users,dc=example,dc=com` | LDAP directory to begin search from |
|
||||
| `CMD_LDAP_SEARCHFILTER` | `(uid={{username}})` | LDAP filter to search with |
|
||||
| `CMD_LDAP_SEARCHATTRIBUTES` | `displayName, mail` | LDAP attributes to search with (use comma to separate) |
|
||||
| `CMD_LDAP_USERIDFIELD` | `uidNumber` or `uid` or `sAMAccountName` | The LDAP field which is used uniquely identify a user on CodiMD |
|
||||
| `CMD_LDAP_USERNAMEFIELD` | Fallback to userid | The LDAP field which is used as the username on CodiMD |
|
||||
| `CMD_LDAP_TLS_CA` | `server-cert.pem, root.pem` | Root CA for LDAP TLS in PEM format (use comma to separate) |
|
||||
| `CMD_LDAP_PROVIDERNAME` | `My institution` | Optional name to be displayed at login form indicating the LDAP provider |
|
||||
|
||||
|
||||
### Mattermost Login
|
||||
|
||||
| variable | example value | description |
|
||||
| -------- | ------------- | ----------- |
|
||||
| `CMD_MATTERMOST_BASEURL` | no example | 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 example | Mattermost API client id |
|
||||
| `CMD_MATTERMOST_CLIENTSECRET` | no example | Mattermost API client secret |
|
||||
|
||||
|
||||
### OAuth2 Login
|
||||
|
||||
| variable | example value | description |
|
||||
| -------- | ------------- | ----------- |
|
||||
| `CMD_OAUTH2_USER_PROFILE_URL` | `https://example.com` | where retrieve information about a user after succesful login. Needs to output JSON. (no default value) Refer to the [Mattermost](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` | `name` | where to find the username in the JSON from the user profile URL. (no default value)|
|
||||
| `CMD_OAUTH2_USER_PROFILE_DISPLAY_NAME_ATTR` | `display-name` | where to find the display-name in the JSON from the user profile URL. (no default value) |
|
||||
| `CMD_OAUTH2_USER_PROFILE_EMAIL_ATTR` | `email` | where to find the email address in the JSON from the user profile URL. (no default value) |
|
||||
| `CMD_OAUTH2_TOKEN_URL` | `https://example.com` | sometimes called token endpoint, please refer to the documentation of your OAuth2 provider (no default value) |
|
||||
| `CMD_OAUTH2_AUTHORIZATION_URL` | `https://example.com` | authorization URL of your provider, please refer to the documentation of your OAuth2 provider (no default value) |
|
||||
| `CMD_OAUTH2_CLIENT_ID` | `afae02fckafd...` | you will get this from your OAuth2 provider when you register CodiMD as OAuth2-client, (no default value) |
|
||||
| `CMD_OAUTH2_CLIENT_SECRET` | `afae02fckafd...` | you will get this from your OAuth2 provider when you register CodiMD as OAuth2-client, (no default value) |
|
||||
| `CMD_OAUTH2_PROVIDERNAME` | `My institution` | Optional name to be displayed at login form indicating the oAuth2 provider |
|
||||
|
||||
|
||||
### SAML Login
|
||||
|
||||
| variable | example value | description |
|
||||
| -------- | ------------- | ----------- |
|
||||
| `CMD_SAML_IDPSSOURL` | `https://idp.example.com/sso` | authentication endpoint of IdP. for details, see [guide](guides/auth/saml-onelogin.md). |
|
||||
| `CMD_SAML_IDPCERT` | `/path/to/cert.pem` | certificate file path of IdP in PEM format |
|
||||
| `CMD_SAML_ISSUER` | no example | identity of the service provider (optional, default: serverurl)" |
|
||||
| `CMD_SAML_DISABLEREQUESTEDAUTHNCONTEXT` | `true` or `false` | true to allow any authentication method, false restricts to password authentication (PasswordProtectedTransport) method (default: false) |
|
||||
| `CMD_SAML_IDENTIFIERFORMAT` | no example | name identifier format (optional, default: `urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress`) |
|
||||
| `CMD_SAML_GROUPATTRIBUTE` | `memberOf` | attribute name for group list (optional) |
|
||||
| `CMD_SAML_REQUIREDGROUPS` | `codimd-users` | group names that allowed (use vertical bar to separate) (optional) |
|
||||
| `CMD_SAML_EXTERNALGROUPS` | `Temporary-staff` | group names that not allowed (use vertical bar to separate) (optional) |
|
||||
| `CMD_SAML_ATTRIBUTE_ID` | `sAMAccountName` | attribute map for `id` (optional, default: NameID of SAML response) |
|
||||
| `CMD_SAML_ATTRIBUTE_USERNAME` | `mailNickname` | attribute map for `username` (optional, default: NameID of SAML response) |
|
||||
| `CMD_SAML_ATTRIBUTE_EMAIL` | `mail` | attribute map for `email` (optional, default: NameID of SAML response if `CMD_SAML_IDENTIFIERFORMAT` is default) |
|
||||
|
||||
|
||||
### Twitter Login
|
||||
|
||||
| variable | example value | description |
|
||||
| -------- | ------------- | ----------- |
|
||||
| `CMD_TWITTER_CONSUMERKEY` | no example | Twitter API consumer key |
|
||||
| `CMD_TWITTER_CONSUMERSECRET` | no example | 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
|
||||
|
||||
| variable | example value | description |
|
||||
| -------- | ------------- | ----------- |
|
||||
| `CMD_S3_ACCESS_KEY_ID` | no example | AWS access key id |
|
||||
| `CMD_S3_SECRET_ACCESS_KEY` | no example | AWS secret key |
|
||||
| `CMD_S3_REGION` | `ap-northeast-1` | AWS S3 region |
|
||||
| `CMD_S3_BUCKET` | no example | AWS S3 bucket name |
|
||||
|
||||
|
||||
### Azure Blob Storage
|
||||
|
||||
| variable | example value | description |
|
||||
| -------- | ------------- | ----------- |
|
||||
| `CMD_AZURE_CONNECTION_STRING` | no example | Azure Blob Storage connection string |
|
||||
| `CMD_AZURE_CONTAINER` | no example | Azure Blob Storage container name (automatically created if non existent) |
|
||||
|
||||
|
||||
### imgur
|
||||
|
||||
| variable | example value | description |
|
||||
| -------- | ------------- | ----------- |
|
||||
| `CMD_IMGUR_CLIENTID` | no example | Imgur API client id |
|
||||
|
||||
|
||||
### Minio
|
||||
|
||||
| variable | example value | description |
|
||||
| -------- | ------------- | ----------- |
|
||||
| `CMD_MINIO_ACCESS_KEY` | no example | Minio access key |
|
||||
| `CMD_MINIO_SECRET_KEY` | no example | Minio secret key |
|
||||
| `CMD_MINIO_ENDPOINT` | `minio.example.org` | Address of your Minio endpoint/instance |
|
||||
| `CMD_MINIO_PORT` | `9000` | Port that is used for your Minio instance |
|
||||
| `CMD_MINIO_SECURE` | `true` | If set to `true` HTTPS is used for Minio |
|
||||
|
||||
|
||||
### Lutim
|
||||
|
||||
| variable | example value | description |
|
||||
| -------- | ------------- | ----------- |
|
||||
| `CMD_LUTIM_URL` | `https://framapic.org/` | When `CMD_IMAGE_UPLOAD_TYPE` is set to `lutim`, you can setup the lutim url |
|
||||
|
||||
**Note:** *Due to the rename process we renamed all `HMD_`-prefix variables to be `CMD_`-prefixed. The old ones continue to work.*
|
||||
|
||||
**Note:** *relative paths are based on CodiMD's base directory*
|
57
docs/dev/getting-started.md
Normal file
|
@ -0,0 +1,57 @@
|
|||
Developer Notes
|
||||
===
|
||||
|
||||
## 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/codimd/server.git codimd-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-config-file.md) or set up
|
||||
[environment variables](../configuration-env-vars.md).
|
||||
|
||||
|
||||
## Running the Code
|
||||
|
||||
Now that everything is in place, we can start CodiMD:
|
||||
|
||||
4. `npm run build` will build the frontend bundle. It uses webpack to do that.
|
||||
5. 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.
|
||||
|
||||
4. Use `npm run dev` if you want webpack to continuously rebuild the frontend
|
||||
code.
|
||||
5. 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
|
||||
codimd-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
|
||||
```
|
14
docs/dev/ot.md
Normal file
|
@ -0,0 +1,14 @@
|
|||
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,4 +1,11 @@
|
|||
# Webpack Docs
|
||||
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 definition for chunks and plugins, that are needed by the whole app.
|
||||
|
||||
|
|
|
@ -1,27 +1,24 @@
|
|||
Authentication guide - GitHub
|
||||
===
|
||||
|
||||
***Note:** This guide was written before the renaming. Just replace `HackMD` with `CodiMD` in your mind :smile: thanks!*
|
||||
**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)
|
||||
![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)
|
||||
|
||||
![register-oauth-application-form](../images/auth/register-oauth-application-form.png)
|
||||
|
||||
*Note: The callback URL is <your-hackmd-url>/auth/github/callback*
|
||||
**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)
|
||||
![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
|
||||
* `config.json`:
|
||||
```js
|
||||
{
|
||||
"production": {
|
||||
"github": {
|
||||
|
@ -30,9 +27,9 @@ Authentication guide - GitHub
|
|||
}
|
||||
}
|
||||
}
|
||||
````
|
||||
```
|
||||
* environment variables:
|
||||
````
|
||||
HMD_GITHUB_CLIENTID=3747d30eaccXXXXXXXXX
|
||||
HMD_GITHUB_CLIENTSECRET=2a8e682948eee0c580XXXXXXXXXXXXXXXXXXXXXX
|
||||
```sh
|
||||
CMD_GITHUB_CLIENTID=3747d30eaccXXXXXXXXX
|
||||
CMD_GITHUB_CLIENTSECRET=2a8e682948eee0c580XXXXXXXXXXXXXXXXXXXXXX
|
||||
````
|
||||
|
|
|
@ -1,24 +1,24 @@
|
|||
# GitLab (self-hosted)
|
||||
GitLab (self-hosted)
|
||||
===
|
||||
|
||||
***Note:** This guide was written before the renaming. Just replace `HackMD` with `CodiMD` in your mind :smile: thanks!*
|
||||
**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)
|
||||
![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)
|
||||
![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_DOMAIN=your.codimd.domain
|
||||
- HMD_URL_ADDPORT=443
|
||||
- HMD_PROTOCOL_USESSL=true
|
||||
- HMD_GITLAB_BASEURL=https://your.gitlab.domain
|
||||
|
@ -27,6 +27,6 @@
|
|||
```
|
||||
|
||||
7. Run `docker-compose up -d` to apply your settings.
|
||||
8. Sign in to your HackMD using your GitLab ID:
|
||||
8. Sign in to your CodiMD using your GitLab ID:
|
||||
|
||||
![Sign in via GitLab](../images/auth/gitlab-sign-in.png)
|
||||
![Sign in via GitLab](../../images/auth/gitlab-sign-in.png)
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
AD LDAP auth
|
||||
===
|
||||
|
||||
|
||||
To setup your CodiMD instance with Active Directory you need the following configs:
|
||||
|
||||
```
|
||||
|
|
|
@ -1,33 +1,29 @@
|
|||
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.*
|
||||
**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)
|
||||
![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)
|
||||
![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)
|
||||
![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)
|
||||
![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
|
||||
* `config.json`:
|
||||
```javascript
|
||||
{
|
||||
"production": {
|
||||
"oauth2": {
|
||||
|
@ -43,9 +39,9 @@ This guide uses the generic OAuth2 module for compatibility with Mattermost vers
|
|||
}
|
||||
}
|
||||
}
|
||||
````
|
||||
```
|
||||
* 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
|
||||
|
@ -55,4 +51,4 @@ This guide uses the generic OAuth2 module for compatibility with Mattermost vers
|
|||
CMD_OAUTH2_AUTHORIZATION_URL=https://your.mattermost.domain/oauth/authorize
|
||||
CMD_OAUTH2_CLIENT_ID=ii4p1u3jz7dXXXXXXXXXXXXXXX
|
||||
CMD_OAUTH2_CLIENT_SECRET=mqzzx6fydbXXXXXXXXXXXXXXXX
|
||||
````
|
||||
```
|
||||
|
|
|
@ -10,14 +10,14 @@ This guide uses the generic OAuth2 module for compatibility with Nextcloud 13 an
|
|||
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)
|
||||
![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)
|
||||
![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)
|
||||
![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!
|
||||
|
||||
|
|
12
docs/guides/auth/oauth.md
Normal file
|
@ -0,0 +1,12 @@
|
|||
# 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` |
|
||||
| mattermost | `/auth/mattermost/callback` |
|
||||
| dropbox | `/auth/dropbox/callback` |
|
||||
| google | `/auth/google/callback` |
|
||||
| saml | `/auth/saml/callback` |
|
|
@ -1,40 +1,35 @@
|
|||
Authentication guide - SAML (OneLogin)
|
||||
===
|
||||
|
||||
***Note:** This guide was written before the renaming. Just replace `HackMD` with `CodiMD` in your mind :smile: thanks!*
|
||||
**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)
|
||||
![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)
|
||||
![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)
|
||||
![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)
|
||||
* 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 hackmd. (serverurl + /auth/saml)
|
||||
|
||||
![onelogin-edit-sp-metadata](../images/auth/onelogin-edit-sp-metadata.png)
|
||||
* 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)
|
||||
|
||||
![onelogin-copy-idp-metadata](../images/auth/onelogin-copy-idp-metadata.png)
|
||||
|
||||
8. In your hackmd server, create IdP certificate file from (A)
|
||||
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
|
||||
* `config.json`:
|
||||
```javascript
|
||||
{
|
||||
"production": {
|
||||
"saml": {
|
||||
|
@ -43,12 +38,11 @@ Authentication guide - SAML (OneLogin)
|
|||
}
|
||||
}
|
||||
}
|
||||
````
|
||||
```
|
||||
* 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)
|
||||
```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,7 +1,7 @@
|
|||
Authentication guide - SAML
|
||||
===
|
||||
|
||||
***Note:** This guide was written before the renaming. Just replace `HackMD` with `CodiMD` in your mind :smile: thanks!*
|
||||
**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.
|
||||
|
||||
|
@ -9,36 +9,36 @@ The basic procedure is the same as the case of OneLogin which is mentioned in [O
|
|||
* {{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
|
||||
* `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
|
||||
* `config.json`:
|
||||
```javascript
|
||||
{
|
||||
"production": {
|
||||
"saml": {
|
||||
/* omitted */
|
||||
"issuer": "myhackmd"
|
||||
"issuer": "mycodimd"
|
||||
"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
|
||||
````
|
||||
```
|
||||
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 HackMD
|
||||
* `attribute.username`: Attribute name of displaying user name on HackMD
|
||||
* `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
|
||||
* `config.json`:
|
||||
```javascript
|
||||
{
|
||||
"production": {
|
||||
"saml": {
|
||||
|
@ -51,35 +51,35 @@ The basic procedure is the same as the case of OneLogin which is mentioned in [O
|
|||
}
|
||||
}
|
||||
}
|
||||
````
|
||||
```
|
||||
* environment variables
|
||||
````
|
||||
HMD_SAML_ATTRIBUTE_ID=sAMAccountName
|
||||
HMD_SAML_ATTRIBUTE_USERNAME=nickName
|
||||
HMD_SAML_ATTRIBUTE_EMAIL=mail
|
||||
````
|
||||
```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 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.
|
||||
* `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
|
||||
* `config.json`:
|
||||
```javascript
|
||||
{
|
||||
"production": {
|
||||
"saml": {
|
||||
/* omitted */
|
||||
"groupAttribute": "memberOf",
|
||||
"requiredGroups": [ "hackmd-users", "board-members" ],
|
||||
"requiredGroups": [ "codimd-users", "board-members" ],
|
||||
"externalGroups": [ "temporary-staff" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
````
|
||||
```
|
||||
* environment variables
|
||||
````
|
||||
HMD_SAML_GROUPATTRIBUTE=memberOf
|
||||
HMD_SAML_REQUIREDGROUPS=hackmd-users|board-members
|
||||
HMD_SAML_EXTERNALGROUPS=temporary-staff
|
||||
````
|
||||
```sh
|
||||
CMD_SAML_GROUPATTRIBUTE=memberOf
|
||||
CMD_SAML_REQUIREDGROUPS=codimd-users|board-members
|
||||
CMD_SAML_EXTERNALGROUPS=temporary-staff
|
||||
```
|
||||
|
|
|
@ -1,33 +1,29 @@
|
|||
Authentication guide - Twitter
|
||||
===
|
||||
|
||||
***Note:** This guide was written before the renaming. Just replace `HackMD` with `CodiMD` in your mind :smile: thanks!*
|
||||
**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)
|
||||
![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)
|
||||
|
||||
![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*
|
||||
|
||||
*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
|
||||
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)
|
||||
![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)
|
||||
|
||||
![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
|
||||
7. Add your Consumer Key and Consumer Secret to your `config.json` file or pass them as environment variables:
|
||||
* `config.json`:
|
||||
```javascript
|
||||
{
|
||||
"production": {
|
||||
"twitter": {
|
||||
|
@ -36,9 +32,9 @@ To do this Click your profile icon --> Settings and privacy --> Mobile --> Sele
|
|||
}
|
||||
}
|
||||
}
|
||||
````
|
||||
```
|
||||
* environment variables:
|
||||
````
|
||||
HMD_TWITTER_CONSUMERKEY=esTCJFXXXXXXXXXXXXXXXXXXX
|
||||
HMD_TWITTER_CONSUMERSECRET=zpCs4tU86pRVXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
````
|
||||
```sh
|
||||
CMD_TWITTER_CONSUMERKEY=esTCJFXXXXXXXXXXXXXXXXXXX
|
||||
CMD_TWITTER_CONSUMERSECRET=zpCs4tU86pRVXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
```
|
||||
|
|
|
@ -12,7 +12,7 @@ require some creativity to work properly in your case. When I wrote this guide,
|
|||
[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
|
||||
[CodiMD 1.2.1]: https://github.com/codimd/server/tree/1.2.1
|
||||
|
||||
## 0. Requirements
|
||||
|
||||
|
@ -21,7 +21,7 @@ require some creativity to work properly in your case. When I wrote this guide,
|
|||
- running CodiMD server
|
||||
- [codimd-cli]
|
||||
|
||||
[codimd-cli]: https://github.com/hackmdio/codimd-cli/blob/master/bin/codimd
|
||||
[codimd-cli]: https://github.com/codimd/cli/blob/master/bin/codimd
|
||||
|
||||
## 1. Retrieve the list of pads
|
||||
|
||||
|
@ -57,7 +57,7 @@ configuration settings `ETHERPAD_SERVER` and `CODIMD_SERVER`.
|
|||
# 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
|
||||
# [1]: https://github.com/codimd/cli/blob/master/bin/codimd
|
||||
|
||||
# The base url to where etherpad is hosted
|
||||
ETHERPAD_SERVER="https://etherpad.example.com"
|
||||
|
|
52
docs/guides/migrations-and-breaking-changes.md
Normal file
|
@ -0,0 +1,52 @@
|
|||
Migrations and Notable Changes
|
||||
===
|
||||
|
||||
## 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,7 +1,7 @@
|
|||
Minio Guide for CodiMD
|
||||
===
|
||||
|
||||
***Note:** This guide was written before the renaming. Just replace `HackMD` with `CodiMD` in your mind :smile: thanks!*
|
||||
**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.
|
||||
|
||||
|
@ -9,7 +9,7 @@ Minio Guide for CodiMD
|
|||
production setup.
|
||||
|
||||
For checking it out and development purposes a non-persistent setup is enough:
|
||||
```console
|
||||
```sh
|
||||
docker run --name test-minio --rm -d -p 9000:9000 minio/minio server /data
|
||||
```
|
||||
|
||||
|
@ -18,29 +18,29 @@ Minio Guide for CodiMD
|
|||
|
||||
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)
|
||||
![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)
|
||||
![minio default view](../images/minio-image-upload/default-view.png)
|
||||
|
||||
4. Create a bucket for HackMD
|
||||
4. Create a bucket for CodiMD
|
||||
|
||||
![minio create bucket](images/minio-image-upload/create-bucket.png)
|
||||
![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)
|
||||
![minio edit policy](../images/minio-image-upload/open-edit-policy.png)
|
||||
*Open policy editor*
|
||||
|
||||
![minio policy adding](images/minio-image-upload/create-policy.png)
|
||||
![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`
|
||||
6. Set credentials and configs for Minio in CodiMD's `config.json`
|
||||
|
||||
```JSON
|
||||
"minio": {
|
||||
|
@ -58,7 +58,7 @@ Minio Guide for CodiMD
|
|||
7. Set bucket name
|
||||
|
||||
```JSON
|
||||
"s3bucket": "hackmd"
|
||||
"s3bucket": "codimd"
|
||||
```
|
||||
|
||||
8. Set upload type.
|
||||
|
@ -79,7 +79,7 @@ Minio Guide for CodiMD
|
|||
"port": 9000,
|
||||
"secure": false
|
||||
},
|
||||
"s3bucket": "hackmd",
|
||||
"s3bucket": "codimd",
|
||||
"imageuploadtype": "minio"
|
||||
}
|
||||
```
|
||||
|
|
|
@ -1,18 +1,19 @@
|
|||
# Guide - Setup CodiMD S3 image upload
|
||||
Guide - Setup CodiMD S3 image upload
|
||||
===
|
||||
|
||||
***Note:** This guide was written before the renaming. Just replace `HackMD` with `CodiMD` in your mind :smile: thanks!*
|
||||
**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)
|
||||
![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)
|
||||
![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)
|
||||
![bucket-policy-editor](../images/s3-image-upload/bucket-policy-editor.png)
|
||||
|
||||
```json
|
||||
{
|
||||
|
@ -32,15 +33,15 @@
|
|||
|
||||
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)
|
||||
![iam-user](../images/s3-image-upload/iam-user.png)
|
||||
|
||||
6. Select **Custom Policy**
|
||||
|
||||
![custom-policy](images/s3-image-upload/custom-policy.png)
|
||||
![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)
|
||||
![review-policy](../images/s3-image-upload/review-policy.png)
|
||||
|
||||
```json
|
||||
{
|
||||
|
@ -76,7 +77,7 @@
|
|||
}
|
||||
```
|
||||
|
||||
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).
|
||||
9. In additional to edit `config.json` directly, you could also try [environment variables](../configuration-env-vars.md).
|
||||
|
||||
## Related Tools
|
||||
|
||||
|
|
40
docs/history.md
Normal file
|
@ -0,0 +1,40 @@
|
|||
History of CodiMD
|
||||
===
|
||||
|
||||
## 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/codimd/server/issues/10).*
|
BIN
docs/images/CodiMD-1.3.2-features.png
Normal file
After Width: | Height: | Size: 80 KiB |
Before Width: | Height: | Size: 120 KiB After Width: | Height: | Size: 120 KiB |
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 113 KiB After Width: | Height: | Size: 113 KiB |
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 44 KiB |
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 5.5 KiB |
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 31 KiB |
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 61 KiB |
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 46 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 40 KiB |
Before Width: | Height: | Size: 234 KiB After Width: | Height: | Size: 234 KiB |
Before Width: | Height: | Size: 120 KiB After Width: | Height: | Size: 120 KiB |
Before Width: | Height: | Size: 180 KiB After Width: | Height: | Size: 180 KiB |
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 72 KiB |
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 60 KiB |
Before Width: | Height: | Size: 198 KiB After Width: | Height: | Size: 198 KiB |
Before Width: | Height: | Size: 187 KiB After Width: | Height: | Size: 187 KiB |
Before Width: | Height: | Size: 159 KiB After Width: | Height: | Size: 159 KiB |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 72 KiB |
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 53 KiB |
Before Width: | Height: | Size: 70 KiB After Width: | Height: | Size: 70 KiB |
Before Width: | Height: | Size: 69 KiB After Width: | Height: | Size: 69 KiB |
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 54 KiB |
Before Width: | Height: | Size: 89 KiB After Width: | Height: | Size: 89 KiB |
Before Width: | Height: | Size: 98 KiB After Width: | Height: | Size: 98 KiB |
6
docs/setup/cloudron.md
Normal file
|
@ -0,0 +1,6 @@
|
|||
Cloudron
|
||||
===
|
||||
|
||||
Install CodiMD on [Cloudron](https://cloudron.io):
|
||||
|
||||
[![Install](https://cloudron.io/img/button.svg)](https://cloudron.io/button.html?app=io.hackmd.cloudronapp)
|
23
docs/setup/docker.md
Normal file
|
@ -0,0 +1,23 @@
|
|||
CodiMD by docker container
|
||||
===
|
||||
|
||||
[![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
|
||||
cd codimd-container
|
||||
docker-compose up
|
||||
```
|
||||
Read more about it in the [container repository](https://github.com/codimd/container).
|
7
docs/setup/heroku.md
Normal file
|
@ -0,0 +1,7 @@
|
|||
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)
|
6
docs/setup/kubernetes.md
Normal file
|
@ -0,0 +1,6 @@
|
|||
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).
|
39
docs/setup/manual-setup.md
Normal file
|
@ -0,0 +1,39 @@
|
|||
Manual Installation
|
||||
===
|
||||
|
||||
## Requirements on your server
|
||||
|
||||
- Node.js 6.x or up (test up to 7.5.0) and <10.x
|
||||
- Database (PostgreSQL, MySQL, MariaDB, SQLite, MSSQL) use charset `utf8`
|
||||
- npm (and its dependencies, [node-gyp](https://github.com/nodejs/node-gyp#installation))
|
||||
- `libssl-dev` for building scrypt (see [here](https://github.com/ml1nk/node-scrypt/blob/master/README.md#installation-instructions) for further information)
|
||||
- For **building** CodiMD we recommend to use a machine with at least **2GB** RAM
|
||||
|
||||
|
||||
## Instructions
|
||||
|
||||
1. Download a release and unzip or clone into a directory
|
||||
2. Enter the directory and type `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 configs, see more below
|
||||
4. Setup environment variables which will overwrite the configs
|
||||
5. Build front-end bundle by `npm run build` (use `npm run dev` if you are in development)
|
||||
6. 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`
|
||||
7. Run `node_modules/.bin/sequelize db:migrate`, this step will migrate your db to the latest schema
|
||||
8. Run the server as you like (node, forever, pm2)
|
||||
|
||||
|
||||
## How to upgrade your installation
|
||||
|
||||
:warning: When you are still running from the old repository, please run: `git remote set-url origin https://github.com/codimd/server.git` :warning:
|
||||
|
||||
If you are upgrading CodiMD from an older version, follow these steps:
|
||||
|
||||
1. Fully stop your old server first (important)
|
||||
2. `git pull` or do whatever that updates the files
|
||||
3. `npm install` to update dependencies
|
||||
4. Build front-end bundle by `npm run build` (use `npm run dev` if you are in development)
|
||||
5. 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`
|
||||
6. Run `node_modules/.bin/sequelize db:migrate`, this step will migrate your db to the latest schema
|
||||
7. Start your whole new server!
|
161
docs/slide-options.md
Normal file
|
@ -0,0 +1,161 @@
|
|||
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
|
||||
|
||||
---
|
||||
```
|
|
@ -58,8 +58,11 @@ module.exports = {
|
|||
heartbeatTimeout: 10000,
|
||||
// document
|
||||
documentMaxLength: 100000,
|
||||
// image upload setting, available options are imgur/s3/filesystem/azure
|
||||
// image upload setting, available options are imgur/s3/filesystem/azure/lutim
|
||||
imageUploadType: 'filesystem',
|
||||
lutim: {
|
||||
url: 'https://framapic.org/'
|
||||
},
|
||||
imgur: {
|
||||
clientID: undefined
|
||||
},
|
||||
|
@ -138,6 +141,7 @@ module.exports = {
|
|||
idpCert: undefined,
|
||||
issuer: undefined,
|
||||
identifierFormat: 'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress',
|
||||
disableRequestedAuthnContext: false,
|
||||
groupAttribute: undefined,
|
||||
externalGroups: [],
|
||||
requiredGroups: [],
|
||||
|
|
|
@ -49,6 +49,9 @@ module.exports = {
|
|||
secure: toBooleanConfig(process.env.CMD_MINIO_SECURE),
|
||||
port: toIntegerConfig(process.env.CMD_MINIO_PORT)
|
||||
},
|
||||
lutim: {
|
||||
url: process.env.CMD_LUTIM_URL
|
||||
},
|
||||
s3bucket: process.env.CMD_S3_BUCKET,
|
||||
azure: {
|
||||
connectionString: process.env.CMD_AZURE_CONNECTION_STRING,
|
||||
|
@ -115,6 +118,7 @@ module.exports = {
|
|||
idpCert: process.env.CMD_SAML_IDPCERT,
|
||||
issuer: process.env.CMD_SAML_ISSUER,
|
||||
identifierFormat: process.env.CMD_SAML_IDENTIFIERFORMAT,
|
||||
disableRequestedAuthnContext: toBooleanConfig(process.env.CMD_SAML_DISABLEREQUESTEDAUTHNCONTEXT),
|
||||
groupAttribute: process.env.CMD_SAML_GROUPATTRIBUTE,
|
||||
externalGroups: toArrayConfig(process.env.CMD_SAML_EXTERNALGROUPS, '|', []),
|
||||
requiredGroups: toArrayConfig(process.env.CMD_SAML_REQUIREDGROUPS, '|', []),
|
||||
|
|
|
@ -109,6 +109,7 @@ module.exports = {
|
|||
idpCert: process.env.HMD_SAML_IDPCERT,
|
||||
issuer: process.env.HMD_SAML_ISSUER,
|
||||
identifierFormat: process.env.HMD_SAML_IDENTIFIERFORMAT,
|
||||
disableRequestedAuthnContext: toBooleanConfig(process.env.HMD_SAML_DISABLEREQUESTEDAUTHNCONTEXT),
|
||||
groupAttribute: process.env.HMD_SAML_GROUPATTRIBUTE,
|
||||
externalGroups: toArrayConfig(process.env.HMD_SAML_EXTERNALGROUPS, '|', []),
|
||||
requiredGroups: toArrayConfig(process.env.HMD_SAML_REQUIREDGROUPS, '|', []),
|
||||
|
|
|
@ -152,7 +152,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://github.com/codimd/server#environment-variables-will-overwrite-other-server-configs')
|
||||
}
|
||||
|
||||
// Generate session secret if it stays on default values
|
||||
|
@ -164,8 +164,8 @@ if (config.sessionSecret === 'secret') {
|
|||
}
|
||||
|
||||
// Validate upload upload providers
|
||||
if (['filesystem', 's3', 'minio', 'imgur', 'azure'].indexOf(config.imageUploadType) === -1) {
|
||||
logger.error('"imageuploadtype" is not correctly set. Please use "filesystem", "s3", "minio", "azure" or "imgur". Defaulting to "filesystem"')
|
||||
if (['filesystem', 's3', 'minio', 'imgur', 'azure', 'lutim'].indexOf(config.imageUploadType) === -1) {
|
||||
logger.error('"imageuploadtype" is not correctly set. Please use "filesystem", "s3", "minio", "azure", "lutim" or "imgur". Defaulting to "filesystem"')
|
||||
config.imageUploadType = 'filesystem'
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ exports.generateAvatarURL = function (name, email = '', big = true) {
|
|||
let hexDigest = hash.digest('hex')
|
||||
|
||||
if (email !== '' && config.allowGravatar) {
|
||||
photo = 'https://www.gravatar.com/avatar/' + hexDigest;
|
||||
photo = 'https://cdn.libravatar.org/avatar/' + hexDigest;
|
||||
if (big) {
|
||||
photo += '?s=400'
|
||||
} else {
|
||||
|
|
|
@ -427,7 +427,7 @@ function publishNoteActions (req, res, next) {
|
|||
actionDownload(req, res, note)
|
||||
break
|
||||
case 'edit':
|
||||
res.redirect(config.serverURL + '/' + (note.alias ? note.alias : models.Note.encodeNoteId(note.id)))
|
||||
res.redirect(config.serverURL + '/' + (note.alias ? note.alias : models.Note.encodeNoteId(note.id)) + '?both')
|
||||
break
|
||||
default:
|
||||
res.redirect(config.serverURL + '/s/' + note.shortid)
|
||||
|
@ -441,7 +441,7 @@ function publishSlideActions (req, res, next) {
|
|||
var action = req.params.action
|
||||
switch (action) {
|
||||
case 'edit':
|
||||
res.redirect(config.serverURL + '/' + (note.alias ? note.alias : models.Note.encodeNoteId(note.id)))
|
||||
res.redirect(config.serverURL + '/' + (note.alias ? note.alias : models.Note.encodeNoteId(note.id)) + '?both')
|
||||
break
|
||||
default:
|
||||
res.redirect(config.serverURL + '/p/' + note.shortid)
|
||||
|
|
|
@ -17,7 +17,8 @@ passport.use(new SamlStrategy({
|
|||
entryPoint: config.saml.idpSsoUrl,
|
||||
issuer: config.saml.issuer || config.serverURL,
|
||||
cert: fs.readFileSync(config.saml.idpCert, 'utf-8'),
|
||||
identifierFormat: config.saml.identifierFormat
|
||||
identifierFormat: config.saml.identifierFormat,
|
||||
disableRequestedAuthnContext: config.saml.disableRequestedAuthnContext
|
||||
}, function (user, done) {
|
||||
// check authorization if needed
|
||||
if (config.saml.externalGroups && config.saml.groupAttribute) {
|
||||
|
|
31
lib/web/imageRouter/lutim.js
Normal file
|
@ -0,0 +1,31 @@
|
|||
'use strict'
|
||||
const config = require('../../config')
|
||||
const logger = require('../../logger')
|
||||
|
||||
const lutim = require('lutim')
|
||||
|
||||
exports.uploadImage = function (imagePath, callback) {
|
||||
if (!imagePath || typeof imagePath !== 'string') {
|
||||
callback(new Error('Image path is missing or wrong'), null)
|
||||
return
|
||||
}
|
||||
|
||||
if (!callback || typeof callback !== 'function') {
|
||||
logger.error('Callback has to be a function')
|
||||
return
|
||||
}
|
||||
|
||||
if (config.lutim && config.lutim.url) {
|
||||
lutim.setAPIUrl(config.lutim.url)
|
||||
}
|
||||
|
||||
lutim.uploadImage(imagePath)
|
||||
.then(function (json) {
|
||||
if (config.debug) {
|
||||
logger.info('SERVER uploadimage success: ' + JSON.stringify(json))
|
||||
}
|
||||
callback(null, lutim.getAPIUrl() + json.msg.short)
|
||||
}).catch(function (err) {
|
||||
callback(new Error(err), null)
|
||||
})
|
||||
}
|
|
@ -40,7 +40,9 @@ exports.uploadImage = function (imagePath, callback) {
|
|||
callback(new Error(err), null)
|
||||
return
|
||||
}
|
||||
callback(null, `${protocol}://${config.minio.endPoint}:${config.minio.port}/${config.s3bucket}/${key}`)
|
||||
let hidePort = [80, 443].includes(config.minio.port)
|
||||
let urlPort = hidePort ? '' : `:${config.minio.port}`
|
||||
callback(null, `${protocol}://${config.minio.endPoint}${urlPort}/${config.s3bucket}/${key}`)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
|
|
@ -29,8 +29,8 @@
|
|||
"Import from browser": "Importuj z przeglądarki",
|
||||
"Releases": "Wydania",
|
||||
"Are you sure?": "Jesteś pewny?",
|
||||
"Do you really want to delete this note?": "Do you really want to delete this note?",
|
||||
"All users will lose their connection.": "All users will lose their connection.",
|
||||
"Do you really want to delete this note?": "Czy chcesz usunąć tą notatkę?",
|
||||
"All users will lose their connection.": "Wszyscy użytkownicy stracą swoje połączenie.",
|
||||
"Cancel": "Anuluj",
|
||||
"Yes, do it!": "Tak, zrób to!",
|
||||
"Choose method": "Wybierz metodę",
|
||||
|
@ -62,7 +62,7 @@
|
|||
"Refresh": "Odśwież",
|
||||
"Contacts": "Kontakty",
|
||||
"Report an issue": "Zgłoś błąd",
|
||||
"Meet us on %s": "Meet us on %s",
|
||||
"Meet us on %s": "Spotkaj się z nami na %s",
|
||||
"Send us email": "Wyślij nam email",
|
||||
"Documents": "Dokumenty",
|
||||
"Features": "Funkcje",
|
||||
|
@ -104,12 +104,16 @@
|
|||
"OR": "LUB",
|
||||
"Export to Snippet": "Eksportuj do Snippet",
|
||||
"Select Visibility Level": "Wybierz poziom widoczności",
|
||||
"Night Theme": "Night Theme",
|
||||
"Follow us on %s and %s.": "Follow us on %s, and %s.",
|
||||
"Privacy": "Privacy",
|
||||
"Terms of Use": "Terms of Use",
|
||||
"Do you really want to delete your user account?": "Do you really want to delete your user account?",
|
||||
"This will delete your account, all notes that are owned by you and remove all references to your account from other notes.": "This will delete your account, all notes that are owned by you and remove all references to your account from other notes.",
|
||||
"Delete user": "Delete user",
|
||||
"Export user data": "Export user data"
|
||||
"Night Theme": "Motyw Nocny",
|
||||
"Follow us on %s and %s.": "Znajdź nas na %s oraz %s.",
|
||||
"Privacy": "Prywatność",
|
||||
"Terms of Use": "Warunki korzystania",
|
||||
"Do you really want to delete your user account?": "Czy chcesz usunąć swoje konto użytkownika?",
|
||||
"This will delete your account, all notes that are owned by you and remove all references to your account from other notes.": "Ta akcja usunie twoje konto, wszystkie notatki które posiadasz oraz wszystkie referencje do tego konta w twoich pozostałych notatkach.",
|
||||
"Delete user": "Usuń użytkownika",
|
||||
"Export user data": "Eksportuj dane użytkownika",
|
||||
"Help us translating on %s": "Pomóż nam przetłumaczyć na język %s",
|
||||
"Source Code": "Kod źródłowy",
|
||||
"Register": "Zarejestruj",
|
||||
"Powered by %s": "Wspierany przez %s"
|
||||
}
|
|
@ -34,7 +34,7 @@
|
|||
"Cancel": "Одустани",
|
||||
"Yes, do it!": "Да, уради!",
|
||||
"Choose method": "Изаберите начин",
|
||||
"Sign in via %s": "Пријавите се помоћу %s",
|
||||
"Sign in via %s": "Пријави се уз %s",
|
||||
"New": "Ново",
|
||||
"Publish": "Објави",
|
||||
"Extra": "Додатно",
|
||||
|
@ -113,5 +113,7 @@
|
|||
"Delete user": "Брисање корисника",
|
||||
"Export user data": "Извоз свих корисничких података",
|
||||
"Help us translating on %s": "Помозите нам да преведемо на %s",
|
||||
"Source Code": "Изворни код"
|
||||
"Source Code": "Изворни код",
|
||||
"Register": "Региструј се",
|
||||
"Powered by %s": "Покреће %s"
|
||||
}
|
23
package.json
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "CodiMD",
|
||||
"version": "1.3.1",
|
||||
"version": "1.3.2",
|
||||
"description": "Realtime collaborative markdown notes on all platforms.",
|
||||
"main": "app.js",
|
||||
"license": "AGPL-3.0",
|
||||
|
@ -10,10 +10,9 @@
|
|||
"jsonlint": "find . -not -path './node_modules/*' -type f -name '*.json' -o -type f -name '*.json.example' | while read json; do echo $json ; jq . $json; done",
|
||||
"standard": "echo 'standard is no longer being used, use `npm run eslint` instead!' && exit 1",
|
||||
"dev": "webpack --config webpack.dev.js --progress --colors --watch",
|
||||
"heroku-prebuild": "bin/heroku",
|
||||
"build": "webpack --config webpack.prod.js --progress --colors --bail",
|
||||
"postinstall": "bin/heroku",
|
||||
"start": "sequelize db:migrate && node app.js",
|
||||
"doctoc": "doctoc --title='# Table of Contents' README.md"
|
||||
"start": "sequelize db:migrate && node app.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@hackmd/js-sequence-diagrams": "^0.0.1-alpha.2",
|
||||
|
@ -57,12 +56,14 @@
|
|||
"jquery-mousewheel": "^3.1.13",
|
||||
"jquery-ui": "^1.12.1",
|
||||
"js-cookie": "^2.1.3",
|
||||
"js-sequence-diagrams": "git+https://github.com/codimd/js-sequence-diagrams.git",
|
||||
"js-url": "^2.3.0",
|
||||
"js-yaml": "^3.7.0",
|
||||
"js-yaml": "^3.13.1",
|
||||
"jsdom-nogyp": "^0.8.3",
|
||||
"keymaster": "^1.6.2",
|
||||
"list.js": "^1.5.0",
|
||||
"lodash": "^4.17.11",
|
||||
"lutim": "^1.0.2",
|
||||
"lz-string": "git+https://github.com/hackmdio/lz-string.git",
|
||||
"markdown-it": "^8.2.2",
|
||||
"markdown-it-abbr": "^1.0.4",
|
||||
|
@ -140,7 +141,7 @@
|
|||
"engines": {
|
||||
"node": ">=6.x"
|
||||
},
|
||||
"bugs": "https://github.com/hackmdio/codimd/issues",
|
||||
"bugs": "https://github.com/codimd/server/issues",
|
||||
"keywords": [
|
||||
"Collaborative",
|
||||
"Markdown",
|
||||
|
@ -149,17 +150,18 @@
|
|||
"homepage": "https://codimd.org",
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "Max Wu",
|
||||
"email": "jackymaxj@gmail.com"
|
||||
"name": "Claudius Coenen",
|
||||
"url": "https://www.claudiuscoenen.de/"
|
||||
},
|
||||
{
|
||||
"name": "Christoph (Sheogorath) Kern",
|
||||
"email": "codimd@sheogorath.shivering-isles.com"
|
||||
"email": "codimd@sheogorath.shivering-isles.com",
|
||||
"url": "https://shivering-isles.com"
|
||||
}
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/hackmdio/codimd.git"
|
||||
"url": "https://github.com/codimd/server.git"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-cli": "^6.26.0",
|
||||
|
@ -171,7 +173,6 @@
|
|||
"babel-runtime": "^6.26.0",
|
||||
"copy-webpack-plugin": "^4.5.2",
|
||||
"css-loader": "^1.0.0",
|
||||
"doctoc": "^1.4.0",
|
||||
"ejs-loader": "^0.3.1",
|
||||
"eslint": "^5.9.0",
|
||||
"eslint-config-standard": "^12.0.0",
|
||||
|
|
|
@ -385,7 +385,7 @@ div[contenteditable]:empty:not(:focus):before{
|
|||
color: #eee;
|
||||
}
|
||||
|
||||
.night .btn.btn-default.ui-view.active{
|
||||
.night .btn.btn-default.active{
|
||||
background: #202020;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,131 +1,138 @@
|
|||
Features
|
||||
===
|
||||
# Features
|
||||
|
||||
## Introduction
|
||||
|
||||
Introduction
|
||||
===
|
||||
<i class="fa fa-file-text"></i> **CodiMD** is a real-time, multi-platform collaborative markdown note editor.
|
||||
This means that you can write notes with other people on your **desktop**, **tablet** or even on the **phone**.
|
||||
You can sign-in via multiple auth providers like **Facebook**, **Twitter**, **GitHub** and many more on the [_homepage_](/).
|
||||
|
||||
If you experience any _issues_, feel free to report it on [**GitHub**](https://github.com/hackmdio/codimd/issues).
|
||||
If you experience any _issues_, feel free to report it on [**GitHub**](https://github.com/codimd/server/issues).
|
||||
Or meet us on [**Matrix.org**](https://riot.im/app/#/room/#codimd:matrix.org) for dev-talk and interactive help.
|
||||
**Thank you very much!**
|
||||
|
||||
Workspace
|
||||
===
|
||||
## Modes
|
||||
**Desktop & Tablet**
|
||||
## Workspace
|
||||
|
||||
### Modes
|
||||
|
||||
#### Desktop & Tablet
|
||||
|
||||
<i class="fa fa-edit fa-fw"></i> Edit: See only the editor.
|
||||
<i class="fa fa-eye fa-fw"></i> View: See only the result.
|
||||
<i class="fa fa-columns fa-fw"></i> Both: See both in split view.
|
||||
<i class="fa fa-columns fa-fw"></i> Both: See editor and result at the same time.
|
||||
<i class="fa fa-pencil fa-fw"></i> Edit: See only the editor.
|
||||
|
||||
**Mobile**
|
||||
#### Mobile
|
||||
|
||||
<i class="fa fa-toggle-on fa-fw"></i> View: See only the result.
|
||||
<i class="fa fa-toggle-off fa-fw"></i> Edit: See only the editor.
|
||||
<i class="fa fa-eye fa-fw"></i> View: See only the result.
|
||||
<i class="fa fa-pencil fa-fw"></i> Edit: See only the editor.
|
||||
|
||||
### Night Mode
|
||||
|
||||
## Night Mode:
|
||||
When you are tired of a white screen and like a night mode, click on the little moon <i class="fa fa-moon-o"></i> and turn on the night view of CodiMD.
|
||||
|
||||
The editor view, which is in night mode by default, can also be toggled between night and day view using the the little sun<i class="fa fa-sun-o fa-fw"></i>.
|
||||
|
||||
## Image Upload:
|
||||
You can upload an image simply by clicking on the camera button <i class="fa fa-camera"></i>.
|
||||
### Image Upload
|
||||
|
||||
You can upload an image simply by clicking on the upload button <i class="fa fa-upload"></i>.
|
||||
Alternatively, you can **drag-n-drop** an image into the editor. Even **pasting** images is possible!
|
||||
This will automatically upload the image to **[imgur](http://imgur.com)**, **[Amazon S3](https://aws.amazon.com/s3/)**, **[Minio](https://minio.io)** or **local filesystem**, nothing to worry about. :tada:
|
||||
This will automatically upload the image to **[imgur](http://imgur.com)**, **[Amazon S3](https://aws.amazon.com/s3/)**, **[Minio](https://minio.io)** or the **local filesystem** (depending on the instance's configuration), nothing to worry about. :tada:
|
||||
|
||||
![imgur](https://i.imgur.com/9cgQVqD.png)
|
||||
|
||||
## Share Notes:
|
||||
### Share Notes
|
||||
|
||||
If you want to share an **editable** note, just copy the URL.
|
||||
If you want to share a **read-only** note, simply press publish button <i class="fa fa-share-square-o"></i> and copy the URL.
|
||||
If you want to share a **read-only** note, simply press the publish button <i class="fa fa-share-square-o"></i> and copy the URL.
|
||||
|
||||
## Save a Note:
|
||||
Currently, you can save to **Dropbox** <i class="fa fa-dropbox"></i> or save an `.md` file <i class="fa fa-file-text"></i> locally.
|
||||
### Save a Note
|
||||
|
||||
## Import Notes:
|
||||
Similarly to the _save_ feature, you can also import an `.md` file from **Dropbox** <i class="fa fa-dropbox"></i>,
|
||||
or import content from your **clipboard** <i class="fa fa-clipboard"></i>, and that can parse some **html** which might be useful :smiley:
|
||||
Currently, you can save to **Dropbox** <i class="fa fa-dropbox"></i> (depending on the instance's configuration) or save a Markdown <i class="fa fa-file-text"></i>, HTML or raw HTML <i class="fa fa-file-code-o"></i> file locally.
|
||||
|
||||
## Permissions:
|
||||
It is possible to change the access permission to a note through the little button on the top right of the view.
|
||||
### Import Notes
|
||||
|
||||
Similarly to the _save_ feature, you can also import a Markdown file from **Dropbox** <i class="fa fa-dropbox"></i> (depending on the instance's configuration), or import content from your **clipboard** <i class="fa fa-clipboard"></i>, which can parse some HTML. :smiley:
|
||||
|
||||
### Permissions
|
||||
|
||||
It is possible to change the access permission of a note through the little button on the top right of the view.
|
||||
There are four possible options:
|
||||
|
||||
| |Owner read/write|Signed-in read|Signed-in write|Guest read|Guest write|
|
||||
|:-----------------------------|:--------------:|:------------:|:-------------:|:--------:|:---------:|
|
||||
|<span class="text-nowrap"><i class="fa fa-leaf fa-fw"></i> **Freely**</span> |✔|✔|✔|✔|✔|
|
||||
|<span class="text-nowrap"><i class="fa fa-pencil fa-fw"></i> **Editable**</span> |✔|✔|✔|✔|✖|
|
||||
|<span class="text-nowrap"><i class="fa fa-id-card fa-fw"></i> **Limited**</span> |✔|✔|✔|✖|✖|
|
||||
|<span class="text-nowrap"><i class="fa fa-lock fa-fw"></i> **Locked**</span> |✔|✔|✖|✔|✖|
|
||||
|<span class="text-nowrap"><i class="fa fa-umbrella fa-fw"></i> **Protected**</span> |✔|✔|✖|✖|✖|
|
||||
|<span class="text-nowrap"><i class="fa fa-hand-stop-o fa-fw"></i> **Private**</span> |✔|✖|✖|✖|✖|
|
||||
|
||||
|<span class="text-nowrap"><i class="fa fa-leaf fa-fw"></i> **Freely**</span>|✔|✔|✔|✔|✔|
|
||||
|<span class="text-nowrap"><i class="fa fa-pencil fa-fw"></i> **Editable**</span>|✔|✔|✔|✔|✖|
|
||||
|<span class="text-nowrap"><i class="fa fa-id-card fa-fw"></i> **Limited**</span>|✔|✔|✔|✖|✖|
|
||||
|<span class="text-nowrap"><i class="fa fa-lock fa-fw"></i> **Locked**</span>|✔|✔|✖|✔|✖|
|
||||
|<span class="text-nowrap"><i class="fa fa-umbrella fa-fw"></i> **Protected**</span>|✔|✔|✖|✖|✖|
|
||||
|<span class="text-nowrap"><i class="fa fa-hand-stop-o fa-fw"></i> **Private**</span>|✔|✖|✖|✖|✖|
|
||||
|
||||
**Only the owner of the note can change the note's permissions.**
|
||||
|
||||
## Embed a Note:
|
||||
### Embed a Note
|
||||
|
||||
Notes can be embedded as follows:
|
||||
|
||||
```xml
|
||||
<iframe width="100%" height="500" src="https://hackmd.io/features" frameborder="0"></iframe>
|
||||
<iframe width="100%" height="500" src="https://demo.codimd.io/features" frameborder="0"></iframe>
|
||||
```
|
||||
|
||||
## [Slide Mode](./slide-example):
|
||||
### [Slide Mode](./slide-example)
|
||||
|
||||
You can use a special syntax to organize your note into slides.
|
||||
After that, you can use the **[Slide Mode](./slide-example)** <i class="fa fa-tv"></i> to make a presentation.
|
||||
Visit the above link for details.
|
||||
|
||||
To switch the editor into slide mode, set the [document type](./yaml-metadata#type) to `slide`.
|
||||
|
||||
View
|
||||
===
|
||||
## Table of Contents:
|
||||
## View
|
||||
|
||||
### Autogenerated Table of Contents
|
||||
|
||||
You can look at the bottom right section of the view area, there is a _ToC_ button <i class="fa fa-bars"></i>.
|
||||
Pressing that button will show you a current _Table of Contents_, and will highlight which section you're at.
|
||||
ToCs support up to **three header levels**.
|
||||
|
||||
## Permalink
|
||||
### Permalink
|
||||
|
||||
Every header will automatically add a permalink on the right side.
|
||||
You can hover and click <i class="fa fa-chain"></i> to anchor on it.
|
||||
|
||||
Edit:
|
||||
===
|
||||
## Editor Modes:
|
||||
You can look in the bottom right section of the editor area, there you'll find a button with `sublime` on it.
|
||||
When you click it, you can select 3 editor modes:
|
||||
## Edit
|
||||
|
||||
- sublime (default)
|
||||
- emacs
|
||||
- vim
|
||||
### Editor Modes
|
||||
|
||||
## Shortcut Keys:
|
||||
The shortcut keys depend on your selected editor mode. By default they are just like Sublime text, which is pretty quick and convenient.
|
||||
> For more information, see [here](https://codemirror.net/demo/sublime.html).
|
||||
You can look in the bottom right section of the editor area, there you'll find a button with `SUBLIME` on it.
|
||||
When you click it, you can select 3 editor modes, which will also define your shortcut keys:
|
||||
|
||||
For emacs:
|
||||
> For more information, see [here](https://codemirror.net/demo/emacs.html).
|
||||
- [Sublime](https://codemirror.net/demo/sublime.html) (default)
|
||||
- [Emacs](https://codemirror.net/demo/emacs.html)
|
||||
- [Vim](https://codemirror.net/demo/vim.html)
|
||||
|
||||
For vim:
|
||||
> For more information, see [here](https://codemirror.net/demo/vim.html).
|
||||
### Auto-Complete
|
||||
|
||||
## Auto-Complete:
|
||||
This editor provides full auto-complete hints in markdown.
|
||||
|
||||
- Emojis: type `:` to show hints.
|
||||
- Code blocks: type ` ``` ` and plus a character to show hint. <i hidden>```</i>
|
||||
- Code blocks: type ` ``` `, followed by another character to show syntax highlighting suggestions.
|
||||
- Headers: type `#` to show hint.
|
||||
- Referrals: type `[]` to show hint.
|
||||
- Externals: type `{}` to show hint.
|
||||
- Images: type `!` to show hint.
|
||||
|
||||
## Title:
|
||||
This will take the first **level 1 header** as the note title.
|
||||
### Title
|
||||
|
||||
The first **level 1 heading** (e.g. `# Title`) will be used as the note title.
|
||||
|
||||
### Tags
|
||||
|
||||
## Tags:
|
||||
Using tags as follows, the specified tags will show in your **history**.
|
||||
|
||||
###### tags: `features` `cool` `updated`
|
||||
|
||||
## [YAML Metadata](./yaml-metadata)
|
||||
### [YAML Metadata](./yaml-metadata)
|
||||
|
||||
You can provide advanced note information to set the browser behavior (visit above link for details):
|
||||
|
||||
- robots: set web robots meta
|
||||
- lang: set browser language
|
||||
- dir: set text direction
|
||||
|
@ -134,23 +141,30 @@ You can provide advanced note information to set the browser behavior (visit abo
|
|||
- disqus: set to use Disqus
|
||||
- slideOptions: setup slide mode options
|
||||
|
||||
## ToC:
|
||||
Use the syntax `[TOC]` to embed table of content into your note.
|
||||
### Table of Contents
|
||||
|
||||
Use the syntax `[TOC]` to embed a table of contents into your note.
|
||||
|
||||
[TOC]
|
||||
|
||||
## Emoji
|
||||
### Emoji
|
||||
|
||||
You can type any emoji like this :smile: :smiley: :cry: :wink:
|
||||
|
||||
> See full emoji list [here](http://www.emoji-cheat-sheet.com/).
|
||||
|
||||
## ToDo List:
|
||||
### ToDo List
|
||||
|
||||
- [ ] ToDos
|
||||
- [x] Buy some salad
|
||||
- [ ] Brush teeth
|
||||
- [x] Drink some water
|
||||
- [ ] **Click my box** and see the source code, if you're allowed to edit!
|
||||
|
||||
### Code Block
|
||||
|
||||
## Code Block:
|
||||
We support many programming languages, use the auto complete function to see the entire list.
|
||||
|
||||
```javascript=
|
||||
var s = "JavaScript syntax highlighting";
|
||||
alert(s);
|
||||
|
@ -168,9 +182,11 @@ function $initHighlight(block, cls) {
|
|||
}
|
||||
}
|
||||
```
|
||||
> If you want **line numbers**, type `=` after specifying the code block languagues.
|
||||
> Also, you can specify the start line number.
|
||||
> Like below, the line number starts from 101:
|
||||
|
||||
If you want **line numbers**, type `=` after specifying the code block languagues.
|
||||
Also, you can specify the start line number.
|
||||
Like below, the line number starts from 101:
|
||||
|
||||
```javascript=101
|
||||
var s = "JavaScript syntax highlighting";
|
||||
alert(s);
|
||||
|
@ -189,44 +205,50 @@ function $initHighlight(block, cls) {
|
|||
}
|
||||
```
|
||||
|
||||
> Or you might want to continue the previous code block's line number, use `=+`
|
||||
Or you might want to continue the previous code block's line number, use `=+`:
|
||||
|
||||
```javascript=+
|
||||
var s = "JavaScript syntax highlighting";
|
||||
alert(s);
|
||||
```
|
||||
|
||||
> Somtimes you have a super long text without breaks. It's time to use `!` to wrap your code.
|
||||
Somtimes you have a super long text without breaks. It's time to use `!` to wrap your code:
|
||||
|
||||
```!
|
||||
When you’re a carpenter making a beautiful chest of drawers, you’re not going to use a piece of plywood on the back.
|
||||
```
|
||||
|
||||
### Blockquote Tags:
|
||||
### Blockquote Tags
|
||||
|
||||
> Using the syntax below to specifiy your **name, time and color** to vary the blockquotes.
|
||||
> [name=ChengHan Wu] [time=Sun, Jun 28, 2015 9:59 PM] [color=#907bf7]
|
||||
> > Even support the nest blockquotes!
|
||||
> > [name=ChengHan Wu] [time=Sun, Jun 28, 2015 10:00 PM] [color=red]
|
||||
> > Even support nested blockquotes!
|
||||
> > [name=Max Mustermann] [time=Sun, Jun 28, 2015 9:47 PM] [color=red]
|
||||
|
||||
## Externals
|
||||
### Externals
|
||||
|
||||
#### YouTube
|
||||
|
||||
### YouTube
|
||||
{%youtube aqz-KE-bpKQ %}
|
||||
|
||||
### Vimeo
|
||||
#### Vimeo
|
||||
|
||||
{%vimeo 124148255 %}
|
||||
|
||||
### Gist
|
||||
#### Gist
|
||||
|
||||
{%gist schacon/4277%}
|
||||
|
||||
### SlideShare
|
||||
#### SlideShare
|
||||
|
||||
{%slideshare briansolis/26-disruptive-technology-trends-2016-2018-56796196 %}
|
||||
|
||||
### PDF
|
||||
#### PDF
|
||||
|
||||
**Caution: this might be blocked by your browser if not using an `https` URL.**
|
||||
{%pdf https://papers.nips.cc/paper/5346-sequence-to-sequence-learning-with-neural-networks.pdf %}
|
||||
|
||||
## MathJax
|
||||
### MathJax
|
||||
|
||||
You can render *LaTeX* mathematical expressions using **MathJax**, as on [math.stackexchange.com](http://math.stackexchange.com/):
|
||||
|
||||
|
@ -242,9 +264,9 @@ $$
|
|||
|
||||
> More information about **LaTeX** mathematical expressions [here](http://meta.math.stackexchange.com/questions/5020/mathjax-basic-tutorial-and-quick-reference).
|
||||
|
||||
## UML Diagrams
|
||||
### Diagrams
|
||||
|
||||
### Sequence Diagrams
|
||||
#### UML Sequence Diagrams
|
||||
|
||||
You can render sequence diagrams like this:
|
||||
|
||||
|
@ -256,9 +278,12 @@ Note left of Alice: Alice responds
|
|||
Alice->Bob: Where have you been?
|
||||
```
|
||||
|
||||
### Flow Charts
|
||||
More information about **sequence diagrams** syntax [here](http://bramp.github.io/js-sequence-diagrams/).
|
||||
|
||||
#### Flow Charts
|
||||
|
||||
Flow charts can be specified like this:
|
||||
|
||||
```flow
|
||||
st=>start: Start
|
||||
e=>end: End
|
||||
|
@ -271,36 +296,45 @@ cond(yes)->e
|
|||
cond(no)->op2
|
||||
```
|
||||
|
||||
### Graphviz
|
||||
More information about **flow charts** syntax [here](http://adrai.github.io/flowchart.js/).
|
||||
|
||||
#### Graphviz
|
||||
|
||||
```graphviz
|
||||
digraph hierarchy {
|
||||
nodesep=1.0 // Increases the separation between nodes
|
||||
|
||||
nodesep=1.0 // increases the separation between nodes
|
||||
node [color=Red,fontname=Courier,shape=box] // All nodes will this shape and colour
|
||||
edge [color=Blue, style=dashed] // All the lines look like this
|
||||
|
||||
node [color=Red,fontname=Courier,shape=box] //All nodes will this shape and colour
|
||||
edge [color=Blue, style=dashed] //All the lines look like this
|
||||
|
||||
Headteacher->{Deputy1 Deputy2 BusinessManager}
|
||||
Deputy1->{Teacher1 Teacher2}
|
||||
BusinessManager->ITManager
|
||||
{rank=same;ITManager Teacher1 Teacher2} // Put them on the same level
|
||||
Headteacher->{Deputy1 Deputy2 BusinessManager}
|
||||
Deputy1->{Teacher1 Teacher2}
|
||||
BusinessManager->ITManager
|
||||
{rank=same;ITManager Teacher1 Teacher2} // Put them on the same level
|
||||
}
|
||||
```
|
||||
|
||||
### Mermaid
|
||||
More information about **graphviz** syntax [here](http://www.tonyballantyne.com/graphs.html)
|
||||
|
||||
#### Mermaid
|
||||
|
||||
```mermaid
|
||||
gantt
|
||||
title A Gantt Diagram
|
||||
title A Gantt Diagram
|
||||
|
||||
section Section
|
||||
A task :a1, 2014-01-01, 30d
|
||||
Another task :after a1 , 20d
|
||||
section Another
|
||||
Task in sec :2014-01-12 , 12d
|
||||
anther task : 24d
|
||||
section Section
|
||||
A task: a1, 2014-01-01, 30d
|
||||
Another task: after a1, 20d
|
||||
|
||||
section Another
|
||||
Task in sec: 2014-01-12, 12d
|
||||
Another task: 24d
|
||||
```
|
||||
|
||||
### Abc
|
||||
More information about **mermaid** syntax [here](http://knsv.github.io/mermaid)
|
||||
|
||||
#### Abc Music Notation
|
||||
|
||||
```abc
|
||||
X:1
|
||||
T:Speed the Plough
|
||||
|
@ -313,14 +347,10 @@ GABc dedB|dedB dedB|c2ec B2dB|A2F2 G4:|
|
|||
g2gf g2Bd|g2f2 e2d2|c2ec B2dB|A2F2 G4:|
|
||||
```
|
||||
|
||||
> More information about **sequence diagrams** syntax [here](http://bramp.github.io/js-sequence-diagrams/).
|
||||
> More information about **flow charts** syntax [here](http://adrai.github.io/flowchart.js/).
|
||||
> More information about **graphviz** syntax [here](http://www.tonyballantyne.com/graphs.html)
|
||||
> More information about **mermaid** syntax [here](http://knsv.github.io/mermaid)
|
||||
> More information about **abc** syntax [here](http://abcnotation.com/learn)
|
||||
More information about **abc** syntax [here](http://abcnotation.com/learn)
|
||||
|
||||
### Alert Area
|
||||
|
||||
Alert Area
|
||||
---
|
||||
:::success
|
||||
Yes :tada:
|
||||
:::
|
||||
|
@ -337,11 +367,11 @@ Watch out :zap:
|
|||
Oh No! :fire:
|
||||
:::
|
||||
|
||||
## Typography
|
||||
### Typography
|
||||
|
||||
### Headers
|
||||
#### Headers
|
||||
|
||||
```
|
||||
``` markdown
|
||||
# h1 Heading
|
||||
## h2 Heading
|
||||
### h3 Heading
|
||||
|
@ -350,7 +380,7 @@ Oh No! :fire:
|
|||
###### h6 Heading
|
||||
```
|
||||
|
||||
### Horizontal Rules
|
||||
#### Horizontal Rules
|
||||
|
||||
___
|
||||
|
||||
|
@ -358,8 +388,7 @@ ___
|
|||
|
||||
***
|
||||
|
||||
|
||||
### Typographic Replacements
|
||||
#### Typographic Replacements
|
||||
|
||||
Enable typographer option to see result.
|
||||
|
||||
|
@ -375,7 +404,7 @@ Remarkable -- awesome
|
|||
|
||||
'Smartypants, single quotes'
|
||||
|
||||
### Emphasis
|
||||
#### Emphasis
|
||||
|
||||
**This is bold text**
|
||||
|
||||
|
@ -397,18 +426,15 @@ Subscript: H~2~O
|
|||
|
||||
==Marked text==
|
||||
|
||||
|
||||
### Blockquotes
|
||||
|
||||
#### Blockquotes
|
||||
|
||||
> Blockquotes can also be nested...
|
||||
>> ...by using additional greater-than signs right next to each other...
|
||||
> > > ...or with spaces between arrows.
|
||||
|
||||
#### Lists
|
||||
|
||||
### Lists
|
||||
|
||||
#### Unordered
|
||||
##### Unordered
|
||||
|
||||
+ Create a list by starting a line with `+`, `-`, or `*`
|
||||
+ Sub-lists are made by indenting 2 spaces:
|
||||
|
@ -418,27 +444,26 @@ Subscript: H~2~O
|
|||
- Nulla volutpat aliquam velit
|
||||
+ Very easy!
|
||||
|
||||
#### Ordered
|
||||
##### Ordered
|
||||
|
||||
1. Lorem ipsum dolor sit amet
|
||||
2. Consectetur adipiscing elit
|
||||
3. Integer molestie lorem at massa
|
||||
3. Aenean commodo ligula eget dolor
|
||||
|
||||
|
||||
1. You can use sequential numbers...
|
||||
1. ...or keep all the numbers as `1.`
|
||||
1. feafw
|
||||
2. 332
|
||||
3. 242
|
||||
4. 2552
|
||||
1. e2
|
||||
1. **You can use sequential numbers...**
|
||||
1. **...or keep all the numbers as `1.`**
|
||||
1. Aenean massa
|
||||
2. Cum sociis natoque penatibus
|
||||
3. Magnis dis parturient montes
|
||||
4. Nascetur ridiculus mus
|
||||
1. Donec quam felis
|
||||
|
||||
Start numbering with offset:
|
||||
|
||||
57. foo
|
||||
1. bar
|
||||
|
||||
### Code
|
||||
#### Code
|
||||
|
||||
Inline `code`
|
||||
|
||||
|
@ -449,7 +474,6 @@ Indented code
|
|||
line 2 of code
|
||||
line 3 of code
|
||||
|
||||
|
||||
Block code "fences"
|
||||
|
||||
```
|
||||
|
@ -466,7 +490,7 @@ var foo = function (bar) {
|
|||
console.log(foo(5));
|
||||
```
|
||||
|
||||
### Tables
|
||||
#### Tables
|
||||
|
||||
| Option | Description |
|
||||
| ------ | ----------- |
|
||||
|
@ -498,26 +522,28 @@ Center aligned columns
|
|||
| engine | engine to be used for processing templates. Handlebars is the default. |
|
||||
| ext | extension to be used for dest files. |
|
||||
|
||||
#### Links
|
||||
|
||||
### Links
|
||||
[link text](http://dev.nodeca.com)
|
||||
[link with title](http://nodeca.github.io/pica/demo/ "title text!")
|
||||
[link text](https://demo.codimd.org)
|
||||
[link with title](https://nodeca.github.io/pica/demo/ "title text!")
|
||||
Autoconverted link https://github.com/nodeca/pica
|
||||
|
||||
#### Images
|
||||
|
||||
### Images
|
||||
![Minion](https://octodex.github.com/images/minion.png)
|
||||
|
||||
With a title:
|
||||
![Stormtroopocat](https://octodex.github.com/images/stormtroopocat.jpg "The Stormtroopocat")
|
||||
Like links, Images also have a footnote style syntax
|
||||
![Alt text][id]
|
||||
With a reference later in the document defining the URL location:
|
||||
|
||||
[id]: https://octodex.github.com/images/dojocat.jpg "The Dojocat"
|
||||
Like links, images also have a footnote style syntax with a reference later in the document defining the URL location:
|
||||
![Dojocat][dojoref]
|
||||
|
||||
[dojoref]: https://octodex.github.com/images/dojocat.jpg "The Dojocat"
|
||||
|
||||
Show the image with given size:
|
||||
![Minion](https://octodex.github.com/images/minion.png =200x200)
|
||||
Show the image with given size
|
||||
|
||||
### Footnotes
|
||||
#### Footnotes
|
||||
|
||||
Footnote 1 link[^first].
|
||||
Footnote 2 link[^second].
|
||||
|
@ -528,7 +554,7 @@ Duplicated footnote reference[^second].
|
|||
and multiple paragraphs.
|
||||
[^second]: Footnote text.
|
||||
|
||||
### Definition Lists
|
||||
#### Definition Lists
|
||||
|
||||
Term 1
|
||||
|
||||
|
@ -552,7 +578,7 @@ Term 2
|
|||
~ Definition 2a
|
||||
~ Definition 2b
|
||||
|
||||
### Abbreviations
|
||||
#### Abbreviations
|
||||
|
||||
This is an HTML abbreviation example.
|
||||
It converts "HTML", but keeps intact partial entries like "xxxHTMLyyy" and so on.
|
||||
|
|
|
@ -1,6 +1,16 @@
|
|||
Release Notes
|
||||
===
|
||||
|
||||
<i class="fa fa-tag"></i> 1.3.2 <i class="fa fa-clock-o"></i> 2019-03-28 00:00
|
||||
---
|
||||
|
||||
### Announcement
|
||||
* CodiMD is now running in an own organization. [Check out our vision for the future](https://github.com/codimd/server/issues/10)
|
||||
|
||||
### Fixes
|
||||
* Update various links to the new repositories
|
||||
* Fix background color for mode switching button in night mode
|
||||
|
||||
<i class="fa fa-tag"></i> 1.3.1 <i class="fa fa-clock-o"></i> 2019-03-23 00:00
|
||||
---
|
||||
|
||||
|
@ -158,7 +168,7 @@ Release Notes
|
|||
|
||||
### Deprecations
|
||||
* NodeJS version 6
|
||||
* Mattermost login integration (is replaced by [generic oAuth2 module](https://github.com/hackmdio/codimd/blob/6ce7b20a7f92ccff2f7f870ff5d116d685310cfd/docs/guides/auth/mattermost-self-hosted.md))
|
||||
* Mattermost login integration (is replaced by [generic oAuth2 module](https://github.com/codimd/server/blob/6ce7b20a7f92ccff2f7f870ff5d116d685310cfd/docs/guides/auth/mattermost-self-hosted.md))
|
||||
|
||||
### Honorable mentions
|
||||
* [Alex Hesse (Pingu501)](https://github.com/Pingu501)
|
||||
|
@ -174,7 +184,7 @@ Release Notes
|
|||
---
|
||||
|
||||
### Announcement
|
||||
* HackMD CE is renamed to CodiMD to prevent confusion. [For details see here](https://github.com/hackmdio/codimd#hackmd-ce-became-codimd)
|
||||
* HackMD CE is renamed to CodiMD to prevent confusion. [For details see here](https://github.com/codimd/server/tree/master/docs/history.md)
|
||||
|
||||
### Enhancements
|
||||
* Show full title by hovering over to table of contents entries
|
||||
|
|
|
@ -304,7 +304,6 @@ var editor = editorInstance.init(textit)
|
|||
// FIXME: global referncing in jquery-textcomplete patch
|
||||
window.editor = editor
|
||||
|
||||
var inlineAttach = inlineAttachment.editors.codemirror4.attach(editor)
|
||||
defaultTextHeight = parseInt($('.CodeMirror').css('line-height'))
|
||||
|
||||
// initalize ui reference
|
||||
|
@ -801,7 +800,6 @@ function changeMode (type) {
|
|||
editor.getInputField().blur()
|
||||
}
|
||||
if (appState.currentMode === modeType.edit || appState.currentMode === modeType.both) {
|
||||
ui.toolbar.uploadImage.fadeIn()
|
||||
// add and update status bar
|
||||
if (!editorInstance.statusBar) {
|
||||
editorInstance.addStatusBar()
|
||||
|
@ -814,8 +812,6 @@ function changeMode (type) {
|
|||
// work around foldGutter might not init properly
|
||||
editor.setOption('foldGutter', false)
|
||||
editor.setOption('foldGutter', true)
|
||||
} else {
|
||||
ui.toolbar.uploadImage.fadeOut()
|
||||
}
|
||||
if (appState.currentMode !== modeType.edit) {
|
||||
$(document.body).css('background-color', 'white')
|
||||
|
@ -1051,17 +1047,6 @@ ui.toolbar.import.snippet.click(function () {
|
|||
ui.spinner.hide()
|
||||
})
|
||||
})
|
||||
// import from clipboard
|
||||
ui.toolbar.import.clipboard.click(function () {
|
||||
// na
|
||||
})
|
||||
// upload image
|
||||
ui.toolbar.uploadImage.bind('change', function (e) {
|
||||
var files = e.target.files || e.dataTransfer.files
|
||||
e.dataTransfer = {}
|
||||
e.dataTransfer.files = files
|
||||
inlineAttach.onDrop(e)
|
||||
})
|
||||
// toc
|
||||
ui.toc.dropdown.click(function (e) {
|
||||
e.stopPropagation()
|
||||
|
|
|
@ -138,6 +138,7 @@ export default class Editor {
|
|||
}
|
||||
|
||||
addToolBar () {
|
||||
var inlineAttach = inlineAttachment.editors.codemirror4.attach(this.editor)
|
||||
this.toolBar = $(toolBarTemplate)
|
||||
this.toolbarPanel = this.editor.addPanel(this.toolBar[0], {
|
||||
position: 'top'
|
||||
|
@ -157,6 +158,7 @@ export default class Editor {
|
|||
var makeTable = $('#makeTable')
|
||||
var makeLine = $('#makeLine')
|
||||
var makeComment = $('#makeComment')
|
||||
var uploadImage = $('#uploadImage')
|
||||
|
||||
makeBold.click(() => {
|
||||
utils.wrapTextWith(this.editor, this.editor, '**')
|
||||
|
@ -217,6 +219,13 @@ export default class Editor {
|
|||
makeComment.click(() => {
|
||||
utils.insertText(this.editor, '> []')
|
||||
})
|
||||
uploadImage.bind('change', function (e) {
|
||||
console.log("tiggered")
|
||||
var files = e.target.files || e.dataTransfer.files
|
||||
e.dataTransfer = {}
|
||||
e.dataTransfer.files = files
|
||||
inlineAttach.onDrop(e)
|
||||
})
|
||||
}
|
||||
|
||||
addStatusBar () {
|
||||
|
|
|
@ -34,6 +34,9 @@
|
|||
<a id="makeImage" class="btn btn-sm btn-dark text-uppercase" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false" title="Image">
|
||||
<i class="fa fa-image fa-fw"></i>
|
||||
</a>
|
||||
<span id="uploadImage" class="btn btn-sm btn-dark btn-file ui-upload-image" title="Upload Image">
|
||||
<i class="fa fa-upload fa-fw"></i><input type="file" accept="image/*" name="upload" multiple>
|
||||
</span>
|
||||
<a id="makeTable" class="btn btn-sm btn-dark text-uppercase" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false" title="Table">
|
||||
<i class="fa fa-table fa-fw"></i>
|
||||
</a>
|
||||
|
|
|
@ -35,8 +35,7 @@ export const getUIElements = () => ({
|
|||
edit: $('.ui-edit'),
|
||||
view: $('.ui-view'),
|
||||
both: $('.ui-both'),
|
||||
night: $('.ui-night'),
|
||||
uploadImage: $('.ui-upload-image')
|
||||
night: $('.ui-night')
|
||||
},
|
||||
infobar: {
|
||||
lastchange: $('.ui-lastchange'),
|
||||
|
|
Before Width: | Height: | Size: 233 KiB After Width: | Height: | Size: 222 KiB |
|
@ -15,9 +15,6 @@
|
|||
</div>
|
||||
<a class="navbar-brand pull-left" href="<%- serverURL %>/"><i class="fa fa-file-text"></i> DepauMD</a>
|
||||
<div class="nav-mobile pull-right visible-xs">
|
||||
<span class="btn btn-link btn-file ui-upload-image" title="Upload Image" style="display:none;">
|
||||
<i class="fa fa-camera"></i><input type="file" accept="image/*" name="upload" multiple>
|
||||
</span>
|
||||
<a data-toggle="dropdown" class="btn btn-link">
|
||||
<i class="fa fa-caret-down"></i>
|
||||
</a>
|
||||
|
@ -100,9 +97,6 @@
|
|||
<span class="btn btn-link btn-file ui-help" title="<%= __('Help') %>" data-toggle="modal" data-target=".help-modal">
|
||||
<i class="fa fa-question-circle"></i>
|
||||
</span>
|
||||
<span class="btn btn-link btn-file ui-upload-image" title="<%= __('Upload Image') %>" style="display:none;">
|
||||
<i class="fa fa-camera"></i><input type="file" accept="image/*" name="upload" multiple>
|
||||
</span>
|
||||
</ul>
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
<li id="online-user-list">
|
||||
|
|
|
@ -135,26 +135,26 @@
|
|||
<option value="ca">Català</option>
|
||||
<option value="el">Ελληνικά</option>
|
||||
<option value="pt">Português</option>
|
||||
<option value="it">italiano</option>
|
||||
<option value="it">Italiano</option>
|
||||
<option value="tr">Türkçe</option>
|
||||
<option value="ru">Русский</option>
|
||||
<option value="nl">Nederlands</option>
|
||||
<option value="hr">hrvatski jezik</option>
|
||||
<option value="pl">język polski</option>
|
||||
<option value="hr">Hrvatski</option>
|
||||
<option value="pl">Polski</option>
|
||||
<option value="uk">Українська</option>
|
||||
<option value="hi">हिन्दी</option>
|
||||
<option value="sv">svenska</option>
|
||||
<option value="sv">Svenska</option>
|
||||
<option value="eo">Esperanto</option>
|
||||
<option value="da">dansk</option>
|
||||
<option value="da">Dansk</option>
|
||||
<option value="ko">한국어</option>
|
||||
<option value="id">Bahasa Indonesia</option>
|
||||
<option value="sr">српски</option>
|
||||
<option value="sr">Cрпски</option>
|
||||
</select>
|
||||
<p>
|
||||
<%- __('Powered by %s', '<a href="https://codimd.org">CodiMD</a>') %> | <a href="<%- serverURL %>/s/release-notes" target="_blank" rel="noopener"><%= __('Releases') %></a>| <a href="<%- sourceURL %>" target="_blank" rel="noopener"><%= __('Source Code') %></a><% if(privacyStatement) { %> | <a href="<%- serverURL %>/s/privacy" target="_blank" rel="noopener"><%= __('Privacy') %></a><% } %><% if(termsOfUse) { %> | <a href="<%- serverURL %>/s/terms-of-use" target="_blank" rel="noopener"><%= __('Terms of Use') %></a><% } %>
|
||||
<%- __('Powered by %s', '<a href="https://codimd.org">CodiMD</a>') %> | <a href="<%- serverURL %>/s/release-notes" target="_blank" rel="noopener"><%= __('Releases') %></a> | <a href="<%- sourceURL %>" target="_blank" rel="noopener"><%= __('Source Code') %></a><% if(privacyStatement) { %> | <a href="<%- serverURL %>/s/privacy" target="_blank" rel="noopener"><%= __('Privacy') %></a><% } %><% if(termsOfUse) { %> | <a href="<%- serverURL %>/s/terms-of-use" target="_blank" rel="noopener"><%= __('Terms of Use') %></a><% } %>
|
||||
</p>
|
||||
<h6 class="social-foot">
|
||||
<%- __('Follow us on %s and %s.', '<a href="https://github.com/hackmdio/CodiMD" target="_blank" rel="noopener"><i class="fa fa-github"></i> GitHub</a>, <a href="https://riot.im/app/#/room/#codimd:matrix.org" target="_blank" rel="noopener"><i class="fa fa-comments"></i> Riot</a>', '<a href="https://translate.codimd.org" target="_blank" rel="noopener"><i class="fa fa-globe"></i> POEditor</a>') %>
|
||||
<%- __('Follow us on %s and %s.', '<a href="https://github.com/codimd/server" target="_blank" rel="noopener"><i class="fa fa-github"></i> GitHub</a>, <a href="https://riot.im/app/#/room/#codimd:matrix.org" target="_blank" rel="noopener"><i class="fa fa-comments"></i> Riot</a>', '<a href="https://translate.codimd.org" target="_blank" rel="noopener"><i class="fa fa-globe"></i> POEditor</a>') %>
|
||||
</h6>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<h3 class="panel-title"><%= __('Contacts') %></h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<a href="https://github.com/hackmdio/codimd/issues" target="_blank"><i class="fa fa-tag fa-fw"></i> <%= __('Report an issue') %></a>
|
||||
<a href="https://github.com/codimd/server/issues" target="_blank"><i class="fa fa-tag fa-fw"></i> <%= __('Report an issue') %></a>
|
||||
<br>
|
||||
<a href="https://riot.im/app/#/room/#codimd:matrix.org" target="_blank"><i class="fa fa-hashtag fa-fw"></i> <%= __('Meet us on %s', 'Matrix') %></a>
|
||||
<br>
|
||||
|
|
|
@ -19,8 +19,8 @@ describe('generateAvatarURL() gravatar enabled', function () {
|
|||
})
|
||||
|
||||
it('should return correct urls', function () {
|
||||
assert.strictEqual(avatars.generateAvatarURL('Daan Sprenkels', 'hello@dsprenkels.com', true), 'https://www.gravatar.com/avatar/d41b5f3508cc3f31865566a47dd0336b?s=400')
|
||||
assert.strictEqual(avatars.generateAvatarURL('Daan Sprenkels', 'hello@dsprenkels.com', false), 'https://www.gravatar.com/avatar/d41b5f3508cc3f31865566a47dd0336b?s=96')
|
||||
assert.strictEqual(avatars.generateAvatarURL('Daan Sprenkels', 'hello@dsprenkels.com', true), 'https://cdn.libravatar.org/avatar/d41b5f3508cc3f31865566a47dd0336b?s=400')
|
||||
assert.strictEqual(avatars.generateAvatarURL('Daan Sprenkels', 'hello@dsprenkels.com', false), 'https://cdn.libravatar.org/avatar/d41b5f3508cc3f31865566a47dd0336b?s=96')
|
||||
})
|
||||
|
||||
it('should return correct urls for names with spaces', function () {
|
||||
|
|