Compare commits

...

1152 Commits

Author SHA1 Message Date
Davide Depau 7b31ddecc3
Merge branch 'master' into DepauMD 2019-08-04 10:49:43 +02:00
Sheogorath 1a4a0c41a4 Update de.json (POEditor.com) 2019-08-03 18:16:00 +02:00
Sheogorath 7d67566b96
Update yarn.lock 2019-08-01 20:14:48 +02:00
Salim B 5e7715a4e2
Slightly improve docker-linux-server.md
- fix typo
- add link to PhantomJS
- improve formatting

Signed-off-by: Salim B <salim@posteo.de>
2019-08-01 20:11:55 +02:00
Sheogorath e85f4defbb
Merge pull request #114 from SISheogorath/fix/linuxServerDocs
Fix some minor quirks in the LinuxServer.io docs
2019-08-01 20:07:09 +02:00
Sheogorath 788d8ca933
Fix some minor quirks in the LinuxServer.io docs
The current documents might end up confusing people and are not
completely accessible. This minor fixes should clear up the situation
and add alt texts to all badges, explain the links at the end of the
docs, and list LinuxServer.io in the supported provider section of the
README.

Some reasoning on the change in the listing:
Since we maintain an own container image which is for sure kept updated
on release, this is our first listing, as well as general solutions that
are build on that image, like the K8s integration.

The next listings are integrated provides which allow self-hosting, like
Cloudron and I also consider LinuxServer.io as this kind of providers.
Which try to enable people to run CodiMD on their own hardware or rented
servers in a very easy way, but by using their own images.

As third category I would look at hosted offers, like Heroku, which are
not completely SaaS but far enough away from the self-hostability that
I consider them as an own category. PaaS-based solutions are not as
FOSS-style as we want our setups to be, but of course still supported.

Finally the manual setup. We keep it down here, because we support it,
but don't recommend it in general. It's hard to upgrade and can cause
problems when dependencies are not correctly updated or people don't run
the db migrations.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2019-08-01 20:03:07 +02:00
Sheogorath 1ec083a091
Merge pull request #137 from codimd/snyk-fix-90a963f5d1c4d3e15b1c30f372c2f444
[Snyk] Fix for 1 vulnerable dependencies
2019-08-01 19:59:10 +02:00
snyk-test 6f588826e0 fix: package.json to reduce vulnerabilities
The following vulnerabilities are fixed with an upgrade:
- https://snyk.io/vuln/SNYK-JS-MERMAID-174698
2019-07-24 05:32:45 +00:00
Sheogorath 1bfed17f8c
Merge pull request #104 from SISheogorath/feature/dnt
Respect DNT header
2019-07-20 12:50:13 +02:00
Sheogorath 2f6e81e4db
Merge pull request #128 from dargmuesli/docker-secrets
DB URL: Secret File Support
2019-07-20 12:49:19 +02:00
Jonas Thelemann cc78dd0428
Docker Secrets: Add DB URL Support
As the connection string may include a password it should be supported by Docker Secrets.

Signed-off-by: Jonas Thelemann <e-mail@jonas-thelemann.de>
2019-07-01 19:43:42 +02:00
Sheogorath 118314d8dd
Merge pull request #119 from lhw/patch-1
Add SVG image detection based on file extension
2019-07-01 19:03:18 +02:00
Sheogorath 0d5923d61c
Update sequelize to latest version
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2019-06-22 16:29:09 +02:00
Sheogorath 502fae70a4
Update yarn.lock
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2019-06-22 16:23:24 +02:00
Sheogorath fd2731042f
Merge pull request #107 from SISheogorath/feature/db-upgrade
Fix sequelize by updating to the latest version
2019-06-22 16:17:11 +02:00
Lennart Weller f22a563116 Add SVG image detection based on file extension
Add simple SVG image detecetion base on the file extension .svg.
This fixes the SVG being delivered as binary/octet-stream and makes it possible to embedd the SVG.

Signed-off-by: Lennart Weller <lennart.weller@hansemerkur.de>
2019-06-18 17:13:50 +02:00
Sheogorath 8612740f82 Update sv.json (POEditor.com) 2019-06-16 10:59:48 +02:00
Sheogorath 3d2f5daa0f Update de.json (POEditor.com) 2019-06-16 10:59:46 +02:00
Sheogorath 4b4c6d6168
Merge pull request #111 from CHBMB/ls.io
Add docker image from LinuxServer.io as an install option.
2019-06-13 17:30:07 +02:00
chbmb 04d26637d6 Add docker image from LinuxServer.io as an install option.
As requested by @SISheogorath [here](https://github.com/linuxserver/docker-codimd/issues/4#issue-454332233) and further to discussion about previous PR [here.](https://github.com/codimd/server/pull/110#issuecomment-501214087)

Signed-off-by: Neil Green <chbmb@linuxserver.io>
2019-06-12 11:46:49 +01:00
Sheogorath 1e48b763d6
Merge pull request #106 from SISheogorath/fix/dco-location
Move DCO into docs section
2019-06-11 10:23:30 +02:00
BoHong Li 63c96e7359
fix: upgrade sequelize to latest version to fix CVE
Signed-off-by: BoHong Li <a60814billy@gmail.com>
2019-06-11 00:41:50 +02:00
Sheogorath 7cdb325e1c
Move DCO into docs section
The DCO currently resides in an own directory creating a pointless
additional click/tab in order to reach end read it. It also just
clutteres the directory structure of the project.

Therefore this patch provides moves the DCO into an own legal section in
the docs directory, which is hopefully a more reasonable place.

This section can also be extended in future in order to host other legal
documents as well.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2019-06-10 17:35:36 +02:00
Sheogorath 02929cd4bf
Merge pull request #103 from SISheogorath/feature/improve-logging
Rework debug logging
2019-06-09 13:47:32 +02:00
Sheogorath da4665c759
Respect DNT header
Do Not Track (DNT) is an old web standard in order to notify pages that
the user doesn't want to be tracked. Even while a lot of pages either
ignore this header or even worse, use it for tracking purposes, the
orignal intention of this header is good and should be adopted.

This patch implements a respect of the DNT header by no longer including
the optional Google Analytics and disqus integrations when sending a DNT
header. This should reduce outside resource usage and help to stay more
private.

This should later-on extended towards other document content (i.e.
iframe based content).

The reason to not change the CDN handling is that CDNs will be
deprecated with next release and removed in long term.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2019-06-08 23:43:50 +02:00
Sheogorath b5fc6db75d
Rework debug logging
We have various places with overly simple if statements that could be
handled by our logging library. Also a lot of those logs are not marked
as debug logs but as info logs, which can cause confusion during
debugging.

This patch removed unneeded if clauses around debug logging statements,
reworks debug log messages towards ECMA templates and add some new
logging statements which might be helpful in order to debug things like
image uploads.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2019-06-08 21:27:29 +02:00
Davide Depau d59212ea8b
Merge branch 'master' into DepauMD 2019-06-05 11:46:10 +02:00
Sheogorath 6462968e84
Merge pull request #97 from SISheogorath/fix/linting
Fix eslint warnings
2019-06-04 16:09:46 +02:00
Sheogorath ae32a12930
Merge pull request #93 from ttasovac/master
fixed styling of slides preview
2019-06-04 16:09:26 +02:00
Claudius Coenen 9140ca3c96
Merge pull request #98 from codimd/ccoenen-patch-1
mentioning the node 6 deprecation along with the migration guide
2019-05-31 15:21:57 +02:00
Claudius Coenen 8d576895ea
mentioning the node 6 deprecation along with the migration guide
Signed-off-by: Claudius <opensource@amenthes.de>
2019-05-31 15:16:24 +02:00
Sheogorath 51d69d993c
Release version 1.4.0
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2019-05-31 01:08:45 +02:00
Sheogorath 4da68597f7
Fix eslint warnings
Since we are about to release it's time to finally fix our linting. This
patch basically runs eslint --fix and does some further manual fixes.
Also it sets up eslint to fail on every warning on order to make
warnings visable in the CI process.

There should no functional change be introduced.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2019-05-31 00:30:29 +02:00
Sheogorath ac0bcb1c81
Merge pull request #94 from SISheogorath/fix/mathjax
Fix hidden MathJax output
2019-05-30 19:16:34 +02:00
Sheogorath 6f4841dcd2
Fix hidden MathJax output
In order to have a better experience when linking to headlines based on
their ID, a patch[1] introduced a new CSS construct to add some space in
front of HTML tags with an id field. Therefore they would no longer be
hidden by a visible navbar.

This cause a regression bug by moving the rendered mathjax out of its
visible area. This patch fixes the problem by restricting the previous
change to headlines only.

[1]: commit c9af13cf34

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2019-05-30 13:26:24 +02:00
Toma Tasovac 9e7b081bd9 fixed styling of slides preview
Signed-off-by: Toma Tasovac <ttasovac@humanistika.org>
2019-05-30 10:53:08 +02:00
Sheogorath 3eca0a74ae
Update yarn.lock
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2019-05-30 00:10:44 +02:00
Sheogorath e02defd402
Add Discourse link to footer
As we are about to announce the community forum, we should provide a
link to it in the footer. This patch adds Discouse between Riot, GitHub
and Mastodon as platform to follow our progress.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2019-05-30 00:02:37 +02:00
Sheogorath 388f034750
Merge pull request #81 from SISheogorath/fix/codemirrorBottomCSS
Fix CodeMirror toolbar hiding content
2019-05-26 22:19:57 +02:00
Sheogorath e2990c56fd
Merge pull request #82 from SISheogorath/fix/doubleCount
Fix missing pictures for OpenID
2019-05-26 22:19:22 +02:00
Sheogorath 515495bfbc
Merge pull request #83 from SISheogorath/language/vietnamese
Add vietnamese language
2019-05-26 14:32:53 +02:00
Sheogorath c89c43b0bc
Add vietnamese language
There was some awesome work by Hồng in the recent days who translated
CodiMD completely into Vietnamese language! This patch provides this
awesome contributions.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2019-05-26 05:34:52 +02:00
Sheogorath 0dff8796ac
Fix missing pictures for OpenID
Currently a problem appears when using OpenID for authentication as
there is no method to add a profile picture right now.

This patch makes sure that all undefined login methods get a profile
picture.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2019-05-26 03:53:59 +02:00
Sheogorath 5e500de628
Fix CodeMirror toolbar hiding content
As it may happens that the codemirror content flows underneath the
status bar, this patch should help to avoid it. It adds the size of the
status bar as margin-bottom so the codemirror window itself is forced
above the statusbar.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2019-05-26 03:48:58 +02:00
Sheogorath 678d139691
Merge pull request #6 from SISheogorath/feautre/notTooBusy
Add config for toobusy middleware
2019-05-25 21:17:28 +02:00
Sheogorath 6c62efae2a
Add config for toobusy middleware
With very low CPU frequency or bad IO situation, as well as not-loaded
JS CodiMD happens to present unneeded "I'm busy"-messages to users.

This patch allows to configure the lag. The default is taken from the
libray but set in our own default configs.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2019-05-25 21:08:38 +02:00
Sheogorath 816ed4ebc7
Merge pull request #77 from SISheogorath/fix/scrolling
Fix hidden header on link
2019-05-25 20:41:54 +02:00
Sheogorath c9af13cf34
Fix hidden header on link
When people link a section or use the ToC to scroll to it upwards, it
happens that those become hidden behind the navbar.

This patch adds a little hack from StackOverflow[1] in order to fix this
problem. By adding a pseudo element in front of any field that contains
an id, it's possible to add the needed space.

There was no negative impact found except of marking around the header
areas in the rendered view requires a bit preciser work. This needs some
more detailed testing.

[1]: https://stackoverflow.com/a/24298427

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2019-05-24 15:00:41 +02:00
Sheogorath de669c7b93
Merge pull request #73 from Amolith/master
fix issues #70 and #72
2019-05-20 23:44:01 +02:00
Amolith 871d8ea183
remove single quote preceding mastodon link
Signed-off-by: Amolith <amolith@nixnet.xyz>
2019-05-20 15:16:49 -04:00
Amolith 0eb1d4d612
add mastodon link to index - complete #70
Signed-off-by: Amolith <amolith@nixnet.xyz>
2019-05-19 21:52:21 -04:00
Amolith b220de8eb1
add mastodon badge - partially fix #70
Signed-off-by: Amolith <amolith@nixnet.xyz>
2019-05-19 21:52:08 -04:00
Amolith 4a02ca5d11
fix issue 72
Signed-off-by: Amolith <amolith@nixnet.xyz>
2019-05-19 20:50:53 -04:00
Christoph (Sheogorath) Kern 84d9b9acb5 Update es.json (POEditor.com) 2019-05-17 02:59:51 +02:00
Claudius 4c90863f2c Merge branch 'feature/drop-node-6' 2019-05-14 14:43:31 +02:00
Claudius 1da5a5bccc travis config is now in stages
Signed-off-by: Claudius <opensource@amenthes.de>
2019-05-13 19:37:22 +02:00
Claudius aa57b76a4f updating travis config: readable job names, more recent distro
Signed-off-by: Claudius <opensource@amenthes.de>
2019-05-13 19:37:22 +02:00
Claudius 806ebe6e1a drop node 6 support
We will no longer test on node6 and instead focus on 8+. This won't
break node6 immediately, but we will no longer go out of our way
supporting a version that does not receive security updates.

Signed-off-by: Claudius <opensource@amenthes.de>
2019-05-13 19:37:21 +02:00
Claudius 4833f300c5 polyfilling scrypt for node 8.5+
Signed-off-by: Claudius <opensource@amenthes.de>
2019-05-13 19:37:21 +02:00
Claudius 1d403e183d asyncified setting and verifying the password
Signed-off-by: Claudius <opensource@amenthes.de>
2019-05-13 19:37:21 +02:00
Claudius df666dd214 getting password hashing into a hook where it could be async
Signed-off-by: Claudius <opensource@amenthes.de>
2019-05-13 14:37:08 +02:00
Claudius 4b579be93e Adding the first few lines of user model test
Signed-off-by: Claudius <opensource@amenthes.de>
2019-05-13 14:37:08 +02:00
Claudius Coenen dabcb91185
Merge pull request #44 from pferreir/fix-23
Fix toolbar day mode and upload button
2019-05-12 23:30:28 +02:00
Pedro Ferreira e4c24c2936 Remove sass-loader, to avoid confusion
Signed-off-by: Pedro Ferreira <pedro@dete.st>
2019-05-12 20:15:46 +02:00
Pedro Ferreira 23f22d1fa6 Add no-console as a warning
Signed-off-by: Pedro Ferreira <pedro@dete.st>
2019-05-12 20:15:46 +02:00
Pedro Ferreira 26dacde959 Fix toolbar day mode
Also moved the code to SCSS

Signed-off-by: Pedro Ferreira <pedro@dete.st>
2019-05-12 20:15:46 +02:00
Pedro Ferreira 1801febfe6 Make upload button respect night mode
Also set a title in the input field, so that the file name doesn't show
up.

Signed-off-by: Pedro Ferreira <pedro@dete.st>
2019-05-12 20:15:46 +02:00
Christoph (Sheogorath) Kern 5bb6929767
Merge pull request #57 from boardfish/patch-1
Provide documentation for configuration with Keycloak
2019-05-11 00:10:37 +02:00
Simon Fish d1fbf63291 Improve documentation
Signed-off-by: Simon Fish <si@mon.fish>
2019-05-06 17:15:07 +01:00
Simon Fish 335065cba9 Provide documentation for configuration with Keycloak
Signed-off-by: Simon Fish <si@mon.fish>
2019-05-06 17:15:07 +01:00
Sheogorath 9101be92ab
Update jQuery to version 3.4.1 2019-05-06 10:42:41 +02:00
Christoph (Sheogorath) Kern d0b234048b
Merge pull request #61 from archemiro/archemiro/docs-setup-docker
Add name of directory to clone into
2019-05-06 10:34:00 +02:00
Mauricio Robayo d4ac3fdd5f Add name of directory to clone into
Signed-off-by: Mauricio Robayo <rfmajo@gmail.com>
2019-05-05 19:28:30 -05:00
Davide Depau 9d9a4c2357
Update Mermaid 2019-04-26 21:57:56 +02:00
Davide Depau 1eca9efd6b Add "DepauMD" to home screen 2019-04-25 22:40:33 +02:00
Davide Depau 36749cc645 Merge remote-tracking branch 'upstream/master' into DepauMD 2019-04-25 21:30:07 +02:00
Christoph (Sheogorath) Kern 868e8e6d66 Update sv.json (POEditor.com) 2019-04-25 10:17:24 +02:00
Christoph (Sheogorath) Kern 321114db12 Update de.json (POEditor.com) 2019-04-20 00:00:12 +02:00
Christoph (Sheogorath) Kern dbfd6f0429 Update de.json (POEditor.com) 2019-04-19 23:23:44 +02:00
Christoph (Sheogorath) Kern 3f458178bd Update zh-TW.json (POEditor.com) 2019-04-19 23:23:42 +02:00
Christoph (Sheogorath) Kern e1fd3f3cca Update sr.json (POEditor.com) 2019-04-19 22:34:15 +02:00
Christoph (Sheogorath) Kern 857f1e3f7a Update pl.json (POEditor.com) 2019-04-19 22:34:13 +02:00
Christoph (Sheogorath) Kern 999e9f21ff Update ja.json (POEditor.com) 2019-04-19 22:34:11 +02:00
Christoph (Sheogorath) Kern 967d2b65a7 Update it.json (POEditor.com) 2019-04-19 22:34:08 +02:00
Christoph (Sheogorath) Kern 72a6e1a5a5 Update fr.json (POEditor.com) 2019-04-19 22:34:06 +02:00
Christoph (Sheogorath) Kern e5af02fe98 Update zh-CN.json (POEditor.com) 2019-04-19 22:34:04 +02:00
Christoph (Sheogorath) Kern 81904b6717
Merge pull request #51 from SISheogorath/fix/wurl
Replace js-url with wurl
2019-04-19 21:46:08 +02:00
Christoph (Sheogorath) Kern a22c1a9d65
Merge pull request #52 from codimd/snyk-fix-yfvllf
[Snyk] Fix for 1 vulnerable dependencies
2019-04-16 22:02:16 +02:00
snyk-bot 54fd5ee0a2 fix: package.json to reduce vulnerabilities
The following vulnerabilities are fixed with an upgrade:
- https://snyk.io/vuln/SNYK-JS-HANDLEBARS-174183
2019-04-16 19:16:26 +00:00
Sheogorath c0e75b8606
Replace js-url with wurl
js-url is outdated and wurl is it's successor. This will fix some
vulnerabilities in the dependencies and also optimize the build process
by removing the external library toward internal tooling.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2019-04-16 19:28:23 +02:00
Christoph (Sheogorath) Kern 04da0615d2
Merge pull request #45 from ccoenen/master
fixing manual upgrade instructions and completing requirements
2019-04-16 19:24:47 +02:00
naimo cc53d5ebfa fix unix socket not removed on shutdown (#50)
* fix unix socket not removed on shutdown

Signed-off-by: naimo <nicolas@aimon.fr>
2019-04-16 18:19:11 +02:00
Sheogorath d359d4aa84
Update yarn.lock 2019-04-16 14:31:01 +02:00
Christoph (Sheogorath) Kern 2df474b63e
Merge pull request #48 from SISheogorath/fix/graphvizXSS
Fix stored XSS in the graphviz error message rendering
2019-04-16 14:17:10 +02:00
Max Wu fb399ebe73
Fix stored XSS in the graphviz error message rendering [Security Issue]
Signed-off-by: Max Wu <jackymaxj@gmail.com>

Co-Authored-By: Sheogorath <sheogorath@shivering-isles.com>
2019-04-16 14:05:26 +02:00
Claudius 32d3b914b2 fixing manual upgrade instructions and completing requirements
Signed-off-by: Claudius <opensource@amenthes.de>
2019-04-15 22:25:06 +02:00
Christoph (Sheogorath) Kern 074198f941
Merge pull request #43 from SISheogorath/feature/community
Add community forum to help section
2019-04-12 23:47:51 +02:00
Christoph (Sheogorath) Kern 2b99ed6d53
Merge pull request #42 from SISheogorath/fix/meta-marked
Update meta-marked to fix possible vulnerabilities
2019-04-12 23:33:52 +02:00
Christoph (Sheogorath) Kern 4630c7afea Update zh-CN.json (POEditor.com) 2019-04-12 15:17:52 +02:00
Sheogorath 454b39ac10
Add community forum to help section
We have a community forum and want to use it for users support and to
bring developers and end-users together. In order to achieve this, it
would be helpful to inform users about its existence.

This patch adds the community forum as resource to the help section and
aligns it along the Matrix channel and GitHub issue tracker.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2019-04-12 12:29:56 +02:00
Davide Depau 107f92e6fd Merge remote-tracking branch 'upstream/master' into DepauMD 2019-04-11 22:30:56 +02:00
Davide Depau 7240364d30 Merge remote-tracking branch 'upstream/master' into DepauMD 2019-04-11 22:26:27 +02:00
Davide Depau 283938b35c Merge remote-tracking branch 'upstream/master' into DepauMD 2019-04-11 22:25:13 +02:00
Raccoon ad9f29acbf
Merge pull request #1188 from hackmdio/fix/js-sequence-diagram
Fix/js sequence diagram
2019-04-10 20:16:37 +08:00
Sheogorath 197b0db88f
Update yarn.lock
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2019-04-10 13:58:04 +02:00
Sheogorath 32f6037da9
Update yarn to version 1.15.2
The yarn version we use in CI is quite outdated. This brings up the
problem that it doesn't support semver for git repositories. In order to
fix that problem updating yarn seems to be the right thing to do.

This patch should fix the CI problem caused by the semver git URL.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2019-04-10 13:40:54 +02:00
BoHong Li c69d91be9f
fix: bump js-sequence-diagrams version to alpha.2 to fix error height measure
Signed-off-by: BoHong Li <a60814billy@gmail.com>
2019-04-10 19:39:00 +08:00
BoHong Li c50a9b416f
fix: flowchart.js eve denpency eve not found
Signed-off-by: BoHong Li <a60814billy@gmail.com>
2019-04-10 19:18:26 +08:00
Sheogorath e014a73393
Update meta-marked to fix possible vulnerabilities
Snyk informed us about possible vulnerabilities in meta-marked. It seems
like at least some of them were already address by HackMD around a year
ago but never pushed upstream to CodiMD.

This patch provides a fix by using an up-to-date dependency from our own
repository with CI integration.

Details: https://app.snyk.io/vuln/SNYK-JS-JSYAML-174129

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2019-04-10 13:11:57 +02:00
BoHong Li 0734f0faa8
fix: js-sequence-diagram not found
Signed-off-by: BoHong Li <a60814billy@gmail.com>
2019-04-10 18:34:31 +08:00
BoHong Li a68d19bc22
fix: scrypt cannot build on some platform, revert the change library commit
Signed-off-by: BoHong Li <a60814billy@gmail.com>
2019-04-10 18:34:31 +08:00
Christoph (Sheogorath) Kern ef348fc49b
Merge pull request #33 from codimd/lutim-support
Add support for image hosting with lutim
2019-04-10 11:39:11 +02:00
Christoph (Sheogorath) Kern f541c00bad
Merge pull request #41 from SISheogorath/js-diagram-v2
Fix broken dependency js-sequence-diagrams
2019-04-10 11:38:54 +02:00
Dylan Dervaux 208070d2e7
Add lutim support
Signed-off-by: Dylan Dervaux <dylanderv05@gmail.com>
2019-04-10 01:37:12 +02:00
Sheogorath 1f55150441
Fix broken dependency js-sequence-diagrams
A few days ago the dependency was removed from npm. this causes various
setups to fail and blocks deployments and development.

This patch should fix the dependency and allow CodiMD to move forward.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2019-04-10 00:18:24 +02:00
Max Wu d032b37ddf
Update README.md 2019-04-08 21:57:46 -04:00
Christoph (Sheogorath) Kern c6384567b8
Merge pull request #38 from codimd/snyk-fix-d5beoi
[Snyk] Fix for 1 vulnerable dependencies
2019-04-07 22:03:21 +02:00
snyk-bot 502c70008e fix: package.json to reduce vulnerabilities
The following vulnerabilities are fixed with an upgrade:
- https://snyk.io/vuln/SNYK-JS-JSYAML-174129
2019-04-07 19:49:25 +00:00
Christoph (Sheogorath) Kern 36c083277e
Merge pull request #30 from codimd/samlConfig
Added a configuration option for passport-saml:
2019-04-06 21:35:39 +02:00
Emmanuel Ormancey df53f465c0
Added a configuration option for passport-saml:
disableRequestedAuthnContext: true|false

By default only Password authmethod is accepted, this option allows any other method.

Issue and option described here:
https://github.com/bergie/passport-saml/issues/226

Signed-off-by: Emmanuel Ormancey <emmanuel.ormancey@cern.ch>
2019-04-06 17:54:58 +02:00
Christoph (Sheogorath) Kern 5379d65edc
Merge pull request #31 from codimd/hidePortMinio
Hide port minio
2019-04-06 17:50:22 +02:00
Thor77 022c7ad616
Hide port from minio URL for protocol default port
Signed-off-by: Thor77 <thor77@thor77.org>
2019-04-06 13:52:49 +02:00
Christoph (Sheogorath) Kern ee725dc58c
Merge pull request #37 from stragu/patch-1
change default mode to "both" when clicking edit
2019-04-05 13:49:28 +02:00
Stéphane Guillou afc8541c86 change default mode to "both" when clicking edit
Add "both" mode to URLs because I assume most people want to straight away see the code when they click the "edit" button in a published note.

Fixes https://github.com/codimd/server/issues/27

Not tested, followed instructions from @ccoenen , please do review! :)

Signed-off-by: Stéphane Guillou <stephane.guillou@member.fsf.org>
2019-04-05 20:58:06 +10:00
Christoph (Sheogorath) Kern fdd912d23a Update sr.json (POEditor.com) 2019-04-04 14:27:27 +02:00
Christoph (Sheogorath) Kern 0d3e065e34
Merge pull request #35 from ccoenen/enhancement/translation-churn
specifying the locale jsons to be in the exact style of poeditor
2019-04-04 13:45:31 +02:00
Claudius e738efe217 specifying the locale jsons to be in the exact style of poeditor should cut down on unneccessary changes ('churn')
Signed-off-by: Claudius <opensource@amenthes.de>
2019-04-04 12:31:38 +02:00
Christoph (Sheogorath) Kern 279235fbbb Update pl.json (POEditor.com) 2019-04-04 12:05:36 +02:00
Henrik "HerHde" Hüttemann f13a91c698 Clean up headings
Signed-off-by: Henrik "HerHde" Hüttemann <mail@herh.de>
2019-04-04 00:54:47 +02:00
Claudius Coenen 49539fb27f
tiny correction to url. also adding RSS feed. 2019-04-04 00:34:23 +02:00
Sheogorath e96c8d1dd4
Update community call URL
We have a discourse forum and since it's the place for all kinds of
community organisation, this should be used for organising the community
calls.

This patch updates the link to the new topic in the forum.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2019-04-03 23:56:31 +02:00
Claudius acd7634fc7 more ways to engage with the community added to the readme
Signed-off-by: Claudius <opensource@amenthes.de>
2019-04-03 23:24:05 +02:00
Christoph (Sheogorath) Kern 07a0594c9a
Merge pull request #22 from SISheogorath/feature/newScreenshot
Add new screenshot
2019-04-02 01:47:48 +02:00
Sheogorath 004b2e51f1
Add new screenshot
The old screenshot is quite dated since it's from the earlier days of
HackMD.

But we developed a lot in the recent years. Changed the name, added a
toolbar, moved buttons, and so on.

This patch should represent those changes in the front page.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2019-04-01 23:19:02 +02:00
Henrik Hüttemann 5951dd1805 Add missing space to footer
Signed-off-by: Henrik "HerHde" Hüttemann <mail@herh.de>
2019-04-01 09:47:06 +02:00
Claudius a140bff47e minor fixes to internal links in documentation 2019-04-01 09:42:33 +02:00
Claudius Coenen a95f1e9f56
Merge pull request #15 from ccoenen/feature/documentation-overhaul
Documentation overhaul
2019-04-01 01:31:05 +02:00
Claudius ba6ede57bd moving code of conduct into its own file for better discoverability
Signed-off-by: Claudius <opensource@amenthes.de>
2019-04-01 01:26:42 +02:00
Claudius 33b22cf26f breaking up config docs into sections
Signed-off-by: Claudius <opensource@amenthes.de>
2019-04-01 01:16:24 +02:00
Claudius 54edec8900 striving for consistency across various docs
Signed-off-by: Claudius <opensource@amenthes.de>
2019-04-01 01:03:36 +02:00
Claudius 74fdd26ea0 integrating information from the old wiki
Signed-off-by: Claudius <opensource@amenthes.de>
2019-04-01 01:03:36 +02:00
Claudius fb973d2a6f removing doctoc, which is no longer being used
Signed-off-by: Claudius <opensource@amenthes.de>
2019-04-01 01:03:36 +02:00
Claudius edf301cfa3 splitting README.md into files in /docs for better readability
Signed-off-by: Claudius <opensource@amenthes.de>
2019-04-01 01:03:36 +02:00
Christoph (Sheogorath) Kern 3a0ff5edd3
Merge pull request #9 from SISheogorath/feature/moveUpload
Move upload button into toolbar
2019-03-31 15:14:31 +02:00
Christoph (Sheogorath) Kern 948c3367eb
Merge pull request #14 from SISheogorath/fix/LICENSE
Fix LICENSE content
2019-03-31 12:41:49 +02:00
Claudius Coenen d08d9f34b0
Merge pull request #13 from ccoenen/feature/heroku-cleanup
cleanup of the heroku configuration
2019-03-31 12:41:38 +02:00
Christoph (Sheogorath) Kern 7f04013f4a
Merge pull request #7 from SISheogorath/feature/libravatar
Use libravatar as drop-in replacement for gravatar
2019-03-31 03:30:51 +02:00
Christoph (Sheogorath) Kern 52055ec7b7
Merge pull request #8 from SISheogorath/fix/languages
Fix capital letters in language selection
2019-03-31 03:30:15 +02:00
Sheogorath 962330933d
Fix LICENSE content
It seems like the license was never correctly filled.

This patch updates the LICENSE file to represent members of the
community and major code contributors.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2019-03-31 03:27:12 +02:00
Claudius 5c607c4f80 cleanup of the heroku configuration
this removes the general `postinstall` call to `bin/heroku` and instead
puts it into a heroku-prebuild hook. At the same time, env vars get
updated to use the `CMD` prefix. The configured buildpacks were not used.
Finally, npm run build is now automatically
done by Heroku.

Signed-off-by: Claudius <opensource@amenthes.de>
2019-03-31 01:29:34 +01:00
Sheogorath 4ffeab6129
Release version 1.3.2
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2019-03-29 12:33:20 +01:00
Sheogorath 16d84926f9
Fix logo URL in app.json
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2019-03-29 12:31:18 +01:00
Sheogorath 9941d5613b
Fix button background color
When introducing night mode the rule for the background of the view 
switches seems to be generated from the view button.

This patch should change the introduced rule to fix for all default 
buttons.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2019-03-29 12:30:21 +01:00
Sheogorath 974dc8fc21
Update maintainers in package.json
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2019-03-29 12:30:20 +01:00
Sheogorath e982ef686c
Add note about changing the upstream repository
People who want to get the latest and greatest version of CodiMD should 
be aware of the repository change. This upgrade note, will hopefully 
help.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2019-03-28 22:45:58 +01:00
Sheogorath a5836dd52f
Fix container image links
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2019-03-28 22:45:58 +01:00
Sheogorath 982a12f569
Fix some remaining references to the old repository
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2019-03-28 22:45:57 +01:00
Max Wu f65d958517
Update README.md 2019-03-27 18:07:22 -04:00
Raccoon b9f36fc9a0 Update zh-TW.json (POEditor.com) 2019-03-28 06:02:23 +08:00
Max Wu ec908f1ba4
Update README.md 2019-03-27 17:56:37 -04:00
Max Wu 6d7202bc97
Update README.md 2019-03-27 17:54:57 -04:00
Max Wu dab90bf4e1
Update README.md 2019-03-27 17:49:38 -04:00
Sheogorath 7cde6958f3
Update links to new repositories
After a long discussion, it turned out that CodiMD as community project
and HackMD as a company, have fundamental different views on the project
governance.

Due to this, it came to point where the decision for a fork was made.
After the fork and move towards an own organisation, this patch updates
all links inside the project to the new repositories.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2019-03-27 19:31:34 +01:00
Sheogorath 1544b45af5
Move upload button into toolbar
Currently we have the odd situation to have two toolbars. One inside the
header and one in the editor.

Since we only show the image upload button when the editor is visible we
should move the upload button into the editor toolbar.

This patch does this by adding the image upload button besides the image
tag button.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2019-03-25 22:33:27 +01:00
Sheogorath d167f7b092
Fix capital letters in language selection
Vladan[1] gave a hint about some minor problems with the capitalization
of language names.

This patch should fix most of them. and removes some "language" prefix
and suffixes which are not needed to make clear what people are
selecting here.

[1]: https://github.com/cvladan

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2019-03-24 23:13:48 +01:00
Sheogorath 50c80c99a4
Release version 1.3.1
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2019-03-23 13:27:39 +01:00
Sheogorath b817b9efd9
Update yarn.lock
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2019-03-23 13:25:33 +01:00
Christoph (Sheogorath) Kern 1678c8e2cc Update ja.json (POEditor.com) 2019-03-20 15:40:28 +01:00
Christoph (Sheogorath) Kern f9fbff2d59 Update it.json (POEditor.com) 2019-03-20 15:40:23 +01:00
Christoph (Sheogorath) Kern f15ab84810 Update id.json (POEditor.com) 2019-03-20 15:40:20 +01:00
Christoph (Sheogorath) Kern 4977dd6109 Update fr.json (POEditor.com) 2019-03-20 15:40:17 +01:00
Christoph (Sheogorath) Kern 01b1697c0c Update nl.json (POEditor.com) 2019-03-20 15:40:11 +01:00
Sheogorath a5133e0f9b
Use libravatar as drop-in replacement for gravatar
Since libravatar got a default fallback to Gravatar and in generell
allows federated image hosting for avatars this shouldn't break any
existing implementations.

The federation functionality is not added yet. This would require to use
the libravatar library.

Details:
https://wiki.libravatar.org/api/

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2019-03-17 23:51:54 +01:00
Christoph (Sheogorath) Kern 992f02c294
Merge pull request #1158 from SISheogorath/feature/serbianLanguage
Add serbian language
2019-03-16 19:58:45 +01:00
Davide Depau 9bb50dda6c * Run db migrations on `npm start`
* Add documentation about integration with AD LDAP
 * Add `rel="noopener"` to all links
 * Add documentation about integration with Nextcloud for authentication
 * Update URL on frontpage to point to codimd.org
 * Replace Fontawesome with Forkawesome
 * Add OpenID support
 * Add print icon to slide view
 * Add auto-complete for language names that are highlighted in codeblocks
 * Improve translations for Chinese, Dutch, French, German, Italien, Korean, Polish, and Russian language
 * Add Download action to published document API
 * Add reset password feature to `manage_users` script
 * Move from own `./tmp` directory to system temp directory
 * Add Etherpad migration guide
 * Move XSS library to a more native position
 * Use full version string to determine changes from the backend
 * Update winston (logging library)
 * Use slide preview in slide example
 * Improve migration handling
 * Update reveal.js to version 3.7.0
 * Replace scrypt library with its successor
 * Replace `to-markdown` with `turndown` (successor library)
 * Update socket.io
 * Add warning on missing base URL
 * Update bootstrap to version 3.4.0
 * Update handlebar
 
 * Fix paths in GitLab documentation
 * Fix missing `data:` URL in CSP
 * Fix oAuth2 name/label field
 * Fix GitLab API integration
 * Fix auto-completed but not rendered emojis
 * Fix menu organization depending on enabled services
 * Fix some logging in the OT module
 * Fix some unhandled internalOAuthError exception
 * Fix unwanted creation of robots.txt document in "freeurl-mode"
 * Fix some links on index page to lead to the right sections on feature page
 * Fix document breaking, empty headlines
 * Fix wrong multiplication for HSTS header seconds
 * Fix wrong subdirectories in exported user data
 * Fix CSP for speaker notes
 * Fix CSP for disqus
 * Fix URL API usage
 * Fix Gist embedding
 * Fix upload provider error message
 * Fix unescaped disqus user names
 * Fix SAML vulnerability
 * Fix link to SAML guide
 * Fix deep dependency problem with node 6.x
 * Fix broken PDF export by wrong unlink call
 * Fix possible XSS attack in MathJax
 
 * Refactor to use `ws` instead of the the no longer supported `uws`
 * Refactor frontend build system to use webpack version 4
 * Refactor file path configuration (views, uploads, …)
 * Refactor `manage_users` script
 * Refactor handling of template variables
 * Refactor linting to use eslint
 
 * Remove no longer working Octicons
 * Remove links to our old Gitter channel
 * Remove unused library node-uuid
 * Remove unneeded blueimp-md5 dependency
 * Remove speakerdeck due to broken implementation
 
 * Adam.emts (translator)
 * [Alex Garcia](https://github.com/asg017)
 * [Cédric Couralet (micedre)](https://github.com/micedre)
 * [Claudius Coenen](https://github.com/ccoenen)
 * [Daan Sprenkels](https://github.com/dsprenkels)
 * [David Mehren](https://github.com/davidmehren)
 * [Erona](https://github.com/Eronana)
 * [Felix Yan](https://github.com/felixonmars)
 * [Jonathan](https://github.com/phrix32)
 * Jong-kai Yang (translator)
 * [MartB](https://github.com/MartB)
 * [Max Wu (jackycute)](https://github.com/jackycute)
 * [mcnesium](https://github.com/mcnesium)
 * Nullnine (translator)
 * RanoIP (translator)
 * [SuNbiT](https://github.com/sunbit)
 * Sylke Vicious (translator)
 * Timothee (translator)
 * [WilliButz](https://github.com/WilliButz)
 * [Xaver Maierhofer](https://github.com/xf-)
 * [云屿](https://github.com/cloudyu)
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEEAeWzysDCaBZIKvtIHwXMNjXN3/0FAlx9Dj8ACgkQHwXMNjXN
 3/2faw/8CYL5qB43K1L3wwMu5YMfVfrZALyQTrrb016I1VkGh+e18ffM4FOYSa5C
 xeUDf/GRa30EKqxaBZjsHoUGxQ196g9WvyA4HziEVUti2LvmWwnSjSvFqGrjFJ79
 veaCfxG2NjvVc+k2Ts+E8G+1VH5TdU/TloViE6hvsu9zAOjKlxbTVlhu/YTpkIx0
 9fmSSrSonMFURvVG9LFnTgtzf0f9cbjGCmu+EjKxDJ2CZ9WkjShaL3nuPTOXReaq
 0MYOaWZJBsDd8nWcVqIamkKhzz/U7jRO6PpvXG6TXhJo8cqml/qpr3ZD6j6L9FOq
 HDQUUcligMynPaSOUBkVQXmlSPljL/2q1NYHAo0zDlP1vcm5+EWt1D4o73RZU4h5
 41mNJhanDeNk/QPrnI+Dldwg1k4PBrLrlPUYyNM7F6FgoZPBTtFVJ9nQVHyI6UWS
 oa3iq0YKCd1ofl0AdfLljgIeRxpArQGK6ey87eXRZXveeDOC+TEAZeS1/1/cac7+
 R7uCszvvLUBdE3W7JzcS5Xo4TtARPOjLkaYKObZhtzUW1YtMyGk+HpIvx2yZet8K
 NGpneShNa6IvygsVQqZ1ZZfIYLFIDsLQmoAe1+dffGF3K2b+ObkrT/hSimP2Ftq0
 +MrdXH56cuKqfyGPnfoqa0zQhieGC6n57xW2WAoBAOcEmpx2Ng4=
 =cjCR
 -----END PGP SIGNATURE-----

Merge tag '1.3.0' into DepauMD

* Run db migrations on `npm start`
* Add documentation about integration with AD LDAP
* Add `rel="noopener"` to all links
* Add documentation about integration with Nextcloud for authentication
* Update URL on frontpage to point to codimd.org
* Replace Fontawesome with Forkawesome
* Add OpenID support
* Add print icon to slide view
* Add auto-complete for language names that are highlighted in codeblocks
* Improve translations for Chinese, Dutch, French, German, Italien, Korean, Polish, and Russian language
* Add Download action to published document API
* Add reset password feature to `manage_users` script
* Move from own `./tmp` directory to system temp directory
* Add Etherpad migration guide
* Move XSS library to a more native position
* Use full version string to determine changes from the backend
* Update winston (logging library)
* Use slide preview in slide example
* Improve migration handling
* Update reveal.js to version 3.7.0
* Replace scrypt library with its successor
* Replace `to-markdown` with `turndown` (successor library)
* Update socket.io
* Add warning on missing base URL
* Update bootstrap to version 3.4.0
* Update handlebar

* Fix paths in GitLab documentation
* Fix missing `data:` URL in CSP
* Fix oAuth2 name/label field
* Fix GitLab API integration
* Fix auto-completed but not rendered emojis
* Fix menu organization depending on enabled services
* Fix some logging in the OT module
* Fix some unhandled internalOAuthError exception
* Fix unwanted creation of robots.txt document in "freeurl-mode"
* Fix some links on index page to lead to the right sections on feature page
* Fix document breaking, empty headlines
* Fix wrong multiplication for HSTS header seconds
* Fix wrong subdirectories in exported user data
* Fix CSP for speaker notes
* Fix CSP for disqus
* Fix URL API usage
* Fix Gist embedding
* Fix upload provider error message
* Fix unescaped disqus user names
* Fix SAML vulnerability
* Fix link to SAML guide
* Fix deep dependency problem with node 6.x
* Fix broken PDF export by wrong unlink call
* Fix possible XSS attack in MathJax

* Refactor to use `ws` instead of the the no longer supported `uws`
* Refactor frontend build system to use webpack version 4
* Refactor file path configuration (views, uploads, …)
* Refactor `manage_users` script
* Refactor handling of template variables
* Refactor linting to use eslint

* Remove no longer working Octicons
* Remove links to our old Gitter channel
* Remove unused library node-uuid
* Remove unneeded blueimp-md5 dependency
* Remove speakerdeck due to broken implementation

* Adam.emts (translator)
* [Alex Garcia](https://github.com/asg017)
* [Cédric Couralet (micedre)](https://github.com/micedre)
* [Claudius Coenen](https://github.com/ccoenen)
* [Daan Sprenkels](https://github.com/dsprenkels)
* [David Mehren](https://github.com/davidmehren)
* [Erona](https://github.com/Eronana)
* [Felix Yan](https://github.com/felixonmars)
* [Jonathan](https://github.com/phrix32)
* Jong-kai Yang (translator)
* [MartB](https://github.com/MartB)
* [Max Wu (jackycute)](https://github.com/jackycute)
* [mcnesium](https://github.com/mcnesium)
* Nullnine (translator)
* RanoIP (translator)
* [SuNbiT](https://github.com/sunbit)
* Sylke Vicious (translator)
* Timothee (translator)
* [WilliButz](https://github.com/WilliButz)
* [Xaver Maierhofer](https://github.com/xf-)
* [云屿](https://github.com/cloudyu)
2019-03-13 13:19:21 +01:00
Christoph (Sheogorath) Kern 27ba5f910d
Merge pull request #1166 from SISheogorath/fix/exportEmojis
Fix broken HTML export with emojis
2019-03-13 11:50:50 +01:00
Sheogorath 5e634aef87
Fix possible order changes for 'Powered by' in other languages
Since not all languages use the same word oder and we run into potential
issues, where the translation of powered by need to add something after
the CodiMD link, this should give us the needed flexiblity.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2019-03-10 01:43:13 +01:00
Christoph (Sheogorath) Kern 1ffc492442
Merge pull request #1076 from SISheogorath/fix/translation
Add some missing translations
2019-03-10 01:32:20 +01:00
Sheogorath 982775f6dc
Fix broken HTML export with emojis
HTML export was broken due to missing alt-attribute for emojis.

This patch adds the old alt-element style and restores the exportability
this way.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2019-03-09 15:04:07 +01:00
Christoph (Sheogorath) Kern 329d39d0d0
Merge pull request #1131 from SISheogorath/fix/gitlabSnippets
Fix shown but broken GitLab snippets
2019-03-09 14:50:47 +01:00
Christoph (Sheogorath) Kern d1b2fb2258
Merge pull request #1163 from SISheogorath/fix/googleAuth
Add required change for Google+ API deprecation
2019-03-09 14:50:20 +01:00
Sheogorath cda878d377
Add required change for Google+ API deprecation
Since Google+ is shutting down soon, we need to get the profile data
from another URL. Since the library already supports it, all we need to
do is adding a single line of code.

Details:
https://github.com/hackmdio/codimd/issues/1160

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2019-03-09 14:42:06 +01:00
Sheogorath bcb7972607
Fix shown but broken GitLab snippets
To provide a GitLab integration we need the GitLab integration to be
configured. Otherwise we shouldn't show the Snippet button.

This patch adds the requirement to the variable that decides if the
import from snippets button shows up or not.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2019-03-05 18:16:04 +01:00
Christoph (Sheogorath) Kern de0acbb566
Merge pull request #1153 from toshi0123/for_empty_serverurl
Fix empty serverURL did not redirect properly
2019-03-05 18:11:37 +01:00
Christoph (Sheogorath) Kern e48342a64a
Merge pull request #1155 from Turakar/master
Mention dependency on libssl-dev in README.md
2019-03-04 20:20:02 +01:00
Turakar 13ee05ba0d Mention dependency on libssl-dev in README.md
This dependency was introduced by upgrading to the new scrypt version in commit cee2aa92f9.

Signed-off-by: Tilman Hoffbauer <turakar23@gmail.com>
2019-03-04 20:14:55 +01:00
Sheogorath b51a048777
Fix wrong value type for HSTS environment variable
Seem like also environment variables are affected. This patch fixes that
as well.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2019-03-04 17:13:43 +01:00
Sheogorath 32a1afbe86
Fix wrong value type in example config
HSTS maxAge has to be an integer, not a string.

Fixes https://github.com/hackmdio/codimd/issues/1159

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2019-03-04 16:59:44 +01:00
Sheogorath 20d1f17d2c
Add serbian language
Thanks for the work of the translator Vladan we got a serbian
translation added! Those few changes will add serbian language support
for future CodiMD releases.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2019-03-04 13:21:01 +01:00
Christoph (Sheogorath) Kern 126cd1b1f0
Merge pull request #1139 from Luclu7/patch-1
Corrected a typo
2019-03-04 13:10:56 +01:00
Sheogorath 87443dec5f
Release version 1.3.0
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2019-03-04 12:37:00 +01:00
toshi0123 6aab032709 Fix empty serverURL did not redirect properly
Signed-off-by: toshi0123 <7948737+toshi0123@users.noreply.github.com>
2019-03-04 13:59:14 +09:00
Sheogorath 1ee9874393
Fix names with spaces in letter-avatars
Seems like there is a possible problem when a name containing a space is
passed to this function. using urlencode on the name should fix possible
problems here.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2019-03-03 15:46:28 +01:00
Christoph (Sheogorath) Kern 112827423a
Merge pull request #1157 from hackmdio/fix-MathJax-XSS-issue
Fix possible MathJax XSS issue [Security Issue]
2019-03-03 15:44:33 +01:00
Max Wu 1743a97c22 Fix possible MathJax XSS issue [Security Issue]
see more at: http://docs.mathjax.org/en/latest/safe-mode.html

Signed-off-by: Max Wu <jackymaxj@gmail.com>
2019-03-03 18:32:58 +08:00
Sheogorath b718eac70a
Force upgrade of some outdated dependencies
I don't really like the way to go here, but I guess having those
forcefully upgraded is better than staying around with vulnerable
dependencies.

This patch fixes some vulnerbilities in dependencies that were
categories as high severity.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2019-03-02 19:14:12 +01:00
Sheogorath edfe7fc401
Update yarn.lock
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2019-03-02 15:27:16 +01:00
Sheogorath 9981a6c8ba
Fix wrong domain in app.json
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2019-03-02 14:27:59 +01:00
Christoph (Sheogorath) Kern 5274247790
Merge pull request #1150 from SISheogorath/fix/speakerdeck
Remove broken speakerdeck embedding
2019-02-21 23:34:15 +01:00
Sheogorath 1f0fb12755
Fix CI errors for unused variables
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2019-02-21 01:36:39 +01:00
Sheogorath c5ca7b634a
Remove broken speakerdeck embedding
The current speakerdeck implementation is broken. An alternative
implementation using oembed doesn't work due to CORS, which could be
solved by proxying the speakerdeck API, but we decided to not do this.

This patch provides the link to the speakerdeck presentation instead,
and this way doesn't break existing notes. This is right now the best
solution we could come up with.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2019-02-21 01:26:37 +01:00
Sheogorath 0d88707475
Update yarn.lock 2019-02-15 15:40:45 +01:00
Sheogorath bce58db97c
Update handlebar to version 4.0.13
Synk found an security vulnerbility in the version we provide, that in
theory can provide an RCE.

Details: https://snyk.io/vuln/SNYK-JS-HANDLEBARS-173692
2019-02-15 15:40:44 +01:00
Claudius Coenen baefa1c672
Merge pull request #1148 from felixonmars/patch-1
Fix several typos in auth/saml.md
2019-02-14 23:19:40 +01:00
Felix Yan 1ccadec5a3 Fix several typos in auth/saml.md
Signed-off-by: Felix Yan <felixonmars@archlinux.org>
2019-02-15 04:14:17 +08:00
Luclu7 d982d8aaf2
Corrected a typo
Signed-off-by: Luclu7 <me@luclu7.fr>
2019-02-07 20:47:43 +01:00
Christoph (Sheogorath) Kern b28201176e Update ja.json (POEditor.com) 2019-01-31 13:06:56 +01:00
Sheogorath 806f403045
Disable OpenID by default
We talked about that during a community call. It turned out that not
everyone likes to have OpenID on their instance.

This patch disables OpenID by default.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2019-01-25 19:31:34 +01:00
Christoph (Sheogorath) Kern afcbea48cd
Merge pull request #1127 from SISheogorath/fix/unlinkFix
Fix broken PDF export by wrong unlink call
2019-01-25 18:27:33 +01:00
Sheogorath 4e81079050
Fix broken PDF export by wrong unlink call
We used `fs.unlink()` to remove the pdf file after we send it out to the
client. This breaks in Node 10, when no function as second parameter is
supplied.

This patches changes it to the `fs.unlinkSync` function that doesn't
have this requirement and this way doesn't crash.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2019-01-24 13:02:53 +01:00
Sheogorath 3dc40116e4
Update yarn.lock
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2019-01-24 12:21:19 +01:00
Claudius Coenen 2c1a618c56
Merge pull request #1125 from hackmdio/dependency-node-6-fix
Fixing deep dependency problem with node 6.x
2019-01-24 01:18:07 +01:00
Claudius Coenen fa0dea0a1b Fixing deep dependency problem with node 6.x
this commit has been blatantly stolen from @samselikoff in ember-cli-addon-docs. It prevents an issue introduced via a deep dependency that no longer supports node 6 (which we still would like to support).
see: 231275b5a4
see: https://github.com/salesforce/tough-cookie/pull/141

Signed-off-by: Claudius Coenen <opensource@amenthes.de>
2019-01-23 23:37:13 +01:00
Christoph (Sheogorath) Kern a9d12e3a28
Merge pull request #1124 from phrix32/patch-1
Fix reference to SAML guide in README
2019-01-22 11:03:20 +01:00
Jonathan 07697ee9a1 Fix reference to SAML guide in README
Signed-off-by: Jonathan Klauck <jonathan.klauck@aoe.com>
2019-01-22 10:48:45 +01:00
Christoph (Sheogorath) Kern d69edd1def
Merge pull request #1123 from SISheogorath/fix/lintingTests
Add linting for tests
2019-01-21 23:16:22 +01:00
Sheogorath bf229d91c6
Add linting for tests
The tests are currently not linted. This causes a different coding style
than the rest of the sources.

This patch adds the `./test` directory to the eslint testing and fixes
linting for existing tests.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2019-01-21 17:17:54 +01:00
Christoph (Sheogorath) Kern 3a23bd7c05
Merge pull request #1121 from SISheogorath/test/CSP
Add tests for csp.js
2019-01-21 17:14:51 +01:00
Sheogorath d408f4c0fe
Add tests for csp.js
Since we lack of tests but got some great point to start, let's write
more tests.

This patch provides some basic tests for our CSP library. It's more an
integration than a unit test, but gets the job done.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2019-01-19 13:54:52 +01:00
Sheogorath 5f1406a136
Update yarn.lock
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2019-01-18 22:04:22 +01:00
Christoph (Sheogorath) Kern b88a1ed04a
Merge pull request #1116 from dsprenkels/manage_users
Fix broken manage_users after Winston upgrade
2019-01-12 15:09:12 +01:00
Christoph (Sheogorath) Kern 4eb9d6941d
Merge pull request #1117 from SISheogorath/upgrade/bootstrap
Update bootstrap from 3.3.7 to 3.4.0
2019-01-12 15:08:54 +01:00
Sheogorath 62477f0279
Update bootstrap from 3.3.7 to 3.4.0
Seems like finally there is a new bootstrap version for old version 3.

This patch implements this new version with CodiMD and this way fixes
some possible security issues in the frontend code.

See:
https://snyk.io/vuln/SNYK-JS-BOOTSTRAP-72889
https://snyk.io/vuln/SNYK-JS-BOOTSTRAP-72890

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2019-01-11 01:56:52 +01:00
Daan Sprenkels 7c144ac7a9 Fix broken manage_users after Winston upgrade
Commit c3584770 upgrades Winston and with that version
`logger.transports.console` becomes undefined. This commit
updates the code to prevent the crash.

Signed-off-by: Daan Sprenkels <hello@dsprenkels.com>
2019-01-10 14:05:12 +01:00
Christoph (Sheogorath) Kern 4eb7748adb
Merge pull request #1114 from SISheogorath/fix/samlVersion
Update SAML to version 1.0.0
2019-01-09 11:53:11 +01:00
Sheogorath 9eb4e545d2
Update SAML to version 1.0.0
Seems like there was a security problem with the library.

This patch updates to version 1.0.0 which fixed the details.

Details: https://snyk.io/vuln/SNYK-JS-PASSPORTSAML-72411

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2019-01-09 01:15:02 +01:00
Christoph (Sheogorath) Kern 7a83fc0f14
Merge pull request #1110 from dsprenkels/issue_1106
Remove blueimp-md5 dependency
2019-01-05 14:08:23 +01:00
Christoph (Sheogorath) Kern dba9575c94
Merge pull request #1112 from hackmdio/fix-XSS-issues
Fix some XSS issues
2018-12-29 21:52:03 +01:00
Max Wu 067cfe2d1e Fix to escape html comment tag [Security Issue]
Signed-off-by: Max Wu <jackymaxj@gmail.com>
2018-12-28 16:42:55 +08:00
Max Wu b89a35196a
Fix to sanitize disqus shortnames to remove slashes [Security Issue]
Signed-off-by: Max Wu <jackymaxj@gmail.com>
2018-12-28 16:39:13 +08:00
Daan Sprenkels f7bc1e99c0 Remove blueimp-md5 dependency
Signed-off-by: Daan Sprenkels <hello@dsprenkels.com>
2018-12-22 19:09:50 +01:00
Daan Sprenkels 318a37d41c Add a test for gravatar urls
Signed-off-by: Daan Sprenkels <hello@dsprenkels.com>
2018-12-22 19:09:45 +01:00
Davide Depau 3a14801a8b Merge branch 'master' into DepauMD 2018-12-22 03:00:12 +01:00
Christoph (Sheogorath) Kern f9cc2ff0ef
Merge pull request #1105 from SISheogorath/fix/gistCSP
Fix broken Gist embedding
2018-12-21 18:39:22 +01:00
Christoph (Sheogorath) Kern e4845849dc
Merge pull request #1108 from dsprenkels/patch-1
Update upload provider error message
2018-12-21 18:38:49 +01:00
Daan Sprenkels 8835a09d95 Update upload provider error message
Fixes #1107.

Signed-off-by: Daan Sprenkels <hello@dsprenkels.com>
2018-12-21 15:30:06 +01:00
Davide Depau 4395b1dcfa Merge branch 'master' into DepauMD 2018-12-21 03:00:12 +01:00
Sheogorath 0f9e367015
Fix broken Gist embedding
Looks like GitHub changed their asset system and our CSP prevented them
from getting loaded.

This patch should fix the Gist embedding with enabled CSP by replacing
the old URL `https://assets-cdn.github.com` with the new
`https://github.githubassets.com`.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-12-20 22:49:25 +01:00
Christoph (Sheogorath) Kern f492fea418
Merge pull request #1103 from SISheogorath/fix/localImageUpload
Fix usage of new URL API
2018-12-20 22:42:17 +01:00
Sheogorath 0621d7a72d
Fix usage of new URL API
Due to the deprecation of the old `url`-API provided by NodeJS we
replaced `url.resolve` with `url.URL.resolve`, which doesn't exist.

This patch fixes the local filesystem upload of CodiMD by using the new
API correctly. Creating an URL object and using its href.

Some more background:
https://nodejs.org/api/url.html#url_url_href
https://nodejs.org/api/url.html#url_url_resolve_from_to

Fixes https://github.com/hackmdio/codimd/issues/1102

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-12-18 14:52:18 +01:00
Davide Depau 84f948aa9a Merge branch 'master' into DepauMD 2018-12-15 03:00:13 +01:00
Christoph (Sheogorath) Kern 17b1b5d6bf Update ru.json (POEditor.com) 2018-12-13 00:10:57 +01:00
Davide Depau 0a02264625 Merge branch 'master' into DepauMD 2018-12-07 03:00:16 +01:00
Christoph (Sheogorath) Kern 7f0fe6903c
Merge pull request #1091 from SISheogorath/fix/speakerNotesCSP
Fix CSP for speaker notes
2018-12-06 10:35:41 +01:00
Christoph (Sheogorath) Kern b9848a4f7c
Merge pull request #1092 from SISheogorath/fix/disqusCSP
Fix disqus CSP
2018-12-06 10:35:24 +01:00
Sheogorath ecee16bd73
Fix disqus CSP
Disqus loads it's embed config.js from its root domain
(https://disqus.com). Our CSPs only allow subdomains (e.g.:
https://codimd.disqus.com). This causes the disqus embedding to fail.

This patch should fix this problem by adding https://disqus.com to the
CSP setting. From a security perspective there is no real change. Since
still the same parties are involved.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-12-05 13:17:14 +01:00
Sheogorath a556575b91
Fix CSP for speaker notes
Looks like I was wrong in my previous commit to update revealjs.[1]

The speaker notes broke again with the CSPs. So this patch updates the
hash and this way the speaker notes.

[1]: bcebf1e8d2

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-12-05 11:32:14 +01:00
Davide Depau 650084daff Merge branch 'master' into DepauMD 2018-12-05 03:00:12 +01:00
Sheogorath b40f14f66d
Update yarn.lock
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-12-04 14:04:34 +01:00
Davide Depau 107f4d03bd Merge branch 'master' into DepauMD 2018-12-02 00:40:31 +01:00
Christoph (Sheogorath) Kern 3cfd18d54f
Merge pull request #1085 from SISheogorath/update/socket.io
Update socket.io
2018-12-01 12:25:18 +01:00
Christoph (Sheogorath) Kern 786140331b
Merge pull request #1086 from SISheogorath/feature/urlWarning
Warn on missing serverURL
2018-12-01 12:25:02 +01:00
Davide Depau 84dce80bc9 Merge branch 'master' into DepauMD 2018-11-29 03:00:13 +01:00
Sheogorath a4941be3de
Warn on missing serverURL
We see some issues that are based on not properly configured
`config.serverURL`.

This patch adds a warning when `config.serverURL` is an empty value.
This should provide users direct feedback about how to improve their
configs.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-11-28 14:38:49 +01:00
Christoph (Sheogorath) Kern b749d50e20
Merge pull request #1082 from cloudyu/pull
Fix wrong config options

In `./lib/web/auth/` some config includes still used `config.serverurl` instead of the correct `config.serverURL`. This causes wrong URL in worst case.

This patch should fix those problems and migrate the wrong statements to camelcase.
2018-11-28 13:27:38 +01:00
Sheogorath cf95465103
Update socket.io
Our socket.io version is 2.0.4 while the current socket.io version is
2.1.1.

This patch updates socket.io to version 2.1.1 and takes care of the CDN
client version.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-11-28 13:23:36 +01:00
Christoph (Sheogorath) Kern 769a1c4ccb
Merge pull request #1084 from dsprenkels/export-subdirs
Prevent subdirectories in user export
2018-11-28 10:26:41 +01:00
Daan Sprenkels 9fba268288 Prevent subdirectories in user export
This commit also refactors the code a bit, and adds a '-' separator
between a filename and its duplicate index.

This commit fixes #1079.

Signed-off-by: Daan Sprenkels <hello@dsprenkels.com>
2018-11-28 09:13:28 +01:00
CloudYu 35a9f72a06 Fix typo
Signed-off-by: CloudYu <cloudyu322@gmail.com>
2018-11-27 22:14:37 +08:00
Davide Depau b72b3b48fe Merge branch 'master' into DepauMD 2018-11-26 23:59:06 +01:00
Davide Depau 4f47ce33bb Merge branch 'master' into DepauMD 2018-11-26 23:58:51 +01:00
Christoph (Sheogorath) Kern 8bace89cab
Merge pull request #1072 from SISheogorath/update/doctoc
Update doctoc to version 1.4.0
2018-11-24 17:36:16 +01:00
Christoph (Sheogorath) Kern 4856aa2840
Merge pull request #1069 from SISheogorath/fix/to-markdown
Update from to-markdown to turndown
2018-11-24 17:35:53 +01:00
Christoph (Sheogorath) Kern 6d0c3ccd23
Merge pull request #1071 from SISheogorath/fix/node-uuid
Remove node-uuid
2018-11-24 17:35:38 +01:00
Sheogorath 494a0d5f06
Add some missing translations
There are some places in our code that made it to be not translated.

This patch fixes some small translation problems and adds some static
strings in templates to translation.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-11-23 17:10:44 +01:00
Christoph (Sheogorath) Kern 4a623c95db Update ko.json (POEditor.com) 2018-11-23 12:10:14 +01:00
Christoph (Sheogorath) Kern bf1f14d17c Update it.json (POEditor.com) 2018-11-23 12:10:11 +01:00
Sheogorath 306c25d8f7
Update doctoc to version 1.4.0
When installing doctoc it throws some warnings about the markdown-to-ast
package that moved to an own namespace.

This patch updates to the version containing the new, namespaced,
package.

References:
https://github.com/thlorenz/doctoc/pull/151

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-11-21 16:43:26 +01:00
Sheogorath 1091efc259
Remove node-uuid
We currently install `uuid` and `node-uuid`. `node-uuid` is deprecated
in favor of `uuid`. It seems like we already switched a while ago, but
somehow missed to remove the dependency.

This patch does exactly that. It removes the dependency from
`package.json` and this way removes the warning during install about
`node-uuid` being deprecated.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-11-21 11:38:40 +01:00
Sheogorath f9929605af
Update yarn.lock
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-11-21 11:34:56 +01:00
Christoph (Sheogorath) Kern 41fd4f0d66
Merge pull request #1070 from SISheogorath/fix/configExample
Fix typo in config.json.example
2018-11-21 11:32:00 +01:00
Sheogorath fb46e188b8
Fix typo in config.json.example
We recently added the new logging option. As it turns out, the new
option was not added correctly, which points out that our current json
linting is **not working**. It throws an error but doesn't break.

This patch fixes the typo in the example. It does not fix the CI part.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-11-21 11:17:59 +01:00
Sheogorath 33774c11b9
Update from to-markdown to turndown
We got a security alert for a regular expression DoS attack on our used
library `to-markdown`.

After checking `to-markdown` to be maintained or not, it turned out they
renamed the library to `turndown`. So upgrading to `turndown` should fix
this vulnerbility.

References:
https://www.npmjs.com/package/to-markdown
https://github.com/domchristie/turndown/wiki/Migrating-from-to-markdown-to-Turndown
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-11-21 11:12:09 +01:00
Christoph (Sheogorath) Kern 2323d203b4
Merge pull request #1063 from SISheogorath/fix/nodeVersion
After removing ws, node version 10 should work
2018-11-21 01:42:35 +01:00
Christoph (Sheogorath) Kern 26b617b032
Merge pull request #1066 from SISheogorath/update/scrypt
Switch scrypt library to a successor
2018-11-21 01:42:19 +01:00
Sheogorath cee2aa92f9
Switch scrypt library to a successor
Since our previous scrypt library is unmaintained since 3 years, it's
time to look for an alternative.

A refactoring towards another password algorithm was worked on and this
is probably still the way to go. But for now the successor of our
previous library should already be enough.

https://www.npmjs.com/package/scrypt (old library)
https://github.com/ml1nk/node-scrypt (new library)
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-11-21 01:33:34 +01:00
Christoph (Sheogorath) Kern 234171e117
Merge pull request #1065 from SISheogorath/update/reveal.js
Update reveal.js to version 3.7.0
2018-11-21 01:29:52 +01:00
Christoph (Sheogorath) Kern 2244b11730
Merge pull request #1064 from SISheogorath/fix/hstsSeconds
Fix wrong maxAgeSeconds multiplication
2018-11-21 01:29:04 +01:00
Sheogorath bcebf1e8d2
Update reveal.js to version 3.7.0
There is a new reveal.js version out. As we try to keep up with
upstream, time to integreate it.

This patch updates reveal.js in for CDN-using instances as well as the
ones using the libraries.

Checked that speaker view in slide mode still works, so no CSP change
needed.

https://github.com/hakimel/reveal.js/releases/tag/3.7.0
2d241b9300/lib/csp.js (L72-L74)
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-11-19 22:31:05 +01:00
Sheogorath 2d241b9300
Update yarn.lock
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-11-19 22:06:37 +01:00
Sheogorath 0aa3116805
Fix wrong maxAgeSeconds multiplication
It seems like the inital work on the hsts module expected milliseconds.
This has either changed or was never true. Either way, it caused that
the current defaults resulted in theory in a 1000 year HSTS policy.
Luckily helmet was smart enough to not go higher than 1 year.

Anyway, this patch fixes the multiplication of the configured size with
1000 by removing this multiplication.

Also to simplify the reading of the defaults, we split them into their
components, 60 times 60 seconds so we get one hour. 24 of those hours so
we get a day and finally 365 days to get our original wanted default of
one year.

Reference:
d69d65ea74
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-11-19 22:01:54 +01:00
Christoph (Sheogorath) Kern 271dff3808
Merge pull request #1043 from SISheogorath/fix/tocEmptyHead
Fix ToC breaking documents with empty h* elements
2018-11-19 21:33:34 +01:00
Sheogorath d6dd33620c
Fix wrong anchors
While experimenting with the ToC changes, it became obvious that anchors
for those unnamed headers don't work.

This patch fixes those links by running the autolinkify twice and make
sure linkify only adds links to non-empty ids.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-11-19 20:20:56 +01:00
Sheogorath e3b6bcc5f8
After removing ws, node version 10 should work
In my local environment I switched to Fedora 29. Fedora 29 comes with
NodeJS version 10.

As far as I can say, it works, so let's try to remove the restriction to
"<10.x"

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-11-19 18:42:28 +01:00
Sheogorath 9951b7df7c
Fix ToC breaking documents with empty h* elements
Right now, the ToC has an undefined variable i that was an index in the
original ToC code. Since the major rewrite in
4fe0620853 it's a recursive function
without this index. The variable `i` was wrongly copied into its current
place from the old code.

This patch replaces the variable `i` with the index of the header
element. Fix the undefined variable problem.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-11-19 18:27:06 +01:00
Christoph (Sheogorath) Kern f46a84ab54
Merge pull request #1061 from SISheogorath/feature/updateHints
Add hints about how to be informed about updates
2018-11-19 01:11:00 +01:00
Christoph (Sheogorath) Kern 9a267ed0dd Update de.json (POEditor.com) 2018-11-18 17:22:45 +01:00
Christoph (Sheogorath) Kern 6d05c6d479 Update fr.json (POEditor.com) 2018-11-18 17:22:42 +01:00
Christoph (Sheogorath) Kern 6cc6d564a1 Update nl.json (POEditor.com) 2018-11-18 17:22:39 +01:00
Christoph (Sheogorath) Kern 435341c557 Update zh-TW.json (POEditor.com) 2018-11-18 17:22:36 +01:00
Christoph (Sheogorath) Kern 120dcc3dae Update zh-CN.json (POEditor.com) 2018-11-18 17:22:33 +01:00
Christoph (Sheogorath) Kern 9a8614ea8b Update de.json (POEditor.com) 2018-11-18 12:38:31 +01:00
Christoph (Sheogorath) Kern 651c4be7b8 Update fr.json (POEditor.com) 2018-11-18 12:38:28 +01:00
Christoph (Sheogorath) Kern 4f071fba7d Update nl.json (POEditor.com) 2018-11-18 12:38:25 +01:00
Christoph (Sheogorath) Kern 96efb09a38 Update zh-TW.json (POEditor.com) 2018-11-18 12:38:22 +01:00
Christoph (Sheogorath) Kern d8fcc83d37 Update zh-CN.json (POEditor.com) 2018-11-18 12:38:19 +01:00
Christoph (Sheogorath) Kern 4b212c8315
Merge pull request #1060 from SISheogorath/fix/indexLinks
Fixing links on index page
2018-11-18 02:46:39 +01:00
Sheogorath 62cad26e08
Add hints about how to be informed about updates
Keeping people in the loop about new version of CodiMD is not easy. When
people don't keep an eye on GitHub it's easy to miss new versions.

To help people keeping their software up to date, this patch adds hints
to check out our community channel or simply the GitHub Atom feed
generated for based on the release page to get informed about new
versions.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-11-18 02:16:04 +01:00
Christoph (Sheogorath) Kern af06d38781 Update nl.json (POEditor.com) 2018-11-18 00:51:00 +01:00
Sheogorath 71ce7921bd
Fixing links on index page
Seems like ids in Firefox are case sensitive. So linking in the current
way fails.

This patch fixes the links by using the exact matching version of the
titles on the features page.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-11-18 00:26:51 +01:00
Christoph (Sheogorath) Kern 5f0d04334b
Merge pull request #1053 from dsprenkels/robots.txt
Disallow creation of robots.txt in freeurl
2018-11-17 13:30:06 +01:00
Daan Sprenkels 4bd8d7eb91 Disallow creation of robots.txt in freeurl
Add a configuration setting to "hard"-disable creation of notes as
set by the configuration value. This defaults to `['robots.txt',
'favicon.ico']`, because these files are often accidentally created
by bots and browsers.

This commit fixes #1052.

Signed-off-by: Daan Sprenkels <hello@dsprenkels.com>
2018-11-17 13:23:03 +01:00
Christoph (Sheogorath) Kern 6f7fd74b1a
Merge pull request #943 from SISheogorath/feature/improveSetup
Some minor improvements for setup script
2018-11-17 12:42:24 +01:00
Christoph (Sheogorath) Kern 1e2bf3698f
Merge pull request #1040 from sunbit/master
Fix migration failure due to change on error messages
2018-11-17 12:34:15 +01:00
Christoph (Sheogorath) Kern 7328e7ad79
Merge pull request #1059 from SISheogorath/fix/winstonStreaming
Fix streaming for winston
2018-11-17 11:36:56 +01:00
Carles Bruguera 5da10c0e2c Update error message text checks
Signed-off-by: Carles Bruguera <carlesba@gmail.com>
2018-11-16 23:53:50 +01:00
Sheogorath bdeb053397
Fix streaming for winston
During the upgrade of winston in
c3584770f2 a the class extension for
streaming was removed.

This caused silent crashes. Somehow winston simply called
`process.exit(1)` whenever `logger.write()` was called. This is really
bad and only easy to debug because of the testing right after upgrading.

However, reimplementing the stream interface as it was, didn't work, due
to the fact that `logger.write()` is already implemented and causes the
mentioned problem. So we extent the object with an `stream` object that
implements `write()` for streams and pass that to morgan.

So this patch fixes unexpected exiting for streaming towards our logging
module.

References:
https://www.digitalocean.com/community/tutorials/how-to-use-winston-to-log-node-js-applications
c3584770f2
https://stackoverflow.com/a/28824464
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-11-16 11:49:39 +01:00
Christoph (Sheogorath) Kern f1367ba270
Merge pull request #1058 from ccoenen/bug/oauth2internalerror
InternalOAuthError is not part of passport, but of passport-oauth2 #1056
2018-11-16 11:45:50 +01:00
Christoph (Sheogorath) Kern db69983a62
Merge pull request #1057 from ccoenen/eslint
switching to eslint for code checking
2018-11-16 11:45:20 +01:00
Claudius Coenen 858a59529e switching to eslint for code checking
most rules degraded to WARN, so we don't go insane. This will
change over time. The aim is to conform to a common style

Signed-off-by: Claudius Coenen <opensource@amenthes.de>
2018-11-14 23:15:36 +01:00
Claudius Coenen 56c043424d InternalOAuthError is not part of passport, but of passport-oauth2
This fixes part of #1056: an error while obtaining the profile
would have `502`-crashed the server.

Signed-off-by: Claudius Coenen <opensource@amenthes.de>
2018-11-14 14:38:47 +01:00
Christoph (Sheogorath) Kern f9aa001ee7
Merge pull request #1055 from SISheogorath/upgrade/winston
Upgrade winston / refactor logging
2018-11-14 12:13:43 +01:00
Christoph (Sheogorath) Kern fc49326b94
Merge pull request #1047 from SISheogorath/docs/slideMode
Add documentation for document type
2018-11-14 10:49:59 +01:00
Sheogorath d94271c81a
Add documentation for slide view mode to features page
Since it's a very useful feature, we should mention it in multiple 
locations.

So we mention it in the slide mode section of the features page.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-11-14 01:06:20 +01:00
Sheogorath 43021283e4
Some minor improvements to the yaml-metadata docs
Switching form XAML to YAML syntax highlighting and fixing some grammar.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-11-14 01:06:20 +01:00
Sheogorath 3020c11d11
Add documentation for type field
The yaml-metadata documentation should mention the type field. This is
also open for future extension.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-11-14 01:06:20 +01:00
Sheogorath 44ca7be294
Activate slide editing mode for example
We have this awesome editing mode for slide shows. We just don't enable 
it or tell anyone that it exists. Maybe we should do this.

This patch sets the type for the slide example.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-11-14 01:04:56 +01:00
Sheogorath c3584770f2
Upgrade winston
Our log library got a new major version which should be implemented.

That's exactly what this patch does. Implementing the new version of the
logging library.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-11-14 00:47:11 +01:00
Christoph (Sheogorath) Kern df2a2e6c6c
Merge pull request #1054 from SISheogorath/fix/otLogging
Fix logging in ot module
2018-11-13 23:59:56 +01:00
Sheogorath 694fb37aea
Fix logging in ot module
Seems like there was some debugging going on some day, this patch should
make sure the right logging is used.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-11-13 23:30:13 +01:00
Christoph (Sheogorath) Kern 54d3d930cf
Merge pull request #1027 from asg017/master
Add download action to published notes
2018-11-12 22:11:44 +01:00
Christoph (Sheogorath) Kern 8ad3fdc3ca
Merge pull request #983 from SISheogorath/fix/disableIndexes
Enforce disabled index for static assets
2018-11-12 22:11:05 +01:00
Sheogorath e8ec9a8af4
Enforce disabled index for static assets
ExpressJS still does allow serving index.html files. This change
disables that permanently.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-11-12 21:42:55 +01:00
Christoph (Sheogorath) Kern 1d8c83cec5
Merge pull request #1028 from SISheogorath/docs/editorModes
Add documentation about editor modes in features page
2018-11-12 21:40:30 +01:00
Christoph (Sheogorath) Kern 51f095a02b
Merge pull request #1048 from dsprenkels/etherpad-migration-guide
Add an etherpad migration guide
2018-11-12 21:30:48 +01:00
Sheogorath 3d1b138a31
Update yarn.lock 2018-11-12 14:27:42 +01:00
Christoph (Sheogorath) Kern 4a39017fe0
Merge pull request #1051 from SISheogorath/feature/fullversion
Fix wrong reading from commit
2018-11-12 14:21:03 +01:00
Sheogorath 4b0528ac4f
Fix wrong reading from commit
Right now we use a substr after reading the commit. That's definitely
wrong and leads to wrong commit hashes since the first 5 chars are
missing.

This patch removes the substr usage here and this way fixes the
generated links.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-11-12 11:18:38 +01:00
Christoph (Sheogorath) Kern 2a8b56e14b
Merge pull request #1046 from SISheogorath/feature/optimizeXSS
Remove the xss library from webpack
2018-11-11 19:01:44 +01:00
Christoph (Sheogorath) Kern a1211abd32
Merge pull request #961 from SISheogorath/feature/osTEMP
Use OS based tmp dir
2018-11-11 19:00:58 +01:00
Christoph (Sheogorath) Kern ca9c4b3135
Merge pull request #991 from SISheogorath/feature/fullversion
Add full version string (and no AGPL violation detection)
2018-11-11 19:00:03 +01:00
Sheogorath bcc914a773
Add full version string
Currently we only provide the version from `package.json`. This means
that during updates of instances, e.g. the demo instance, which runs
latest master instead of a stable release, changes are not reflected to
the webclient.

This patch adds a fullversion string that contains the current commit
and this way makes that clients are notified about changes.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-11-11 12:44:19 +01:00
Daan Sprenkels 1f8e8b476f Add an etherpad migration guide
In this guide I share how a migration from etherpad to codimd can
be done. I am not completely sure if the script that is included is
completely error-free. Readers/reviewers should be aware that there
may be bugs.may be bugs.

Signed-off-by: Daan Sprenkels <hello@dsprenkels.com>
2018-11-10 23:48:03 +01:00
Sheogorath c59b94a37b
Remove the xss library from webpack
We can load the xss functions directly from the library instead of
loading them through the expose loader of webpack, this should simplify
the setup and maybe even improve speed a bit.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-11-10 20:27:07 +01:00
Christoph (Sheogorath) Kern 4e5e7df4f8
Merge pull request #1041 from micedre/export-menu-fix
Fix menu when gitlab is enabled
2018-11-07 13:35:10 +01:00
Cédric Couralet 67f8a64f2b Fix menu for github and dropbox
Signed-off-by: Cédric Couralet <cedric.couralet@gmail.com>
2018-11-07 12:30:17 +00:00
Cédric Couralet d24fb48f16 Fix menu when gitlab is enabled
Signed-off-by: Cédric Couralet <cedric.couralet@gmail.com>
2018-11-07 11:32:20 +00:00
Christoph (Sheogorath) Kern dbcb469fd3
Merge pull request #1033 from SISheogorath/fix/versions
Upgrade some package versions
2018-11-06 19:12:30 +01:00
Christoph (Sheogorath) Kern e17522add9
Merge pull request #1034 from SISheogorath/fix/emojiPlugin
Again: Replace emoji-plugin regex
2018-11-06 19:11:56 +01:00
Claudius Coenen 64e9dfd714
Merge pull request #1035 from ccoenen/feature/global-site-layout-vars
removing global site layout vars from individual routers
2018-11-05 00:35:48 +01:00
Claudius 44ffc564da removing global site layout vars from individual routers, putting them into app.local
Signed-off-by: Claudius <opensource@amenthes.de>
2018-11-03 00:52:48 +01:00
Sheogorath d188b3526a
Again: Replace emoji-plugin regex
The Regex introduced in the last commit[1], was already working quite
good. But still resulted in false positives for all URL that contained a
second `:`.

To fix this once and for all, we craft a simple, but long regex based on
all emoji names and use this to match them.

We could probably optimize it, but that should also be something the
regex engine itself can and should do.

[1]: 7e45533c75 (in this source tree)

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-10-31 15:33:45 +01:00
Davide Depau af995b048d Merge branch 'master' into DepauMD 2018-10-31 03:00:12 +01:00
Sheogorath 59b3885dda
Use OS based tmp dir
We should use the official OS temp directory instead of an own one, to
not run into conflicts. Also various dependencies already use the OS
temp directory, which makes it pointless to use a different for our
internal purposes then. This commit provides the changes needed to use
the OS tmp directory by default.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-10-31 00:37:11 +01:00
Christoph (Sheogorath) Kern 637f955bdd
Merge pull request #1030 from Eronana/patch-1
add option reset in bin/manage_users
2018-10-31 00:33:57 +01:00
Christoph (Sheogorath) Kern d79301a00d
Merge pull request #1031 from SISheogorath/fix/emojiPlugin
Fix emoji regex
2018-10-31 00:30:23 +01:00
Sheogorath 77b2757a16
Upgrade some package versions
`npm audit` reports a ton of issues on CodiMD. Most of them are minor
issues, but these are still things that should be fixed.

This changes were created by running `npm audit fix`.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-10-31 00:27:53 +01:00
Sheogorath 7e45533c75
Fix emoji regex
The old regex, adapted from the other plugins, was a bit too open for
matching. This leads to matching something like: `This is a sentence:
[And something with a: in it.]()` which doesn't become a link anymore.
Because the match is: ` [And something with a`.

This patch provides a fix for the regex to only match non-space string
within the `:`'s.

References:
- Introducing commit:
2063eb8bdf
- Inspirational source of the original RegEx:
2063eb8bdf/public/js/extra.js (L1095)

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-10-29 20:37:47 +01:00
Erona 3abf1f04ed
feat(bin): ensure email exists
Signed-off-by: Erona <erona@loli.bz>
2018-10-29 23:11:32 +08:00
Erona e90d4d824b
feat(bin): add option --reset to reset user password
Signed-off-by: Erona <erona@loli.bz>
2018-10-29 23:11:32 +08:00
Erona 79842b82e8
refactor(bin): add function getPass in bin/manage_users
Signed-off-by: Erona <erona@loli.bz>
2018-10-29 23:11:32 +08:00
Erona 63626b1267
refactor(bin): eliminate `var` and use template string refactor string things
Signed-off-by: Erona <erona@loli.bz>
2018-10-29 23:11:32 +08:00
Erona 2f82e0c86a
refactor(bin): add function showUsage to refactor usage things
Signed-off-by: Erona <erona@loli.bz>
2018-10-29 23:11:19 +08:00
Erona 7b12945c49
refactor(bin): refactor check args in bin/manage_users
Signed-off-by: Erona <erona@loli.bz>
2018-10-29 22:34:45 +08:00
Davide Depau 6b2c7b1778 Merge branch 'master' into DepauMD 2018-10-29 03:00:12 +01:00
Christoph (Sheogorath) Kern 279213eb75 Update it.json (POEditor.com) 2018-10-28 10:12:40 +01:00
Christoph (Sheogorath) Kern 73ff7fea5b Update fr.json (POEditor.com) 2018-10-28 10:12:37 +01:00
Sheogorath 0915b33000
Add documentation about editor modes in features page
Codemirror provides various modes via keymapping. These are already
available by a menu in the interface. But they aren't mentioned
anywhere.

This patch provides some documentation about the editor modes and their
implications. Since they are a feature, the documentation is done on the
features page.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-10-28 10:01:47 +01:00
Alex Garcia fcf08f89c3 forgot break statement
Signed-off-by: Alex Garcia <alexsebastian.garcia@gmail.com>
2018-10-27 17:54:01 -07:00
Alex Garcia 5b789025f3 Add download action to published notes
Signed-off-by: Alex Garcia <alexsebastian.garcia@gmail.com>
2018-10-27 16:55:14 -07:00
Davide Depau e8e503ceda Merge branch 'master' into DepauMD 2018-10-23 03:00:11 +02:00
Christoph (Sheogorath) Kern 152dfc2323
Merge pull request #997 from SISheogorath/docs/slidePrint
slide example: Add link to slide printing instructions
2018-10-22 23:03:11 +02:00
Christoph (Sheogorath) Kern e115423d12
Merge pull request #1006 from SISheogorath/fix/missingEmojis
Fix not rendered autocomplete emojis
2018-10-22 23:02:33 +02:00
Davide Depau 8458e18c51 Merge branch 'master' into DepauMD 2018-10-20 03:00:10 +02:00
Christoph (Sheogorath) Kern 26a65322a4
Merge pull request #1021 from davidmehren/webpack-4
Webpack: Cleanup common config
2018-10-19 14:42:02 +02:00
David Mehren 098908fb25
Code style fixes for webpack.common.js
Signed-off-by: David Mehren <dmehren1@gmail.com>
2018-10-19 12:46:44 +02:00
David Mehren 8264f50062
Use const instead of var in webpack configs.
Signed-off-by: David Mehren <dmehren1@gmail.com>
2018-10-19 12:46:39 +02:00
Davide Depau a1d0a8c30c Merge branch 'master' into DepauMD 2018-10-18 03:00:10 +02:00
Christoph (Sheogorath) Kern c97027b897
Merge pull request #1018 from SISheogorath/remove/gitter
Remove Gitter from codebase
2018-10-17 16:03:27 +02:00
Davide Depau 627650c57c Merge branch 'master' into DepauMD 2018-10-17 03:00:30 +02:00
Sheogorath 7d5abadcf7
Remove Gitter from codebase
We no longer use Gitter for development talk and similar. So we might
want to remove it?

This patch removes Gitter from README, help page and features page. And
replaces it in the help modal with POEditor, our translation platform.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-10-17 02:28:19 +02:00
Christoph (Sheogorath) Kern dba56b6f33
Merge pull request #1017 from MartB/master
Fix #1016: webpack include defect for scripts and header files.
2018-10-16 13:31:08 +02:00
MartB 6bce9ac5bf Fix #1016: webpack include defect for scripts and header files.
Signed-off-by: MartB <mart.b@outlook.de>
2018-10-16 11:40:21 +02:00
Davide Depau 55d4e230b3 Merge branch 'master' into DepauMD 2018-10-16 03:00:22 +02:00
Christoph (Sheogorath) Kern e47442c604 Update de.json (POEditor.com) 2018-10-15 10:10:00 +02:00
Davide Depau 1c7200b098 Merge branch 'master' into DepauMD 2018-10-13 03:00:10 +02:00
Christoph (Sheogorath) Kern d3ec67bbd7 Update pl.json (POEditor.com) 2018-10-12 07:45:37 +02:00
Christoph (Sheogorath) Kern 5fd8b77f80 Update fr.json (POEditor.com) 2018-10-12 07:44:03 +02:00
Davide Depau 13a10da740 Merge branch 'master' into DepauMD 2018-10-12 03:00:11 +02:00
Christoph (Sheogorath) Kern 1abf7c54ae
Merge pull request #1004 from SISheogorath/feature/integrateHljs
Add autocomplete for highlight.js languages into codemirror
2018-10-11 17:30:03 +02:00
Davide Depau b665a62323 Merge branch 'master' into DepauMD 2018-10-11 03:00:12 +02:00
Sheogorath a7281a5275
Update yarn.lock
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-10-11 00:23:23 +02:00
Christoph (Sheogorath) Kern 763b000bc6
Merge pull request #985 from SISheogorath/fix/helmetCSP
Add `data:` URL to CSP and upgrade helmet
2018-10-11 00:19:24 +02:00
Christoph (Sheogorath) Kern 4bce4b1635
Merge pull request #989 from SISheogorath/remove/octicon
Remove dead package octicon
2018-10-11 00:19:00 +02:00
Sheogorath 1d452a6ed4
Remove dead package octicon
Octicon no longer provides its CSS classes and this way is useless in
CodiMD. Replacing all used classes in the UI and remove it from build
system.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-10-10 23:42:41 +02:00
Christoph (Sheogorath) Kern bf525e43d4
Merge pull request #1007 from davidmehren/webpack-4
Webpack 4 refactor & docs
2018-10-10 23:38:13 +02:00
David Mehren 7eed584c01
Update yarn.lock
Signed-off-by: David Mehren <dmehren1@gmail.com>
2018-10-10 22:09:46 +02:00
David Mehren ea027c9b19
Add dev-docs for webpack.
Signed-off-by: David Mehren <dmehren1@gmail.com>
2018-10-10 22:09:46 +02:00
David Mehren 9f92bba036
Use webpack-merge.
Move html export config to own file.
Delete unnecessary config options.
Use cheap source maps.

Signed-off-by: David Mehren <dmehren1@gmail.com>
2018-10-10 22:09:46 +02:00
David Mehren 9a2dcd40d3
Rename Webpack config to official recommendation
Signed-off-by: David Mehren <dmehren1@gmail.com>
2018-10-10 22:09:46 +02:00
Sheogorath 2063eb8bdf
Fix not rendered autocomplete emojis
Currently we have some emojis that are autocompleted but won't show up
in the resulting document.

This patch adds all emojis that are pushed to Codemirror and applies
them to the markdown rendering process, so they become usable.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-10-10 21:24:33 +02:00
Sheogorath 1a9df22680
Add autocomplete for highlight.js languages into codemirror
Right now we support code highlighting for rust, but it doesn't appear
in autocomplete of codemirror, because codemirror is not aware of it.

This patch lets highlightjs simply tell codemirror, what it supports and
adds this to the autocomplete list.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-10-10 11:13:52 +02:00
Davide Depau 008ce565b8 Merge branch 'master' into DepauMD 2018-10-10 03:00:10 +02:00
Sheogorath c7478c1694
Update yarn.lock
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-10-09 23:08:57 +02:00
Christoph (Sheogorath) Kern 535ee36a26
Merge pull request #993 from SISheogorath/feature/useForkAwesome
Replace font-awesome with fork-awesome
2018-10-09 21:58:15 +02:00
Christoph (Sheogorath) Kern 5c4df14bbc
Merge pull request #990 from SISheogorath/fix/oauthProviderName
Make oauth2 provider name accessible
2018-10-09 21:57:37 +02:00
Christoph (Sheogorath) Kern 482a91e15d
Merge pull request #1002 from micedre/fix-issue-1001
Fix #1001: get only project user is member of (and return max of results)
2018-10-09 09:16:34 +02:00
Christoph (Sheogorath) Kern 3817d580dd
Merge pull request #1000 from micedre/fix-issue-986
Fix #986 : Visibility is now transmitted with gitlab V4 api
2018-10-09 09:14:06 +02:00
Cédric Couralet d7987def7f Fix #1001: get only project user is member of (and return max of results)
Signed-off-by: Cédric Couralet <cedric.couralet@gmail.com>
2018-10-09 07:04:04 +00:00
Cédric Couralet 702f52f07c Fix #986 : Visibility is now transmitted with gitlab V4 api
Signed-off-by: Cédric Couralet <cedric.couralet@gmail.com>
2018-10-09 06:46:25 +00:00
Davide Depau aaf4f0ae96 Merge branch 'master' into DepauMD 2018-10-08 03:00:10 +02:00
Christoph (Sheogorath) Kern 466dc9bc21
Merge pull request #992 from SISheogorath/fix/maintainer
Fix maintainer and URL in package.json
2018-10-08 01:12:23 +02:00
Sheogorath 2ddc80fc20
slide example: Add link to slide printing instructions
The printing instructions seem to not be really clear. Linking the
reveal.js offical docs should help.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-10-07 15:21:29 +02:00
Christoph (Sheogorath) Kern 616dfdf543
Merge pull request #994 from xf-/patch-1
Update supported node.js version
2018-10-07 12:57:13 +02:00
Davide Depau 0b5129d01b Merge branch 'master' into DepauMD 2018-10-07 03:00:11 +02:00
Xaver Maierhofer fd54e3f3ac
Update supported node.js version
Support includes v9.x, but no v10.x

Signed-off-by: Xaver Maierhofer <xaver.maierhofer@xwissen.info>
2018-10-07 02:33:38 +02:00
Sheogorath 53ad4ef555
Update yarn.lock
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-10-06 15:56:18 +02:00
Christoph (Sheogorath) Kern 02d64cd56a
Merge pull request #942 from SISheogorath/feature/openID
Add OpenID to CodiMD
2018-10-06 15:48:01 +02:00
Davide Depau 15273cc4c5 Merge branch 'master' into DepauMD 2018-10-06 03:00:11 +02:00
Sheogorath 9f9c4089be
Add OpenID to CodiMD
With OpenID every OpenID capable provider can provide authentication for
users of a CodiMD instance. This means we have federated
authentication.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-10-05 22:43:32 +02:00
Christoph (Sheogorath) Kern 32af96aa37
Merge pull request #940 from WilliButz/fix-configurable-paths
enhance configurabiltiy of paths & make execution path-independent
2018-10-05 22:21:01 +02:00
Sheogorath 5212bbf9c4
Replace font-awesome with fork-awesome
This patch replaces font-awesome with its fork called fork-awesome.
Besides the fact that the newer versions of font-awesome can't be
shipped with distros like debian due to license issues, fork-awesome
also provides more FOSS related icons and builds on top of version 4.7.x
of font-awesome, which we used until this patch.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-10-05 21:52:08 +02:00
Sheogorath a006f53dea
Update URL to codimd's own URL
Since we have an own URL we should use it in here, since CodiMD and
HackMD are really drifting away from each other.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-10-05 19:36:45 +02:00
Sheogorath 36117195fa
Add myself as maintainer
Well, since I'm currently the maintainer of CodiMD, I should maybe
mentioned in the package.json, just in case someone is willing to
contact me about it.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-10-05 19:35:43 +02:00
Davide Depau deb2245bc3 Merge branch 'master' into DepauMD 2018-10-05 03:00:10 +02:00
Sheogorath 3d1d03fa87
Make oauth2 provider name accessible
Right now the feature exists but is almost not usable since the only way
to configure it is to know that it exists from reading the source code
and add it to config.json. This patch provides all needed changes so it
can be used by everyone including documentation.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-10-04 20:45:25 +02:00
Christoph (Sheogorath) Kern f186f73373
Merge pull request #982 from SISheogorath/feature/useNoOpener
Add rel="noopener" to target="_blank" links
2018-10-04 20:08:42 +02:00
Christoph (Sheogorath) Kern c35da4efe6
Merge pull request #988 from ccoenen/oauth2-docs
Oauth2 docs
2018-10-04 20:08:23 +02:00
Christoph (Sheogorath) Kern ada5f51694
Merge pull request #981 from SISheogorath/fix/devMode
Add development mode for webpack in package.json
2018-10-04 20:06:32 +02:00
Christoph (Sheogorath) Kern 03a4e3c0c2
Merge pull request #987 from ccoenen/nextcloud-oauth2
How to use Nextcloud as OAuth2 Provider for CodiMD
2018-10-04 20:04:29 +02:00
Claudius Coenen 423956c44d details about OAuth2 in general. Fixes #930
Signed-off-by: Claudius Coenen <opensource@amenthes.de>
2018-10-04 11:37:48 +02:00
Claudius Coenen a10f551023 How to use Nextcloud as OAuth2 Provider for CodiMD
Signed-off-by: Claudius Coenen <opensource@amenthes.de>
2018-10-04 11:06:33 +02:00
Sheogorath d4a9bb3c7e
Add `data:` URL to CSP and upgrade helmet
Seems like the old version of helmet had a problem with `data:`. This
patch upgrades to the latest version and adds the CSP rule to allow
Google Fonts and the offline version of it, to properly include the
fonts and no longer throw ugly error messages at us.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-10-04 03:04:36 +02:00
Davide Depau cc85d2d78c Merge branch 'master' into DepauMD 2018-10-04 03:00:11 +02:00
Sheogorath 75a23fe2c9
Add rel="noopener" to target="_blank" links
The noopener construct protects from some nasty clickjacking attacks. We
can apply them savely to all our links since we don't rely on the
previously used page.

Some more details: https://mathiasbynens.github.io/rel-noopener/

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-10-04 01:49:36 +02:00
Sheogorath a47d91dbd0
Add development mode for webpack in package.json
Seems like we have to explicitly tell the new webpack version that we
want to use the development environment. This provides us with source
maps and similar.

This patch adds the commandline option in our scripts in package.json

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-10-03 19:34:25 +02:00
Sheogorath d9ba11b21a
Update yarn.lock
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-10-03 19:31:56 +02:00
Christoph (Sheogorath) Kern 7ea2c3b55f
Merge pull request #974 from mcnesium/patch-1
fix image paths
2018-10-03 19:14:36 +02:00
Christoph (Sheogorath) Kern ae8fa41f92
Merge pull request #958 from SISheogorath/fix/uws
Replace `uws` with `ws` package
2018-10-03 16:54:35 +02:00
Christoph (Sheogorath) Kern edcd8a23ff
Merge pull request #932 from davidmehren/webpack-4
Upgrade to Webpack 4
2018-10-03 16:52:32 +02:00
Christoph (Sheogorath) Kern 7749a72f28
Merge pull request #968 from SISheogorath/docs/ldap-AD
Add documentation for an LDAP setup against Active Directory
2018-10-03 16:51:53 +02:00
Sheogorath da818384af
Update version to 1.2.1
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-10-03 16:24:36 +02:00
Sheogorath 7b10f0bed2
Update release notes for 1.2.1
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-10-03 16:24:36 +02:00
Sheogorath c402abb0a5
Revert "Remove unused dependency"
This reverts commit d2ded08f59.

Seems like the package is used for building the sqlite3 integration.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-10-03 13:23:10 +02:00
Christoph (Sheogorath) Kern 0bedc6f126
Merge pull request #979 from SISheogorath/fix/removeUnusedDependencies
Remove unused dependency
2018-10-03 13:02:15 +02:00
Sheogorath d2ded08f59
Remove unused dependency
This dependency where installed, but it seems like they were never used.
Seems like it's a remaining piece from the the prototyping phase of the
project.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-10-03 12:42:11 +02:00
Davide Depau ced1193401 Merge branch 'master' into DepauMD 2018-10-03 03:00:10 +02:00
Christoph (Sheogorath) Kern 14ac20df1c
Merge pull request #977 from SISheogorath/fix/newExample
Replace youtube example video on features page
2018-10-03 00:19:04 +02:00
Christoph (Sheogorath) Kern 6bd7616792
Merge pull request #976 from SISheogorath/feature/newFooter
Some minor footer improvements
2018-10-03 00:18:40 +02:00
Sheogorath e0e037b5e1
Replace youtube example video on features page
Since the youtube video on our feature page seems to have vanished, this
patch replaces it with an video of the blender foundation

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-10-02 12:55:08 +02:00
Sheogorath a1fe5f37f6
Some minor footer improvements
Removing copyrigt sign since we are not copyrighting things.

Changing hackmd.io to codimd.org since HackMD is more and more dividing
from CodiMD and may brings up wrong expectations.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-10-01 12:18:12 +02:00
mcnesium ac95c4e442 fix image paths in moved GitLab auth guide
Signed-off-by: mcnesium <git@mcnesium.com>
2018-09-30 11:09:01 +02:00
Davide Depau 3cb4d825c1 Merge branch 'master' into DepauMD 2018-09-28 03:00:10 +02:00
Sheogorath c03b42d5d4
Fix little bug in length limit
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-09-28 00:17:43 +02:00
Christoph (Sheogorath) Kern ffc28e06f3
Merge pull request #971 from SISheogorath/fix/gitlabWarning
Set default to `v4`
2018-09-27 22:45:12 +02:00
Sheogorath 57e6d3a482
Set default to `v4`
Seems like we didn't fix the problem with the last patch. This should
finally fix it.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-09-27 21:57:12 +02:00
Christoph (Sheogorath) Kern 55f7568985
Merge pull request #966 from SISheogorath/fix/documentLength
Fix document length limit on post
2018-09-27 20:10:50 +02:00
WilliButz 61e240192e
README: add note about configurable paths
Signed-off-by: WilliButz <wbutz@cyberfnord.de>
2018-09-27 12:08:29 +02:00
Davide Depau 1568a5eb83 Merge branch 'master' into DepauMD 2018-09-27 03:00:10 +02:00
Claudius bb80bc2292
removing superfluous config parameters for template files
Signed-off-by: Claudius <opensource@amenthes.de>
2018-09-26 21:01:15 +02:00
WilliButz 825ee4e66e
app.js: add missing routes for configurable paths
Signed-off-by: WilliButz <wbutz@cyberfnord.de>
2018-09-26 20:58:38 +02:00
WilliButz 12cd747270
imageRouter/filesystem: make callback path-independent
Images are now properly served when `config.uploadsPath`
differs from its default value.

Signed-off-by: WilliButz <wbutz@cyberfnord.de>
2018-09-26 20:55:15 +02:00
Sheogorath 3122e351cd
Add documentation for an LDAP setup against Active Directory
Since our documentation on our LDAP configs is quite small, I add this
example for LDAP in an Active Directory environment.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-09-26 19:13:07 +02:00
WilliButz 556783ffad
lib/config: use `path.resolve` instead of `path.join`
While paths like `tmpPath` could previously be configured,
they were all interpreted relative to `appRootPath` because
of `path.join`.

Now the configurable paths can be canonical and therefore
independent of the `appRootPath`.

Signed-off-by: WilliButz <wbutz@cyberfnord.de>
2018-09-26 16:56:37 +02:00
WilliButz e48852e0e2
lib/config: add environment variable to set config file
Previously it was assumed that `config.json` would be placed in
the same directory as the rest of CodiMD without any optional override.

This allows to override the path to the `config.json` by setting
`CMD_CONFIG_FILE` to the canonical path of the desired config file.

Signed-off-by: WilliButz <wbutz@cyberfnord.de>
2018-09-26 16:56:37 +02:00
WilliButz bd2f7cef49
lib/models/revision.js: make independent of exec-path
Previously calling `app.js` from another directory than
the base directory of CodiMD would result in an error being
thrown because `lib/workers/dmpWorker.js` could not be found.

This change makes the function call independent of the path CodiMD
is started from.

Signed-off-by: WilliButz <wbutz@cyberfnord.de>
2018-09-26 16:56:36 +02:00
Christoph (Sheogorath) Kern eb885af995
Merge pull request #967 from SISheogorath/fix/follow
Add POEditor to 'follow us' statement
2018-09-26 16:20:31 +02:00
Sheogorath 353642c870
Fix document length limit on post
We recently introduced a new way to create notes using a post requeest
to the `/new` endpoint. This is not limited in size, other than pasting
a note in the editor. This patch should enforce this limit also on this
way.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-09-26 16:08:24 +02:00
Sheogorath 2c32cf0abf
Add POEditor to 'follow us' statement
We broke the follow us before by removing Facebook and Twitter. Adding
POEditor should fix it and help to attract new translators.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-09-26 15:42:43 +02:00
Davide Depau 3219e93bdd Merge branch 'master' into DepauMD 2018-09-26 03:00:10 +02:00
Sheogorath db59bb99dc
Run db migrations on start
We should force db migrations to run on every start. This will minimize
the impact of breaking migrations in future. While it may causes some
issues with the next start since CodiMD won't start when the migrations
fail.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-09-25 19:58:55 +02:00
Christoph (Sheogorath) Kern bdf897d31c
Merge pull request #964 from SISheogorath/fix/gitlabWarning
Omit unneeded warning if no gitlab is configured
2018-09-25 11:23:40 +02:00
Davide Depau f725ebd369 Merge branch 'master' into DepauMD 2018-09-25 03:00:10 +02:00
Sheogorath 7e0be69abb
Omit unneeded warning if no gitlab is configured
This patch should fix the unneeded warning of the wrong API version,
when gitlab isn't configured at all.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-09-25 00:26:40 +02:00
Christoph (Sheogorath) Kern 9e4d165663
Merge pull request #963 from SISheogorath/fix/crashPDF
Fix server crash on PDF creation
2018-09-24 20:34:29 +02:00
Sheogorath 6fdb9eea46
Fix server crash on PDF creation
`markdown-pdf` seems to fail to provide the PDFs on tmpfs. This leads
crashing codimd which expects the file to be there. This patch should
add some proper error handling when expectation and reality don't fit
together.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-09-24 20:25:25 +02:00
Davide Depau b094ffb531 Merge branch 'master' into DepauMD 2018-09-24 03:00:11 +02:00
Christoph (Sheogorath) Kern 32afa14375
Merge pull request #962 from SISheogorath/feature/indonesian
Add indonesian language to CodiMD
2018-09-23 17:57:06 +02:00
Sheogorath e65e85fa6d
Add indonesian language to CodiMD
Big thanks @filosofikode for the translation work!

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-09-23 17:23:16 +02:00
Sheogorath 6b80626dca
Replace `uws` with `ws` package
`uws` was deprecated by its maintainer and starts to cause more and more
problems and issue reports. So it's time to replace it and use a
maintained project instead. Lucky us, `uws` and `ws` can be used in an
identical way, without problems. To provide better performance, we
install the optional packages as well.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-09-18 00:02:23 +02:00
Davide Depau 69386c33a8 Merge branch 'master' into DepauMD 2018-09-13 03:00:13 +02:00
Sheogorath fe977434f9
Remove dead link from README
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-09-12 15:40:20 +02:00
Davide Depau 550f6ebb1f Merge branch 'master' into DepauMD 2018-09-10 00:11:17 +02:00
David Mehren c66aa60495
Upgrade to Webpack 4 - development config
Signed-off-by: David Mehren <dmehren1@gmail.com>
2018-09-06 17:26:09 +02:00
David Mehren 6056f9a392
Upgrade to Webpack 4 - remove baseUrl property
Signed-off-by: David Mehren <dmehren1@gmail.com>
2018-09-06 17:26:09 +02:00
David Mehren ce63c1cc1c
Upgrade to Webpack 4 - clean dependencies
Signed-off-by: David Mehren <dmehren1@gmail.com>
2018-09-06 17:26:09 +02:00
David Mehren dcb10b0ec9
Upgrade to Webpack 4 - fix CSS import order
Signed-off-by: David Mehren <dmehren1@gmail.com>
2018-09-06 17:26:09 +02:00
David Mehren a6d3ac647b
Upgrade to Webpack 4 - fix 'export as html' chunk
Signed-off-by: David Mehren <dmehren1@gmail.com>
2018-09-06 17:26:09 +02:00
David Mehren 29a3813ada
Upgrade to Webpack 4 - first try
Signed-off-by: David Mehren <dmehren1@gmail.com>
2018-09-06 17:26:09 +02:00
Sheogorath 0017ddd310
Update yarn.lock 2018-09-06 15:12:37 +01:00
Sheogorath 5aec047a3e
Some minor improvements for setup script
Since we use `yarn` for our container setup and try to enforce
dependencies, we should also use yarn in the setup script.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-09-06 15:04:20 +01:00
Christoph (Sheogorath) Kern dbbc1f6ac8
Merge pull request #939 from SISheogorath/fix/migrationsV2
Extend migration error handling
2018-09-06 14:50:37 +01:00
Sheogorath f27e11adab
Fix typo in link 2018-09-06 14:42:08 +01:00
Sheogorath f177cdfbba
Change to new codimd-container repository
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-09-06 14:40:37 +01:00
Christoph (Sheogorath) Kern d28a493305
Merge pull request #929 from maxer456/mattermost-auth-guide
Add an auth provider guide for Mattermost
2018-09-06 11:53:26 +01:00
Sheogorath 81e3d7bd00
Extend migration error handling
The current error handling seems to conflict with some sequelize
versions. So we add a second version of it in our excemptions.

I'm not happy about it, but when it helps to prevent further migration
breaking, it's worth it.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-09-05 16:19:35 +01:00
Christoph (Sheogorath) Kern e1746c1229
Merge pull request #936 from SISheogorath/fix/lzstring
Switch to own, fixed, lz-string version
2018-09-05 12:26:13 +01:00
Christoph (Sheogorath) Kern 5c8eaabba0
Merge pull request #938 from SISheogorath/fix/nodeTesting
Remove tests using node version 7
2018-09-05 12:24:50 +01:00
Sheogorath 8cd2f4623d
Remove tests using node version 7
Since node 7 is EOL and may breaks some new builds, we want to get rid of it. But having tests in version 8 would be nice, right? So here we go.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-09-05 12:18:41 +01:00
Sheogorath b028baf77f
Switch to own, fixed, lz-string version
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-09-05 12:09:02 +01:00
Christoph (Sheogorath) Kern 007f252273
Merge pull request #906 from SISheogorath/fix/letterAvatarMail
Fix possible weird objects as email
2018-09-05 11:36:29 +01:00
Ondřej Slabý 6ce7b20a7f Add an auth provider guide for Mattermost
Signed-off-by: Ondřej Slabý <kron258@gmail.com>
2018-08-28 11:00:00 +02:00
Christoph (Sheogorath) Kern 72894d1b7d
Merge pull request #928 from Pingu501/bugfix/wrong-gitlab-api-version-check
BUGFIX: wrong version check for gitlab api
2018-08-23 16:27:04 +02:00
Alexander Hesse f728fdb8ab BUGFIX: wrong version check for gitlab api
Signed-off-by: Alexander Hesse <alexander.hesse@sandstorm-media.de>
2018-08-23 14:06:26 +02:00
Christoph (Sheogorath) Kern 3a857a3ab3
Merge pull request #924 from cloudron-io/cloudron
Add Cloudron as an installation method
2018-08-21 09:13:52 +02:00
Girish Ramakrishnan aa0c4705db Add Cloudron as an installation method
Fixes #923

Signed-off-by: Girish Ramakrishnan <girish@cloudron.io>
2018-08-20 20:42:52 -07:00
Davide Depau 18fd14949e Merge branch 'master' into DepauMD 2018-08-01 03:00:08 +02:00
Christoph (Sheogorath) Kern c9fe236594
Merge pull request #910 from hackmdio/change-social-links
Update to replace Twitter and Facebook to Riot
2018-07-31 16:25:46 +02:00
Max Wu 40340c89f7
Update to replace Twitter and Facebook to Riot
Signed-off-by: Max Wu <jackymaxj@gmail.com>
2018-07-31 22:17:06 +08:00
Christoph (Sheogorath) Kern 881ca88c51
Merge pull request #908 from micedre/gitlabV4
Add possibility to choose between version v3 or v4 for the gitlab api.
2018-07-31 10:55:08 +02:00
Cédric Couralet 66d374b128 Add possibility to choose between version v3 or v4 for the gitlab api.
Apart from the uri versioning, one big change is the snippet visibility post data (visibility_level -> visibility)

Default gitlab api version to v4

Signed-off-by: Cédric Couralet <cedric.couralet@gmail.com>
2018-07-31 08:36:56 +00:00
Christoph (Sheogorath) Kern 48ddcef31c
Merge pull request #894 from hcaloto/fixMigrationIssues
Add missing catch blocks for migration from 1.1.1 to 1.2.0
2018-07-31 10:26:39 +02:00
Hugo Caloto 26a14dd987 Add missing catch blocks for migration from 1.1.1 to 1.2.0
Signed-off-by: Hugo Caloto <hcaloto@gmail.com>
2018-07-31 08:19:57 +02:00
Davide Depau 3cf3e7c6da Merge branch 'master' of https://github.com/hackmdio/codimd into DepauMD 2018-07-28 15:33:53 +02:00
Christoph (Sheogorath) Kern 93a3ce1164
Merge pull request #907 from SISheogorath/fix/historyLZString
Some minor improvements for LZString handling
2018-07-28 15:03:06 +02:00
Sheogorath db5b86df4c
Further improvement of error handling for LZString
This does some more in depth check on the error message and minimizes
the log noise that is caused by LZString.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-07-27 15:42:58 +02:00
Christoph (Sheogorath) Kern a6a15e09fe
Merge pull request #902 from ahihi/listen-address-options
Support 'host' & 'path' config options
2018-07-27 14:40:41 +02:00
Miranda Kastemaa 70e8df5c04 Support 'host' & 'path' config options
Signed-off-by: Miranda Kastemaa <miranda@foldplop.com>
2018-07-27 15:35:29 +03:00
Sheogorath 53a846bdc5
Update markdown-pdf
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-07-27 14:15:45 +02:00
Sheogorath 1f85017625
Minimize number of errors in LZString parsing errors for history
Right now we still see a lot of LZString parsing errors in the logs. 
They probably come from the user history. We should minimize the number 
by add the basic length check there as well.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-07-27 13:59:55 +02:00
Sheogorath 187401a876
Fix possible weird objects as email
It seems like some providers return strange types for emails which cause
problems. We default to something that is definitely a string.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-07-27 13:36:22 +02:00
Sheogorath 23bd1a18bb
Add mailmap for contributors
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-07-27 13:21:52 +02:00
Christoph (Sheogorath) Kern 262974dd3d
Merge pull request #896 from maahl/default_img_upload_type
Upload images to the filesystem by default, rather than to imgur
2018-07-27 13:03:32 +02:00
Christoph (Sheogorath) Kern d327bed653
Merge pull request #893 from w4tsn/patch-2
Fix some false titles
2018-07-27 12:59:38 +02:00
Christoph (Sheogorath) Kern e45f8bb692 Update ja.json (POEditor.com) 2018-07-10 11:53:09 +02:00
Maxence Ahlouche 972a81aa6f Upload images to the filesystem by default, rather than to imgur
Signed-off-by: Maxence Ahlouche <maxence.ahlouche@gmail.com>
2018-07-09 20:31:14 +02:00
Alexander Wellbrock 97c2330264
Fix some false titles
Signed-off-by: Alexander Wellbrock <a.wellbrock@mailbox.org>
2018-07-08 20:41:46 +02:00
Christoph (Sheogorath) Kern 429257880b
Merge pull request #890 from hackmdio/fix-csp-for-speaker-notes
Replaces script src hash for speaker note to CSP directives
2018-07-05 12:54:07 +02:00
Max Wu b7e5a82f52 Add script src hash for speaker note to CSP directives
Signed-off-by: Max Wu <jackymaxj@gmail.com>
2018-07-05 18:41:27 +08:00
Christoph (Sheogorath) Kern af26992b55
Merge pull request #886 from SISheogorath/fix/ToCHeader
Refactor generation of ToC
2018-07-04 21:13:14 +02:00
Sheogorath df05bff82a
ToC: Some HTML improvements and style fixes
The ToC generated broken HTML with unclosed `<li>` tags. This got fixed
as well as some minor optimisation and adding list elements for the
subentries so the elements appear in the ToC while scrolling.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-07-04 21:09:06 +02:00
Sheogorath cf934a4e51
Ignore h6 headers
h6 headers are used for tags in CodiMD. So we should ignore them for the
ToC generation.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-07-04 11:21:15 +02:00
Sheogorath 4fe0620853
Refactor generation of ToC
This replaces the existing iterative implementation of the ToC
generation with an recursive one.

This also solves the problem of skipped headers which causes wrong
leveling of them.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-07-04 02:36:47 +02:00
Christoph (Sheogorath) Kern b1d1f469de
Merge pull request #883 from SISheogorath/fix/contentTypes
Fixing content types in status router
2018-07-03 22:17:36 +02:00
Christoph (Sheogorath) Kern 762cff677c
Merge pull request #884 from SISheogorath/fix/nightMode
Fix some night mode colors
2018-07-03 21:41:04 +02:00
Sheogorath 734e7b01a5
Remove some unneeded defined inline-stylings
These have no really useful point here. Let's just remove them.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-07-03 21:34:57 +02:00
Sheogorath 1de8160008
Fix some night mode colors
We have some issues with night mode and the font color. This should fix
this in the permission table and the delete node modal. As well as some
picture styling.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-07-03 21:25:45 +02:00
Sheogorath d76ea5440a
Fixing content types in status router
As it turns out, expressjs doesn't detect the right mimetype and it
seems like I didn't bother to test this enough. So lets fix it for the
next release.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-07-03 20:38:52 +02:00
Christoph (Sheogorath) Kern 4e38d1836e Update it.json (POEditor.com) 2018-07-02 09:41:12 +02:00
Sheogorath 33a4b88dab
Release 1.2.0
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-06-30 19:38:12 +02:00
Sheogorath 2fc4e911fb
Release notes for 1.2.0
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-06-30 19:19:34 +02:00
Christoph (Sheogorath) Kern 7cfade712f Update de.json (POEditor.com) 2018-06-30 19:14:15 +02:00
Sheogorath bd93269dae
Update yarn.lock 2018-06-30 17:45:26 +02:00
Sheogorath a26c142ade
Revert "Update pg"
This reverts commit 4d4163c170.
2018-06-30 17:43:08 +02:00
Sheogorath fe5248acbd
Update yarn.lock
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-06-30 17:07:53 +02:00
Christoph (Sheogorath) Kern 501b46f304
Merge pull request #871 from SISheogorath/update/dependencies
Update dependencies
2018-06-30 17:05:59 +02:00
Sheogorath f30cc3044a
Update randomcolor
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-06-30 16:52:34 +02:00
Sheogorath 4d4163c170
Update pg
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-06-30 16:52:34 +02:00
Sheogorath dea62cf310
Update store
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-06-30 16:52:34 +02:00
Sheogorath 1812b1aaca
Update highlight.js
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-06-30 16:52:34 +02:00
Sheogorath 565cdc0197
Update xss protection
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-06-30 16:52:34 +02:00
Sheogorath 459fe2da07
Update sqlite
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-06-30 16:52:34 +02:00
Sheogorath 3f49aee63f
Update shortid
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-06-30 16:52:34 +02:00
Sheogorath 0cebeb68d7
Update passport
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-06-30 16:52:33 +02:00
Sheogorath b6e1144627
Update to octicon 4.4.0
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-06-30 16:52:33 +02:00
Sheogorath 562985a115
Update passport-ldap
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-06-30 16:52:33 +02:00
Sheogorath f51de7f3bb
Update validator
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-06-30 16:52:33 +02:00
Sheogorath fd3733e7d1
Update password-gitlab2
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-06-30 16:52:33 +02:00
Sheogorath d8df6e4342
Update minio
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-06-30 16:52:33 +02:00
Sheogorath 76b2ba4954
Update markdown-pdf
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-06-30 16:52:33 +02:00
Christoph (Sheogorath) Kern 453cb19fff
Merge pull request #868 from SISheogorath/docs/termsAndPrivacy
Add docs for usage of terms and privacy policy
2018-06-27 23:49:11 +02:00
Sheogorath 20b75a4924
Add docs for usage of terms and privacy policy
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-06-27 23:44:32 +02:00
Christoph (Sheogorath) Kern 8bd85f8960
Merge pull request #866 from SISheogorath/docs/nativeSequelize
Update install instructions to cover sequelize
2018-06-26 23:24:23 +02:00
Sheogorath 3b9e29a14a
Update install instructions to cover sequelize
We instruct people to run db migrations on inital setup. We should do
that!

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-06-26 22:56:19 +02:00
Christoph (Sheogorath) Kern 6218c703a9
Merge pull request #865 from SISheogorath/fix/unicodeURLs
Fix broken unicode urls
2018-06-26 22:47:21 +02:00
Sheogorath 1c92524c08
Fix broken unicode urls
It wasn't possible to create unicode based URLs in freeurl mode, because
the noteid used for the websocket connection is double escaped. When we
decode it and let socketio-client reencode it, we get the real
shortid/noteid and can find the note in the database and open the
connection.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-06-26 22:25:36 +02:00
Christoph (Sheogorath) Kern c7745f6b27
Merge pull request #863 from hackmdio/feature/slidePrint
Add Print icon to slide view
2018-06-26 21:41:18 +02:00
Christoph (Sheogorath) Kern 6634fac849
Merge pull request #850 from SISheogorath/rebrand/CodiMD
Rebrand HackMD CE to CodiMD
2018-06-26 21:38:02 +02:00
Sheogorath 04d16e4d6e
Add Print icon to slide view
It redirects the user to the print view of the document. I claim that
people should either be smart enough to use ctrl+P or ask someone who
knows how to print a webpage. I don't want to babysit our users.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-06-24 23:50:38 +02:00
Sheogorath 2184491f4a
Final replacements
Looks like I missed a few. This should be complete now. And make us
ready for the repo rename and merging.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-06-24 14:13:46 +02:00
Sheogorath 97a08e7954
Add note about renaming to docs
It's way easier to add a note to the guides than to redo all the images,
etc. We have more important things to spend our time on, but if someone
wants to redo them, you are very welcome!

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-06-24 14:06:32 +02:00
Sheogorath a762928e97
Do final internal renameing
A little minor change, by moving the CodiMD version header in its own
middleware. Should simplify to determine the version number of the
Backend in future.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-06-24 14:05:41 +02:00
Sheogorath 23c33c0c04
Rename HackMD view to CodiMD
Even when it looks a bit weird in first place to rename all internals
step by step, it makes sense to do so, because we run into confusion
afterwards.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-06-24 13:40:18 +02:00
Sheogorath b242b59db4
Rename environment variables and add legacy support.
As we are no longer HackMD the short tag `HMD` doesn't match anymore. We
move it to the matching prefix `CMD` and inform our users about the
change.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-06-24 13:40:18 +02:00
Sheogorath 12d11f3f3f
Add background story about the renaming
We want to communicate transparent. So we should state very clear what
CodiMD is and what makes it different from HackMD and at the same time
how we are related and that there are no bad boys involved.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-06-24 13:24:13 +02:00
Sheogorath ddb52bf3c8
Remove outdated contributors file
We can remove this contributors file, since it doesn't provide any more
information than git blame does anyways.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-06-24 13:24:13 +02:00
Sheogorath 4b060c7dba
Rebrand HackMD to CodiMD
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-06-24 13:24:12 +02:00
Christoph (Sheogorath) Kern d87505d583
Merge pull request #854 from hackmdio/feature/disableGravatar
Allow to disable gravatar
2018-06-24 01:59:06 +02:00
Christoph (Sheogorath) Kern b8726bbe8d
Merge pull request #855 from hackmdio/fix/constants
Move config out of statics path
2018-06-24 01:58:08 +02:00
Christoph (Sheogorath) Kern cfdfafdb79
Merge pull request #856 from hackmdio/fix/lineEndings
Fix possible line-ending issues for init note
2018-06-24 01:57:47 +02:00
Christoph (Sheogorath) Kern ec78c4f2fc
Merge pull request #857 from hackmdio/fix/pdf-links
Fix broken images in PDF caused by misconfigred server URL
2018-06-24 01:57:26 +02:00
Christoph (Sheogorath) Kern 050146e62c
Merge pull request #858 from SISheogorath/fix/imgUpload
Fix breaking regex
2018-06-24 01:32:28 +02:00
Sheogorath bf9400e107
Fix breaking regex
The image upload regex breaks with the new path for uploads.

This commit fixes it.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-06-24 01:03:45 +02:00
Sheogorath f69e77de42
Fix broken images in PDF caused by misconfigred server URL
As it turns out, if the serverURL can't be generated correctly, HackMD
will use relative paths in image upload. This causes broken links in
PDF.

With this commit we force absolute links during PDF creation which
hopefully fixes the problem.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-06-24 01:00:29 +02:00
Sheogorath b7b621822c
Fix possible line-ending issues for init note
By uploading a malicous note currently it is possible to prevent this
note from being edited. This happens when using Windows line endings.

With this commit we remove all `\r` characters from the notes and this
way prevent this problem.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-06-24 00:32:50 +02:00
Sheogorath 0ed4b50098
Move config out of statics path
Since static path is providing with a high expiration data, we provide
configs via API. This shouldn't add any noticeable load while making it
uncached and this way working again.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-06-24 00:07:32 +02:00
Christoph (Sheogorath) Kern 7c7cc289f2
Merge pull request #853 from SISheogorath/fix/imgUpload
Fix possible error if HackMD is started with wrong workdir
2018-06-23 23:42:15 +02:00
Sheogorath 318b2d378f
Allow to disable gravatar
Since Gravatar is an external image source and not perfect from a
privacy perspective, forbidding it allows to improve privacy.

This commit also simplifies and optimizes the avatar code.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-06-23 23:40:55 +02:00
Sheogorath a2608c319a
Fix possible error if HackMD is started with wrong workdir
In https://github.com/hackmdio/hackmd/issues/834 is described how
starting HackMD crashes when using the wrong working dir.

This is caused by a relative path in our upload routine. This change
should fix it and prevent future crashes.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-06-23 23:01:01 +02:00
Christoph (Sheogorath) Kern 87824d21e8
Merge pull request #852 from SISheogorath/remove/unusedLang
Remove unused zh.json from repo
2018-06-23 21:38:31 +02:00
Sheogorath 8fe26988d1
Fix all newly introduced linting issues
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-06-23 21:27:21 +02:00
Sheogorath 47b18ada76
Remove unused zh.json from repo
Since the original idea of using a symlink didn't work anyway, we should
remove the zh.json symlink from the repo.  It doesn't provide any
benefit but alters the repo on start of HackMD.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-06-23 21:26:33 +02:00
Sheogorath 49db5bc653
Merge branch 'pr-846' 2018-06-23 21:19:44 +02:00
Sheogorath f65d96c57b
Fix liniting and optimize some functions
First fixed some linting issues. Also optimized some functions to be
undoable with one ctrl+z.

This should also speedup some operations

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-06-23 21:18:15 +02:00
Christoph (Sheogorath) Kern 7542968dc7
Merge pull request #849 from jekrb/cover-template-string
turn concatenated string into a multi-line template string
2018-06-23 18:23:28 +02:00
Jake Burden b98d10c79a turn concatenated string into a multi-line template string
Signed-off-by: Jake Burden <jake@doge.haus>
2018-06-22 18:08:47 -04:00
Edgar Zanella Alvarenga a8b664fdb5 Add a toolbar to Codemirror editor
Signed-off-by: Edgar Zanella Alvarenga <e@vaz.io>
2018-06-19 16:03:56 +02:00
Christoph (Sheogorath) Kern 82c7f9d07c
Merge pull request #844 from hackmdio/docs/fix-default
Fix wrong docs about default image upload location
2018-06-18 03:42:42 +02:00
Christoph (Sheogorath) Kern 818d82559e
Merge pull request #845 from hackmdio/fix/polyfill
Move polyfill to CDN section
2018-06-18 03:42:17 +02:00
Christoph (Sheogorath) Kern 90411c9413
Merge pull request #843 from hackmdio/docs/K8s
Add K8s note in README
2018-06-18 01:26:58 +02:00
Sheogorath ed5353d13a
Move polyfill to CDN section
We don't support it on CDN false instances, but it doesn't hurt to keep
it in for CDN-enabled instances

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-06-18 01:26:11 +02:00
Sheogorath 10dbd537b4
Fix wrong docs about default image upload location
We wrongly state that the default image upload location is imgur. This
is no longer true, but got lost when updating docs. This commit should
fix it.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-06-17 23:38:49 +02:00
Sheogorath 6ffe8875bf
Add K8s note in README
We have an official K8s chart for helm out there but probably no one
knows about it. Let's advertise it a bit!

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-06-17 23:38:25 +02:00
Sheogorath 4fcefebe5c
Update yarn.lock 2018-06-17 23:36:22 +02:00
Christoph (Sheogorath) Kern 56d78a7d6c
Merge pull request #830 from SISheogorath/feature/GDPR
GDPR compliant part 1
2018-06-17 23:33:57 +02:00
Davide Depau 908d6e53e7 DepauMD branding 2018-06-17 19:26:21 +02:00
Christoph (Sheogorath) Kern f36b10abb2
Merge pull request #837 from SISheogorath/translate/korean
Add korean translation
2018-06-07 14:52:56 +02:00
Sheogorath 56182532cb
Add korean translation
This translation was contributed via POEditor by the user Basix.

Thanks a lot for your work!

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-06-07 14:29:01 +02:00
Christoph (Sheogorath) Kern 6f76e9940f
Merge pull request #836 from SISheogorath/fix/i18n-files
Fix i18n writing locale files in production
2018-06-07 10:29:09 +02:00
Sheogorath b07925b849
Update yarn.lock
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-06-05 01:43:17 +02:00
Sheogorath 634b3c9cea
Fix i18n writing locale files in production
This commit should prevent the i18n module from adding missing
translations to the local files in setups that are not for development.
This way we keep the directory clean and idempotent.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-06-05 01:40:50 +02:00
Christoph (Sheogorath) Kern 551840ad57
Merge pull request #784 from pferreir/add-oauth2-support
Add "generic" OAuth2 support
2018-06-04 15:54:47 +02:00
Christoph (Sheogorath) Kern 3f7a33df64
Merge pull request #783 from SISheogorath/docs/splitAuth
Split authentication guides into multiple documents
2018-06-01 20:18:28 +02:00
Sheogorath 3251bcbadc
Split authentication guides into multiple documents
Splitting the documentation should provide an easier access to the
documentation people searching for and result in less merge conflicts
when adding new documentation here.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-06-01 14:36:33 +02:00
Christoph (Sheogorath) Kern 94e015dde7
Merge pull request #833 from ahoka/callback
Fix callback validation
2018-06-01 14:31:44 +02:00
Adam Hoka b5574466cd Fix callback validation
Signed-off-by: Adam Hoka <hoka.adam@nexogen.hu>
2018-06-01 14:26:28 +02:00
Christoph (Sheogorath) Kern 2ed2a08f66
Merge pull request #782 from SISheogorath/feature/showFullTitle
Add title attribute in table of contents
2018-06-01 13:49:09 +02:00
Christoph (Sheogorath) Kern 65544f9a18
Merge pull request #675 from ahoka/master
Add Azure Blob Storage support
2018-06-01 12:35:20 +02:00
Ádám Hóka 376fcab2ca Add Azure Blob Storage support
Signed-off-by: Adam Hoka <hoka.adam@nexogen.hu>
2018-06-01 10:07:52 +02:00
Christoph (Sheogorath) Kern ef1097c58d
Merge pull request #832 from liuderchi/fix/checkbox-style-slide-mode
fix(slide): adjust checkbox size
2018-05-31 19:21:10 +02:00
liuderchi 334707e932
fix(slide): adjust checkbox size
- to override rules in css/github-extract.css with `!important` already

Signed-off-by: liuderchi <liuderchi@gmail.com>
2018-05-31 23:44:03 +08:00
Christoph (Sheogorath) Kern 12ab90020a
Merge pull request #785 from pferreir/redirect-to-login
403: Redirect user to login page if not logged in
2018-05-31 12:16:11 +02:00
Sheogorath fce735e833
Add privacy policy example
As we use various services and integration we should provide an example
privacy policy.

It has to be adjust when using it to match your setup.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-05-31 11:32:11 +02:00
Sheogorath 6f8bd8fdc9
Fix missing dependency
To export the notes we need the archiver package that takes care of
creating the zip files.

Looks like I forgot this one in the initial commit.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-05-27 15:28:46 +02:00
Sheogorath 75f28ca7f3
Add export data UI
This adds the UI for the export feature introduced in
bcbb8c67c9

It allows to download all notes from the main page in the default user
submenu.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-05-26 03:20:44 +02:00
Sheogorath bcbb8c67c9
Add note export function
This function is the first step to get out data following GDPR about the
transportability of data.

Details: https://gdpr-info.eu/art-20-gdpr/
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-05-26 03:12:21 +02:00
Sheogorath 70df29790a
Add token based security feature
In the current setup users could be tricked into deleting their data by
providing a malicious link like `[click me](/me/delete)`. This commit
prevents such an easy attack and need the user's deleteToken to get his
data deleted. In case someone requests his deletion by email you can
also ask him for this token.

We can add a GUI that shows it later on.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-05-25 18:26:06 +02:00
Sheogorath 9fd09a8dfb
Add delete user UI
This provides the UI for the delete user feature introduced in
4229084c62

Placing of the user delete button is not perfect, but can be moved to an
own user tab later on.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-05-25 17:11:11 +02:00
Sheogorath e31d204d74
Fix requests for deleted users
When users are requested from the authorship which no longer exist, they
shouldn't cause a 500.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-05-25 16:15:18 +02:00
Sheogorath 4229084c62
Add delete function for authenticated users
Allow users to delete themselbes. This is require to be GDPR compliant.

See: https://gdpr-info.eu/art-17-gdpr/
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-05-25 15:24:47 +02:00
Sheogorath 408ab7ae1d
Use cascaded deletes
When we delete a user we should delete all the notes that belong to this
user including the revisions of these notes.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-05-25 14:55:18 +02:00
Sheogorath 8aa5c03213
Use hard delete instead of soft delete
Right now we only flag notes as deleted. This is no longer allowed under
GDPR. Make sure you do regular backups!

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-05-25 14:50:37 +02:00
Sheogorath 41a36e2e18
Add privacy and ToS links
To be GDPR compliant we need to provide privacy statement. These should
be linked on the index page. So as soon as a document exist under
`public/docs/privacy.md` the link will show up.

Since we already add legal links, we also add Terms of Use, which will
show up as soon as `public/docs/terms-of-use.md` exists.

This should allow everyone to provide the legal documents they need for
GDPR and other privacy and business laws.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-05-24 18:10:36 +02:00
Sheogorath a258719d34
Release 1.1.1-ce
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-05-23 12:01:26 +02:00
Christoph (Sheogorath) Kern 9e77d88024
Merge pull request #828 from SISheogorath/feature/release-notes-1.1.1-ce
Add release notes for 1.1.1-ce
2018-05-23 00:16:48 +02:00
Sheogorath fada8a8103
Add release notes for 1.1.1-ce
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-05-22 23:17:20 +02:00
Sheogorath 7a91d01830
Update yarn.lock
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-05-21 23:12:34 +02:00
Sheogorath bd46230a7f
Add current requirements for node versions
Right now we can only run on node versions below 10.x thanks to scrypt
dependencies.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-05-21 23:08:13 +02:00
Christoph (Sheogorath) Kern c71361467d
Merge pull request #826 from SISheogorath/upgrade/base64url
Upgrade base64url package
2018-05-17 15:37:25 +02:00
Sheogorath af0a6b1d76
Upgrade base64url package
There was recently a possible security problem with base64url. Shouldn't
really hit us but it doesn't hurt.

Details: https://snyk.io/vuln/npm:base64url:20180511

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-05-17 15:19:24 +02:00
Christoph (Sheogorath) Kern 42b0965550
Merge pull request #825 from SISheogorath/remove/GoogleDrive
Removing google drive integration
2018-05-16 01:59:35 +02:00
Sheogorath ad69c5017b
Removing google drive integration
It's sad but it's not working. For multiple releases this should be
already broken which shows how often it's used.

As there is also a security issue related to that, it's better to
remove the feature completely. Whoever wants to rewrite it, feel free to
go.

This commit removes the Google Drive integration from HackMD's Frontend
editor and this way removes the need to provide any API key and Client
ID in the frontend.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-05-16 01:34:55 +02:00
Christoph (Sheogorath) Kern b8e7c4b97a
Merge pull request #824 from hackmdio/revert-813-fix/googleAPI
Revert "Workaround Google API problems"
2018-05-16 01:32:17 +02:00
Christoph (Sheogorath) Kern 6d44ded269
Revert "Workaround Google API problems" 2018-05-16 01:31:50 +02:00
Christoph (Sheogorath) Kern e4e198c819
Merge pull request #813 from SISheogorath/fix/googleAPI
Workaround Google API problems
2018-05-10 00:13:23 +02:00
Sheogorath 2cc3058a44
Remove Google Upload from UI
This temporarily removes the Upload from the UI as it's broken right
now.

Needs a refactoring and can be added in again later on by undoing this
commit.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-05-01 23:22:53 +02:00
Christoph (Sheogorath) Kern 2232905c4a
Merge pull request #811 from hackmdio/fix-saml-typo
Fix typo of "grouptAttribute" in saml auth module
2018-04-28 01:13:39 +02:00
Max Wu e0629c7d27
Fix typo of "grouptAttribute" in saml auth module
Signed-off-by: Max Wu <jackymaxj@gmail.com>
2018-04-27 21:52:05 +08:00
Christoph (Sheogorath) Kern 763479bea8
Merge pull request #803 from SISheogorath/fix/letterAvatarCSP
Move letter-avatars into own request
2018-04-17 22:29:37 +02:00
Sheogorath 69aed93282
Move letter-avatars into own request
To prevent further weakening of our CSP policies, moving the Avatars
into a non-inline version is the way to go.

This implementation probably needs some beautification. But already fixes
the bug.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-04-17 19:06:59 +02:00
Sheogorath 43fa5cf57f
Update yarn.lock
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-04-17 12:20:57 +02:00
Christoph (Sheogorath) Kern 2a9fe664d1
Merge pull request #805 from SISheogorath/fix/noFile
Fix possible file limit errors
2018-04-17 12:02:13 +02:00
Sheogorath c4dba48f79
Fix possible file limit errors
As we currently may need higher nofile limits than usual/default on
various systems this commit should probide a fix for that an allow to
build HackMD without highering these limits and increase security.

Inspiration was found in a copy-webpack-plugin-issue[1] and found by
@thegcat[2]. Thanks for that!

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>

[1]:
https://github.com/webpack-contrib/copy-webpack-plugin/issues/59#issuecomment-228563990
[2]: https://github.com/thegcat
2018-04-16 21:08:34 +02:00
Sheogorath 8a3cec73c1
Add config.json.example to npm test
This commit extends the find command to also match the example config
file.

This should validate the syntax or this file to prevent syntax errors
for future pull request.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-04-14 22:20:35 +02:00
Sheogorath 132b445fef
Fix example config
This commit fixes some json fromat issues in our config example that
causes errors on setup.

This change should fix it.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-04-14 22:20:25 +02:00
Sheogorath ef86bf5cba
Use API key instead of clientSecret
As recently discovered we send the clientSecret to the webclient which
is potentionally dangerous. This patch should fix the problem and
replace the clientSecret with the originally intended and correct way to
implement it using the API key.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-04-13 09:38:59 +02:00
Christoph (Sheogorath) Kern 10121118fb
Merge pull request #797 from SISheogorath/fix/LZErrorLog
Add check for noteId length
2018-04-11 22:48:40 +02:00
Christoph (Sheogorath) Kern 387afd1791
Merge pull request #799 from SISheogorath/fix/AnonymousEditTypos
Fix typos for `allowAnonymousEdits`
2018-04-11 22:48:15 +02:00
Sheogorath f23f403bcb
Extend README
Add hint about file descriptor limits and add the new translation
platform.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-04-11 09:38:56 +02:00
Sheogorath 735b806d5d
Add check for noteId length
As we know the length of an UUID we can check if the base64 string
of the provided UUID is long enough for a legacy base64 encoded nodeId
and stop processing it in legacy mode, if it's not the case.

This should make the ugly warning way less common.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-04-10 16:10:34 +02:00
Sheogorath 2492cf2cdf
Fix typos for `allowAnonymousEdits`
Looks like we lost some variables during the refactoring of the configs
to camel case.

This should fix it.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-04-10 14:40:27 +02:00
Sheogorath bdb8631a7b
Release 1.1.0-ce
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-04-06 16:24:36 +02:00
Sheogorath 14a0f8594f
Merge branch 'feature/releaseNotes1.1.0' 2018-04-06 16:24:08 +02:00
Sheogorath f4631b038a
Merge branch 'docs/features-1.1.0-ce' 2018-04-06 16:22:26 +02:00
Sheogorath 23b5e9e54a
Minor fixes in relase notes
Fix some spelling and style issues as well as adding the
latest changes.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-04-06 16:19:24 +02:00
Sheogorath 81e5ebf6d6
Add migration section to README.md
As it was requested to be more visable, this commit adds a migration
section about the introduced config style changes.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-04-06 02:20:34 +02:00
Christoph (Sheogorath) Kern b97d6cebad
Merge pull request #796 from SISheogorath/feature/addMatrix
Add matrix.org / Riot link
2018-04-06 01:59:00 +02:00
Sheogorath 95f46520e3
Add matrix.org / Riot link
As an active part of the community prefers Matrix.org over Gitter, we
should link Matrix.org as a place to meet us.

As the matrix and gitter channels are interconnected. We don't loose any
message if a person decides to go for one or another.

We use an more universal way of translation to make it easier to provide
a link to various platforms.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-04-05 11:58:54 +02:00
Christoph (Sheogorath) Kern 5a5b3e9ddd
Merge pull request #790 from SISheogorath/fix/nightModeCSS
Fix modal and panel colors in night mode
2018-04-05 01:24:34 +02:00
Christoph (Sheogorath) Kern 96af23fa31
Merge pull request #791 from SISheogorath/fix/extendedCSPPolicies
Fix CSP for disqus and Google Analytics
2018-04-05 01:13:15 +02:00
Sheogorath b90b215a84
Fix code blocks color in night mode
This provides more eye-friendly code boxes when night mode is active.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-04-05 00:58:41 +02:00
Sheogorath f2f0369259
Provide feature changes in 1.1.0-ce
Adding some documentation for night mode and upload times. Extend the
contact section for community support.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-03-30 20:42:55 +02:00
Sheogorath 645f38c228
Update release notes
Providing release notes for version 1.1.0-ce

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-03-30 20:38:37 +02:00
Sheogorath d939de17df
Fix CSP for disqus and Google Analytics
This commit should fix existing problems with Disqus and Google
Analytics enabled in the meta-yaml section of a note.

Before this commit they were blocked by the strict CSP. It's still
possible to disable the added directives using `addDisqus` and
`addGoogleAnalytics` in the `csp` config section.

They are enabled by default to prevent breaking changes.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-03-30 16:33:52 +02:00
Sheogorath 291b33880c
Fix modal and panel colors in night mode
Night mode provides a generally, dark interface. This fix provides the
needed CSS to also turn modal and panels into night mode design as well.
This mainly effects the help modal.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-03-29 23:23:30 +02:00
Christoph (Sheogorath) Kern a9a0577230
Merge pull request #789 from SISheogorath/fix/sessionSecretEnv
Add session data to env vars
2018-03-29 19:40:38 +02:00
Sheogorath 30b5ff0d96
Add session data to env vars
Currently the session secret can only be set by config.json or docker
secrets. This creates a problem on Heroku hosted instances that can not
set a session secret.

Since we automatically generate them on startup this results in an
logout of all users on every config change in Heroku.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-03-29 19:34:32 +02:00
Christoph (Sheogorath) Kern d2cce7638a
Merge pull request #780 from SISheogorath/fix/sessionSecret
Automatically generate a session secret if default is used
2018-03-28 12:25:01 +02:00
Christoph (Sheogorath) Kern 1649a9b742
Merge pull request #786 from SISheogorath/fix/compatiblityConfig
Fix some issues with legacy config compatiblity
2018-03-27 19:38:21 +02:00
Christoph (Sheogorath) Kern 2d1dc881b8
Merge pull request #788 from mcnesium/docs/gitlab
Add documentation for setting up authentication with a self-hosted GitLab
2018-03-27 18:02:32 +02:00
mcnesium 18d2bbb5f3 Add documentation for setting up authentication with a self-hosted GitLab
Signed-off-by: mcnesium <git@mcnesium.com>
2018-03-27 17:51:59 +02:00
Pedro Ferreira 99abac343b 403: redirect user to login page if not logged in
Signed-Off-By: Pedro Ferreira <pedro.ferreira@cern.ch>
2018-03-27 08:53:37 +02:00
Sheogorath 10a81e7db2
Fix logical error in legacy config expression
We should check for an undefined and not just for a logical true or
false.

Example: When `usecdn` was set to false it was impossible to overwrite
the new config value because the if statement becomes false.

Thanks @davidmehren for pointing me to this issue.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-03-26 20:49:37 +02:00
Sheogorath 4eef661c15
Rename forgotten values
Looks like we forgot something during the migration. This should fix it.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-03-26 20:15:45 +02:00
Pedro Ferreira 34df7ccce8 Use TEXT instead of STRING for tokens
Signed-off-by: Pedro Ferreira <pedro.ferreira@cern.ch>
2018-03-26 15:55:39 +02:00
Pedro Ferreira 40b3855702 Add support for generic OAuth2 providers
Signed-off-by: Pedro Ferreira <pedro.ferreira@cern.ch>
2018-03-26 15:55:39 +02:00
Christoph (Sheogorath) Kern 5d57a4bb6f
Merge pull request #779 from SISheogorath/fix/cspForVideo
Allow embedding of video and audio tags
2018-03-26 14:51:09 +02:00
Christoph (Sheogorath) Kern 6a4350af2b
Merge pull request #778 from SISheogorath/fix/nightModeToggle
Fix night mode button after restore
2018-03-26 11:27:38 +02:00
Sheogorath 7681076eb3
Add title attribute in table of contents
Right now the full title of an element is may not shown as the space of
the ToC is limited. With this path it'll be shower on hover and this way
provide more useful information.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-03-26 11:20:18 +02:00
Sheogorath 3599fb79b4
Automatically generate a session secret if default is used
The session secret is used to sign and authenticate the session cookie
and this way very important for the authentication process.

By default the session secret is set to `secret` and never changes. This
commit will add a generator for a dynamic session secret if it stays
unchanged.

It prevents session hijacking this way and will warn the user about
the missing secret.

This also implies that on a restart without configured session secret
will log out all users. While it may seems annoying, it's for the users
best.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-03-26 00:36:28 +02:00
Sheogorath 450262c4ab
Allow embedding of video and audio tags
Adding mediaSrc to CSP so video and audio files can be embedded without
problems.

From a security perspective it should be fine to load audio and video
data without introducing a high security issue. Only from a privacy
perspective it allows another way to track users if there are data
embedded. But it doesn't introduce any new attack vector as pictures are
also allowed from everywhere.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-03-25 20:51:56 +02:00
Sheogorath 8b69013ebd
Fix night mode button after restore
The night mode toggle doesn't get the right state after restore from
local storage. This results in the need to toggle twice to disable night
mode.

This patch adds the needed class so the toggleNightMode function gets
the right state on execution.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-03-25 20:12:02 +02:00
Christoph (Sheogorath) Kern 57c47a65dd
Merge pull request #758 from SISheogorath/cleanup/config
Change config to camel case with backwards compatibility
2018-03-25 19:15:17 +02:00
Sheogorath 2411dffa2c
Change config to camel case with backwards compatibility
This refactors the configs a bit to now use camel case everywhere.
This change should help to clean up the config interface and make it
better understandable.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-03-25 19:08:14 +02:00
Christoph (Sheogorath) Kern ea1d35eddb
Merge pull request #775 from SISheogorath/feature/nightMode
Persist nightmode so we can re-enable it on reload
2018-03-24 14:35:48 +01:00
Sheogorath 32c578db08
Persist nightmode so we can re-enable it
Right now the night mode is possible to set by a toggle in the menu bar
but needs to be re-enabled on every document switch, reload, etc.. This
is super annoying so we should keep this state in local storage or
a cookie.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-03-23 19:46:38 +01:00
Christoph (Sheogorath) Kern fa4a8418af
Merge pull request #772 from SISheogorath/fix/chromeFileError
Some fixes for inline-Attachments in Codemirror
2018-03-21 14:15:04 +01:00
Christoph (Sheogorath) Kern 6485f96659
Merge pull request #771 from SISheogorath/refactor/imageRouter
Refactoring imageRouter to modularity
2018-03-21 14:13:32 +01:00
Sheogorath 1756e76dc3
Refactoring imageRouter to modularity
This should make the imageRouter more modular and easier to extent. Also
a lot of code duplication was removed which should simplify maintenance
in future.

In the new setup we only need to provide a new module file which exports
a function called `uploadImage` and takes a filePath and a callback as
argument. The callback itself takes an error and an url as parameter.
This eliminates the need of a try-catch-block around the statement and
re-enabled the optimization in NodeJS.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-03-20 11:00:11 +01:00
Sheogorath 6e6a98b392
Update yarn.lock
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-03-18 15:36:52 +01:00
Christoph (Sheogorath) Kern 5361a97188
Merge pull request #770 from SISheogorath/fix/ldapUUID
Add check for undefined UUID
2018-03-18 15:13:51 +01:00
Christoph (Sheogorath) Kern f6df2deb84
Merge pull request #743 from hackmdio/fix-to-use-url-safe-base64
Fix to use url-safe base64 in note url
2018-03-18 15:13:06 +01:00
Sheogorath 6219962892
Reorganize usage of `getAsFile()`
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-03-18 03:11:28 +01:00
Sheogorath 41bf7cc52f
Fix typo in vedor extension
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-03-18 03:10:37 +01:00
Sheogorath 638eae0dfb
Add check for undefined UUID
This check is needed at there are tons of LDAP implementations out there
and none has at least one guaranteed unique field. As we currently check
three fields and added an option to select one yourself, it's still not
said that any of these fields is set. This will now create an error
and fail the authentication instead of letting people may get access to
other people's notes which are stored under a this way deterministic
wrong userid named `LDAP-undefined`.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-03-18 00:27:07 +01:00
Christoph (Sheogorath) Kern 6b30f66272
Merge pull request #757 from SISheogorath/fix/migration
Add missing migration for permissions
2018-03-17 21:33:02 +01:00
Christoph (Sheogorath) Kern e2b8b92530
Merge pull request #769 from SISheogorath/fix/minioInteger
Add helper function to fix number problems
2018-03-17 21:32:03 +01:00
Sheogorath d682695bf1
Add helper function to fix number problems
As minio causes various problem if you configure it using environment
variables and leave the port setting out, which will evaluate to NaN,
this change should fix this in a clean way for this time and helps to
support numbers in general in future.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-03-16 20:37:59 +01:00
Christoph (Sheogorath) Kern 9cbe03d8a8
Merge pull request #761 from SISheogorath/feature/reportURI
Add config option for report URI in CSP
2018-03-14 22:10:23 +01:00
Christoph (Sheogorath) Kern 976657dc21
Merge pull request #765 from vazontang/master
Convert  HMD_MINIO_PORT into Number type.
2018-03-14 21:33:21 +01:00
vazontang 070dd27f95
Convert HMD_MINIO_PORT into Number type.
fix hackmdio/hackmd#763

Signed-off-by: Tang TsungYi <vazontang@gmail.com>
2018-03-15 04:07:45 +08:00
Sheogorath efa490a50f
Add config option for report URI in CSP
This option is needed as it's currently not possible to add an report
URI by the directives array. This option also allows to get CSP reports
not only on docker based setup but also on our heroku instances.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-03-14 17:57:41 +01:00
Christoph (Sheogorath) Kern 2698aa4b5f
Merge pull request #760 from thegcat/fix/support_multiple_emails_in_ldap
Multiple emails from LDAP are already an Array
2018-03-10 20:40:59 +01:00
Max Wu 8bfe51940f Fix typo
Signed-off-by: Max Wu <jackymaxj@gmail.com>
2018-03-11 03:00:36 +08:00
Max Wu dfd833dbe2 Update to show log on migrate LZString type note url in history
Signed-off-by: Max Wu <jackymaxj@gmail.com>
2018-03-11 02:55:54 +08:00
Max Wu 5e975cbe69 Fix to log instead of throwing error on parse note id
Signed-off-by: Max Wu <jackymaxj@gmail.com>
2018-03-11 02:52:24 +08:00
Max Wu c7657ae81e Fix parseNoteId order to fix some edge case
that LZString note url could be parsed by base64url note url and thus return wrong note id

Signed-off-by: Max Wu <jackymaxj@gmail.com>
2018-03-10 16:52:24 +08:00
Max Wu 16cb842b94 Improve history migration performance
Signed-off-by: Max Wu <jackymaxj@gmail.com>
2018-03-10 16:51:00 +08:00
Felix Schäfer 12dae4465f Multiple emails from LDAP are already an Array
Signed-off-by: Felix Schäfer <felix@thegcat.net>
2018-03-09 14:39:08 +01:00
Sheogorath 21be5a5517
Update yarn.lock
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-03-07 11:30:08 +01:00
Christoph (Sheogorath) Kern 17d6fe716d
Merge pull request #756 from davidmehren/master
Remove engine.io-client dependency
2018-03-07 11:15:54 +01:00
Sheogorath f85ba6df53
Add missing migration for permissions
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-03-06 16:31:41 +01:00
David Mehren 7904558292
Remove engine.io-client dependency and fix webpack config
Signed-off-by: David Mehren <dmehren1@gmail.com>
2018-03-06 14:45:14 +01:00
Christoph (Sheogorath) Kern 66d8d3180a
Merge pull request #755 from thegcat/fix/remove_unused_ldap_options
Remove unused LDAP option `tokenSecret`

fixes #754
2018-03-06 14:22:50 +01:00
Felix Schäfer 6094c61871 Remove unused LDAP option `tokenSecret`
hackmdio/hackmd#754

Signed-off-by: Felix Schäfer <felix@thegcat.net>
2018-03-05 14:06:05 +01:00
Christoph (Sheogorath) Kern eb46378fc5
Merge pull request #753 from senk/patch-1
Fix small typo
2018-03-05 10:25:31 +01:00
Robin Naundorf e547664727 Fix small typo
Signed-off-by: Robin Naundorf <r.naundorf@fh-muenster.de>
2018-03-05 09:06:37 +01:00
Christoph (Sheogorath) Kern 96c9096d50
Merge pull request #750 from fooker/master
Use ldap.usernameField over hardcoded uid fields
2018-03-03 23:56:01 +01:00
Max Wu d08c9522c0 Update to migrate note url in the history of browser storage and cookie
Signed-off-by: Max Wu <jackymaxj@gmail.com>
2018-03-03 16:26:19 +08:00
Dustin Frisch d6ee10d176
Introduce ldap.useridField
Signed-off-by: Dustin Frisch <fooker@lab.sh>
2018-03-01 23:51:47 +01:00
Max Wu fe429e9ac1 Update to use buffer in encode/decode note id
Signed-off-by: Max Wu <jackymaxj@gmail.com>
2018-02-27 20:57:31 +08:00
Christoph (Sheogorath) Kern b0ce3d0230
Merge pull request #744 from hackmdio/add-more-html5-tags
Support more html5 tags and styles
2018-02-26 19:41:53 +01:00
Max Wu ea118c2ec8 Update styles of details, summary and figure
Signed-off-by: Max Wu <jackymaxj@gmail.com>
2018-02-26 21:05:13 +08:00
Max Wu 95e9f96aa0 Update to allow rp tag for ruby
Signed-off-by: Max Wu <jackymaxj@gmail.com>
2018-02-26 20:55:10 +08:00
Max Wu 711a11ce23 Remove manual allow details tag since default already allow it
Signed-off-by: Max Wu <jackymaxj@gmail.com>
2018-02-26 20:54:57 +08:00
Max Wu 44298baa93 Add migration for LZString compressed note id in history
Signed-off-by: Max Wu <jackymaxj@gmail.com>
2018-02-26 16:46:59 +08:00
Max Wu baa0418fb5 Remove and replace all note id compression in LZString with base64url
Signed-off-by: Max Wu <jackymaxj@gmail.com>
2018-02-26 16:43:29 +08:00
Christoph (Sheogorath) Kern 912cce2b40
Merge pull request #740 from SISheogorath/feature/moreHTML5
Extend HTML5 support by whitelisting various tags
2018-02-25 21:50:11 +01:00
Sheogorath 5d347d583d
Extend HTML5 support by whitelisting various tags
HTML5 provides a wide feature set of useful elements. Since Markdown
usually supports HTML it should be able to use these HTML5 tags as well.
As they were requested by some users and they where checked for being
safe, whitelisting them isn't a problem. To make the experience the same
as on GitHub when it comes to the basic look and feel of the rendered
markdown, some CSS was added to make the summary and the details tag
look like on GitHub.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-02-25 14:54:21 +01:00
Christoph (Sheogorath) Kern f642a11599
Merge pull request #739 from SISheogorath/fix/sublime-esc
Allow the usage of the esc-key by codemirror
2018-02-25 14:25:26 +01:00
Sheogorath 9c77e9d7f0
Allow the usage of the esc-key by codemirror
This change allows all input modes of codemirror to use the information
from an input esc-key and make this way vim and sublime more
functional. To prevent this change from breaking the return from the
fullscreen mode, it catches the esc-key in this case. Hopefully this is
an acceptable solution.

As before the vim-mode is handled different in fulltext-mode as it is
esc-key heavy.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-02-24 21:14:47 +01:00
Christoph (Sheogorath) Kern 6bcc72e090
Merge pull request #735 from SISheogorath/fix/jsonlint
Use jq instead of jsonlint
2018-02-19 20:00:59 +01:00
Sheogorath faa839ed3a
Use jq instead of jsonlint
As the jsonlint package from NPM causes problems and looks unmaintained,
it'll be replaced with `jq` a well maintained project which allows to
search through JSON files in a `grep`-like style, but knowing the JSON
structure.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-02-19 19:50:01 +01:00
Christoph (Sheogorath) Kern 298d3d62bb
Merge pull request #730 from Zearin/patch-1
Update README.md
2018-02-19 11:32:13 +01:00
Zearin b8e019c6b0 Rerun doctoc
Signed-off-by: Anthony "Zearin" Rogers <zearin@users.sourceforge.net>
2018-02-17 13:08:05 -05:00
Zearin b0f524e55e Update README.md
Signed-off-by: Anthony "Zearin" Rogers <zearin@users.sourceforge.net>
2018-02-17 12:51:48 -05:00
Christoph (Sheogorath) Kern e4783837ef
Merge pull request #728 from hackmdio/fix-show-error-in-parseNoteId
Fix to show 500 message when got error in parseNoteId
2018-02-17 17:32:26 +01:00
Max Wu 15ef54c2dc Fix to show 500 message when got error in parseNoteId
Signed-off-by: Max Wu <jackymaxj@gmail.com>
2018-02-17 00:57:00 +08:00
Christoph (Sheogorath) Kern e793738833
Merge pull request #725 from SISheogorath/fix/referrerPolicy
Add referrer policy
2018-02-12 22:23:19 +01:00
Sheogorath 714504618c
Add referrer policy
This commit adds a referrer policy to all requests.

The usage of `same-origin` allows HackMD to still interpret all requests
and this way not break anything. But it prevents 3rd party scripts,
pictures and more to get informations that may lead to not secured note.

It has to be mentioned that this maybe breaks some features of the
Google Analytics embedding. This has to be tested.

Fixes #724

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-02-12 01:59:48 +01:00
Max Wu bb5e021f20 Fix field type to prevent data truncation of authorship (#721)
* Fix field type to prevent data truncation of authorship
2018-02-09 14:27:06 +01:00
Christoph (Sheogorath) Kern dfa0851d8f
Add matrix.org badge to README.md
Matrix.org is an interesting platform for collaboration and community building. 

Thanks to various clients it supports it's maybe better than gitter to keep people on track and have a community feeling, discuss changes and more.

Not not split up into two parties not knowing of each other, the Gitter channel and the Matrix channel are bridged. This helps to keep everyone informed while add more medias.

Signed-off-by: Christoph Kern <sheogorath@shivering-isles.com>
2018-02-08 15:27:07 +01:00
Christoph (Sheogorath) Kern d7c66ea49b
Merge pull request #718 from takmatsu/master
Fix typo of DB migration script
2018-02-08 14:53:20 +01:00
Takeaki Matsumoto a9973cabc4 Fix typo of DB migration script
Signed-off-by: Takeaki Matsumoto <takeaki.matsumoto@ntt.com>
2018-02-08 10:15:05 +09:00
Christoph (Sheogorath) Kern f3358b49f5
Merge pull request #716 from stbuehler/fix-referer
don't require referer to find note id in socket.io connections (fixes #623)
2018-02-05 14:50:47 +01:00
Stefan Bühler c4f8fb78ee don't require referer to find note id in socket.io connections (fixes #623)
Signed-off-by: Stefan Bühler <buehler@cert.uni-stuttgart.de>
2018-02-05 14:26:42 +01:00
Christoph (Sheogorath) Kern 2024262200
Merge pull request #714 from SISheogorath/fix/uncaughtException
Fix uncaught exception for non-existent user
2018-01-31 20:48:59 +01:00
Sheogorath 1a4800e21a
Update Heroku button
The button needs a parameter to work, that provides the git repository
that is used for the deployment. This commit corrects the link and this
way fixes the provisioning as it's not working with the wrong/default
buildpacks.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-01-31 14:00:49 +01:00
Sheogorath 6b97dd7aac
Update yarn.lock
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-01-31 01:16:52 +01:00
Sheogorath eddf8a3a33
Fix uncaught exception for non-existent user
Since we added user management it's possible to get non-existent users
which can cause a crash of the Backend server.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-01-30 21:53:36 +01:00
Christoph (Sheogorath) Kern e5edd1a124
Merge pull request #713 from SISheogorath/update/socketio
Update socket.io to version 2.0.4
2018-01-30 21:43:31 +01:00
Sheogorath a01b4a843c
Update socket.io to version 2.0.4
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-01-30 19:44:32 +01:00
Sheogorath a40dcdd222
Prevent "wrong type"-issue
The argument is may interpreted as number which causes the "pass"
parameter of the user creation to fail. Probably the same applies to the
mail address. But mail addresses are by definition not allowed to start
by a number (iirc) which makes it less a problem. This is mainly a quick
fix. Should be refactored a bit in future.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-01-29 22:41:12 +01:00
Sheogorath e055f270b4
Update yarn.lock
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-01-29 22:37:02 +01:00
Christoph (Sheogorath) Kern 80950f806b
Merge pull request #707 from Nebukadneza/add_cmdline_usermanager
Add simple user-management tool for emailsignin
2018-01-29 22:35:20 +01:00
Sheogorath be02aed1c0
Update badges in README.md
The docker badges have to be updated since we now provide official image
like tags. So `latest-alpine` became `alpine`.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-01-29 22:01:31 +01:00
Dario Ernst 31f1db4100 Make travis run shellcheck only on shellscripts
There are only a few scripts in bin/, but not all might be shell. At
least for the moment, it seems reasonable to explicitely enumerate all
shell-scripts in bin/ for shellcheck …

Signed-off-by: Dario Ernst <dario@kanojo.de>
2018-01-29 19:49:04 +01:00
Dario Ernst 9e0359e079 Add simple user-management tool for emailsignin …
Currently, administrators of closed instances need to manually fiddle in
their databases for user-management.
This commit adds a small commandline utility that allows to create and
delete users.

Signed-off-by: Dario Ernst <dario@kanojo.de>
2018-01-29 19:49:04 +01:00
Sheogorath 4c08afbbb5
Update yarn.lock
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-01-29 16:38:32 +01:00
Christoph (Sheogorath) Kern adc781f7e3
Merge pull request #704 from SISheogorath/fix/ldapProviderName
Fix ldap provider name in template
2018-01-29 15:59:27 +01:00
Christoph (Sheogorath) Kern e18e05541c
Merge pull request #705 from SISheogorath/fix/camelcaseConfig
Remove camel case from `imageuploadtype` in config
2018-01-29 15:53:14 +01:00
Christoph (Sheogorath) Kern d8766bbc08
Merge pull request #710 from hackmdio/feature/upgradeRevealJS
Upgrade reveal.js to 3.6.0 and useCDN option for CSS include
2018-01-29 15:19:23 +01:00
Wu Cheng-Han 3c473e60a6 Upgrade reveal.js to 3.6.0 and useCDN option for CSS include 2018-01-29 13:09:52 +08:00
Sheogorath bd92010dd2
Remove camel case from `imageuploadtype` in config
This removes the only camel cased option of the config options
**we** added to the config.json.

In auth provider's config parts are a lot of camel cased options
provided. We shouldn't touch them to keep them as similar as
possible to the examples.

Fixes #315

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-01-27 23:50:15 +01:00
Sheogorath aca5490b3a
Add recommendation for 2GB RAM
We noticed on multiple places that machines with less than 2GB of RAM
fail their build and result in missing files and unexpected errors.

Sadly we can't really solve this right now since it's a webpack
related bug.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-01-26 18:30:01 +01:00
Sheogorath e44751b3f1
Fix ldap provider name in template
Before this fix it's impossible to set the provider name in the
sign-model since `ldap` is a boolean there and this way not able
to have an attribute like `ldap.providerName`.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-01-26 10:46:22 +01:00
Sheogorath 0138911274
Extend README changes for minio 2018-01-26 10:23:51 +01:00
Christoph (Sheogorath) Kern 6dae85f4aa
Merge pull request #698 from SISheogorath/docs/minio
Adding some docs for new Minio Feature
2018-01-26 00:35:50 +01:00
Christoph (Sheogorath) Kern e52d7db96c
Merge pull request #694 from SISheogorath/refactor/socialmedia
Reorganize social media links and footer
2018-01-25 17:40:11 +01:00
Sheogorath e5074df910
Update yarn.lock
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-01-24 19:50:09 +01:00
Sheogorath 16892cd827
Reorganize social media links and footer
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-01-24 14:09:36 +01:00
Christoph (Sheogorath) Kern a49e603c38
Merge pull request #700 from hackmdio/fix-toggle-todo
Fix task todo might not toggle
2018-01-24 09:39:17 +01:00
Max Wu a9c88ce248
Fix task todo might not toggle
which caused by not matching syntax with double dashes correctly
2018-01-24 00:10:52 +08:00
Christoph (Sheogorath) Kern 584f1c5249
Merge pull request #691 from SISheogorath/feature/upload
Allow more detailed configuration of upload mime types
2018-01-23 12:10:33 +01:00
Christoph (Sheogorath) Kern e0389bc4cf
Merge pull request #697 from SISheogorath/fix/minio
Fix broken port config
2018-01-23 12:09:41 +01:00
Sheogorath 817bb9e639
Fix broken port config
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-01-23 12:00:11 +01:00
Sheogorath 587a6e2239
Add README and `config.json.example` content
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-01-23 11:59:07 +01:00
Sheogorath a99467f006
Add minio guide
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-01-23 11:48:00 +01:00
Christoph (Sheogorath) Kern eec2318bda
Merge pull request #506 from erasys/minio
Add support for minio
2018-01-23 11:43:24 +01:00
Christoph (Sheogorath) Kern 7de6e3211f
Merge pull request #598 from xxyy/feature/csp
Implement basic CSP support
2018-01-22 20:43:46 +01:00
Christoph (Sheogorath) Kern fbfe3272f5
Merge pull request #695 from SISheogorath/translate/chinese
Add some missing chinese translations
2018-01-22 17:51:56 +01:00
Sheogorath 36b0524b78
Add some chinese translations
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-01-22 14:22:43 +01:00
Christoph (Sheogorath) Kern 268c81a323
Merge pull request #673 from fooker/master
Allow posting new note with content
2018-01-20 19:45:41 +01:00
Christoph (Sheogorath) Kern 5d9a2c3569
Merge pull request #688 from hackmdio/add-ce-text-on-index
Add CE text on index title
2018-01-20 18:56:39 +01:00
Christoph (Sheogorath) Kern b7e227e9d5
Merge pull request #690 from Nebukadneza/add_allow_anonymous_edits
Add option to enable `freely` permission in closed instance
2018-01-20 18:56:09 +01:00
Christoph (Sheogorath) Kern 2eb30782d5
Merge pull request #687 from SISheogorath/refactor/contact
Remove/update contact details
2018-01-20 18:51:22 +01:00
Christoph (Sheogorath) Kern 38a46c8373
Merge pull request #693 from SISheogorath/translate/german
Extent german translation
2018-01-20 18:50:43 +01:00
Sheogorath 64d8c747f0
Extent german translation
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-01-20 18:23:19 +01:00
Sheogorath dc10ec60fb
Remove/update contact details
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-01-20 17:40:00 +01:00
Sheogorath a7935a595a
Allow more detailed configuration of upload mime types
Fixes #637

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-01-20 15:16:53 +01:00
Dario Ernst 6ae4b8bf13 Add option to enable `freely` permission in closed instance
Before, closed disallowed guest edits completely, by removing
the `freely` permission. This makes it possible to explicitely bring
back guest-editing, but not guest-note-creation, to closed instances.

Signed-off-by: Dario Ernst <dario@kanojo.de>
2018-01-20 15:14:56 +01:00
Max Wu 05cc3a73a2
Update body.ejs
Add CE text on index title
2018-01-20 10:12:38 +08:00
Sheogorath 40d1d75704
Release 1.0.1-ce 2018-01-19 14:40:15 +01:00
Christoph (Sheogorath) Kern da462e01f5
Merge pull request #680 from hackmdio/show-ce-on-title
Update README.md
2018-01-19 14:35:08 +01:00
Christoph (Sheogorath) Kern 60005d3039
Merge pull request #686 from SISheogorath/feature/configVersion
Load version from package.json
2018-01-19 14:34:54 +01:00
Christoph (Sheogorath) Kern feb89f02e2
Merge pull request #684 from hackmdio/fixDropboxAppKey
Fix not passing app key correctly in dropbox config

⚠️ Dropbox ClientSecret was leaked  ⚠️ 

Fixes #683
2018-01-19 14:31:04 +01:00
Christoph (Sheogorath) Kern d492070d3a
Merge pull request #685 from hackmdio/fixImageAlt
Fix image alt not render properly

Fixes #638
2018-01-19 14:26:06 +01:00
Sheogorath a0fdfccb22
It's 2018! 🎉 2018-01-19 14:08:16 +01:00
Sheogorath 583aa4f462
Load version from package.json
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-01-19 13:54:19 +01:00
Wu Cheng-Han 3703b12584 Fix image alt not render properly 2018-01-19 00:53:49 +08:00
Wu Cheng-Han 608008753f Fix not passing app key correctly in dropbox config 2018-01-19 00:25:08 +08:00
Sheogorath 11a5dd0eb4
Release 1.0.0-ce 2018-01-18 13:03:18 +01:00
Christoph (Sheogorath) Kern eb0bda06d7
Merge pull request #682 from SISheogorath/extend/gitignore
Add package-lock.json to .gitignore
2018-01-18 11:22:45 +01:00
Christoph (Sheogorath) Kern 86fbdeea7d
Merge pull request #681 from SISheogorath/fix/420
Ignore empty values for revision.
2018-01-18 11:22:18 +01:00
Sheogorath 15e1189258
Add package-lock.json to .gitignore 2018-01-18 11:21:07 +01:00
Sheogorath 8bf8a1aef1
Ignore empty values for revision.
Fixes #420
2018-01-18 11:19:47 +01:00
Christoph (Sheogorath) Kern 8375544dea
Merge pull request #636 from laysdra7265/fix/sslcapath
Fix sslcapath bug
2018-01-18 11:17:17 +01:00
Christoph (Sheogorath) Kern af082d9347
Merge pull request #567 from ccoenen/fix-mysql-text-length
converting all content fields to MEDIUMTEXT (affects MySQL only)
2018-01-18 11:16:59 +01:00
Dustin Frisch f47601857e
Allow posting new note with content
Signed-off-by: Dustin Frisch <fooker@lab.sh>
2018-01-18 10:41:58 +01:00
Max Wu d073a8ea19
Update README.md
To show "Community Edition" on title.
2018-01-18 13:36:12 +08:00
Christoph (Sheogorath) Kern 9219a9b48c
Merge pull request #679 from SISheogorath/update/yarnlock
Update yarn.lock
2018-01-17 16:36:15 +01:00
Sheogorath ae294f51f5
Update yarn.lock
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2018-01-17 16:34:56 +01:00
Christoph (Sheogorath) Kern e38054113e
Merge pull request #678 from hackmdio/fix-anchor-id-case-sensitive
Fix anchor id to keep uppercase characters
2018-01-16 16:31:41 +07:00
Christoph (Sheogorath) Kern 5f84906b2e
Merge pull request #677 from hackmdio/realtime-minor-typos
Fix minor typos in realtime
2018-01-16 16:28:14 +07:00
Max Wu 919b7467d4
Fix anchor id to keep uppercase characters
id shouldn’t be converted to lowercase since id attribute is case sensitive
2018-01-16 15:59:43 +08:00
Max Wu 68879d20ed
Fix minor typos
of wrong parameters passing order and wrong user object indexing in for each function
2018-01-16 15:51:24 +08:00
Christoph (Sheogorath) Kern 4b419f4877
Merge pull request #664 from schneems/schneems/codetriage-badge
[ci skip] Add CodeTriage badge
2018-01-16 14:43:36 +07:00
Christoph (Sheogorath) Kern 40f1c46453
Merge pull request #668 from xuxiaodong/master
Fix config.json.example format error
2018-01-16 14:39:10 +07:00
Christoph (Sheogorath) Kern 7201144661
Merge pull request #661 from edoardoo/darkTheme
Implemented dark theme.
2018-01-16 14:38:14 +07:00
Xiaodong Xu ac8c381b6e Fix config.json.example format error 2018-01-09 16:45:32 +08:00
Edoardo Odorico 6fc2c39eda Implemented dark theme.
Signed-off-by: Edoardo Odorico <edoubuntu@gmail.com>
2018-01-05 00:15:13 +01:00
schneems 0b7b7244b5 [ci skip] Add CodeTriage badge
[CodeTriage](https://www.codetriage.com/) is an app I have maintained
for the past 4-5 years with the goal of getting people involved in
Open Source projects like this one. The app sends subscribers a random
open issue for them to help "triage". For some languages you can also
suggested areas to add documentation.

The initial approach was inspired by seeing the work of the small
core team spending countless hours asking "what version was
this in" and "can you give us an example app". The idea is to
outsource these small interactions to a huge team of volunteers
and let the core team focus on their work.

I want to add a badge to the README of this project. The idea is to
provide an easy link for people to get started contributing to this
project. A badge indicates the number of people currently subscribed
to help the repo. The color is based off of open issues in the project.

Here are some examples of other projects that have a badge in their
README:

- https://github.com/crystal-lang/crystal
- https://github.com/rails/rails
- https://github.com/codetriage/codetriage

Thanks for building open source software, I would love to help you find some helpers.
2018-01-03 21:08:15 -06:00
Christoph (Sheogorath) Kern 45976a8916
Update index.js 2017-12-22 12:25:13 +01:00
Christoph (Sheogorath) Kern fc626a6724
Simplify loop 2017-12-22 12:19:19 +01:00
Christoph (Sheogorath) Kern a8fa888317
Merge pull request #656 from PeterDaveHello/fix-file-permission
Fix file permission, remove useless executable
2017-12-14 11:35:22 +01:00
Peter Dave Hello 76873d3f7e Fix file permission, remove useless executable 2017-12-14 05:05:18 +08:00
Christoph (Sheogorath) Kern 454e0f8612
Merge pull request #650 from LukasKalbertodt/ldap-username-field
Add setting `ldap.usernameField`
2017-12-12 10:40:14 +01:00
Christoph (Sheogorath) Kern b840c3fa57
Merge pull request #609 from monoxane/master
Correcting grammatical errors related to the document char count tooltip
2017-12-12 10:39:49 +01:00
Christoph (Sheogorath) Kern 17e3b8b5cd
Merge branch 'master' into ldap-username-field 2017-12-12 10:27:22 +01:00
Christoph (Sheogorath) Kern 74758723f9
Merge pull request #651 from alecdwm/ldap-auth-searchattributes-fix
Parse env var `HMD_LDAP_SEARCHATTRIBUTES` as a comma-separated array
2017-12-12 10:23:42 +01:00
alecdwm 5e5a021ce0 parse HMD_LDAP_SEARCHATTRIBUTES env var as a comma-separated array
Signed-off-by: Alec WM <firstcontact@owls.io>
2017-12-09 20:33:57 +01:00
Christoph (Sheogorath) Kern e9e7a8e23d
Update README.md 2017-12-09 19:36:18 +01:00
Lukas Kalbertodt 612b2d1811 Add setting `ldap.usernameField`
This determines which ldap field is used as the username on
HackMD. By default, the "id" is used as username, too. The id
is taken from the fields `uidNumber`, `uid` or
`sAMAccountName`. To give the user more flexibility, they can
now choose the field used for the username instead.
2017-12-09 12:30:48 +01:00
Max Wu 1b7d621fd1
Merge pull request #578 from hackmdio/licenseChangeAgreement
License Change Agreement
2017-12-07 06:54:12 +08:00
LaysDragon 9949795533 fixed sslcapath bug 2017-12-05 12:06:10 +08:00
Christoph (Sheogorath) Kern 0957f5963b
Merge pull request #633 from nakaeeee/saml-auth
Support SAML authentication
2017-12-04 18:57:57 +01:00
Norihito Nakae 2db2ff484f added guide for SAML settings 2017-12-04 20:13:15 +09:00
Christoph (Sheogorath) Kern 8112cd6fef
Merge pull request #646 from SISheogorath/fix/CI
Fix build problem by updating yarn version
2017-12-04 02:58:35 +01:00
Sheogorath bb37ef87d5
Fix build problem by updating yarn version 2017-12-04 02:42:19 +01:00
Christoph (Sheogorath) Kern a0736f9a2e
Merge pull request #639 from mosterdt/master
Fix small spelling mistake and add untranslated sentences to locale
2017-12-03 21:05:50 +01:00
Thomas De Backer c60030b205 close open tags 2017-12-01 20:56:39 +01:00
Thomas De Backer 4eef4875ed Add untranslated sentences to locale 2017-11-30 19:02:40 +01:00
Norihito Nakae 410268da74 added environment variables for SAML 2017-11-29 20:26:28 +09:00
Norihito Nakae a22be81feb fixed the SAML callback URL to unconfigurable. 2017-11-29 15:45:32 +09:00
Norihito Nakae 4a4ae9d332 Initial support for SAML authentication 2017-11-28 18:52:24 +09:00
Christoph (Sheogorath) Kern f0bfa87fbf
Merge pull request #631 from SISheogorath/update/yarn
Update yarn
2017-11-27 08:27:57 +01:00
Sheogorath 9c002ce29b Update yarn 2017-11-27 08:14:28 +01:00
Christoph (Sheogorath) Kern 8ea09a8bd0
Merge pull request #627 from SISheogorath/fix/XSS
Prevent XSS vulnerbility by srcdoc in iframe
2017-11-24 18:09:41 +01:00
Sheogorath 93b91163cd
Prevent XSS vul by srcdoc in iframe 2017-11-24 10:10:50 +01:00
Christoph (Sheogorath) Kern 978ec84906
Merge pull request #601 from devonJS/auth-docs
Added small guide for auth providers GitHub and Twitter
2017-11-09 13:34:18 +01:00
Devon Jue 8c916bb987 added auth docs and images for GitHub and Twitter 2017-11-08 21:20:50 -08:00
Literallie 3a752fde51
Revert "Load js-url lib using legacy-loader"
Didn't work in Firefox for some reason.

`[Script Loader] ReferenceError: module is not defined`

This reverts commit 5b83deb043.
2017-11-02 17:57:44 +01:00
Sheogorath d8997f938b
Merge pull request #615 from PeterDaveHello/patch-1
[README] Add icons to browser version support list
2017-10-31 15:18:03 +01:00
Peter Dave Hello 05541f1546
[README] Add icons to browser version support list 2017-10-31 22:13:36 +08:00
Sheogorath 4c6e768a52
Merge pull request #614 from SISheogorath/fix/mattermostVar
Fix mattermost breaking notes
2017-10-31 14:16:06 +01:00
Sheogorath 8808399c48
Fix mattermost breaking notes 2017-10-31 13:48:35 +01:00
Sheogorath 66b3463825
Merge pull request #604 from PeterDaveHello/refactor-TravisCI-config
Refactor travis ci config
2017-10-31 12:12:33 +01:00
Sheogorath 16b3e015ab
Merge pull request #606 from DoubleMalt/feature/MattermostAuth
Add Mattermost authentication strategy
2017-10-31 12:11:41 +01:00
Christoph Witzany 5cda55086a Add mattermost authentication 2017-10-31 10:34:51 +01:00
Sheogorath f2812730e0
Merge pull request #613 from SISheogorath/fix/allowerrorHandling
Fix allowpdfexport handling on error page
2017-10-31 02:22:42 +01:00
Sheogorath ef49b72442
Fix allowpdfexport handling on error page 2017-10-31 01:57:32 +01:00
Sheogorath 6ca28845c2
Merge pull request #605 from SISheogorath/feature/extentReadme
Extend docker section in README
2017-10-30 23:04:13 +01:00
Sheogorath dad5798472
Merge pull request #612 from SISheogorath/fix/mermaidErr
Fix mermaid error handling

Fixes #610
2017-10-30 12:30:38 +01:00
Sheogorath e807f1b783
Fix mermaid error handling 2017-10-30 12:26:28 +01:00
Sheogorath 803a2776ad
Extend docker section 2017-10-30 07:50:50 +01:00
Sheogorath b3c66d4a10
Merge pull request #608 from SISheogorath/fix/mermaid
Use mermaidAPI in mermaid scope
2017-10-30 07:24:57 +01:00
Sheogorath 09d2ba41cf
Use mermaidAPI in mermaid scope
Introduced by a5b7145527 (diff-67ae90c5144c55348a3cbdb078240454L532)

Fixes #600

Parse only throws error: 167368d508 (diff-67ae90c5144c55348a3cbdb078240454)
2017-10-30 07:11:14 +01:00
Oliver Herrmann b7e87f7767
Merge pull request #1 from monoxane/monoxane-patch-1
Corrected some grammatical issues with document length limits.
2017-10-30 11:26:47 +11:00
Oliver Herrmann 7d0ef1276c
Corrected some grammatical issues
Obviously caught up in a bad translation and didn't particularly make sense for native english speakers.
2017-10-30 11:25:44 +11:00
Sheogorath f1475535a2
Merge pull request #607 from PeterDaveHello/upgrade-mermaid
Upgrade mermaid to v7.1.0, fix #600
2017-10-29 17:32:41 +01:00
Peter Dave Hello da2426ae3d Update yarn.lock 2017-10-30 00:21:35 +08:00
Peter Dave Hello f896432250 Upgrade mermaid to v7.1.0, fix #600 2017-10-30 00:18:53 +08:00
Peter Dave Hello 7478dd14e0 Add build, ShellCheck, doctoc & jsonlint test on Travis CI 2017-10-29 23:01:46 +08:00
Peter Dave Hello cae9bb2e7d Use matrix(jobs) in .travis.yml 2017-10-29 23:01:44 +08:00
Sheogorath 862545fff7
Merge pull request #462 from CrazyPython/patch-1
Fix grammar and use best English standards
2017-10-27 22:15:42 +02:00
Sheogorath abbc43f9b6 Merge pull request #599 from xxyy/fix/inline-styles
Externalise some trivial inline styles from slide.ejs
2017-10-27 13:24:26 +02:00
Sheogorath 881e800fd8 Merge pull request #562 from SISheogorath/fix/LDAP
Fix LDAP problem about missing uidNumber
2017-10-27 12:48:45 +02:00
Sheogorath 94021e2d34 Merge pull request #574 from PeterDaveHello/README.md-Table-of-Contents
Add "Table of Contents" in README.md
2017-10-27 11:51:50 +02:00
Sheogorath be5de239ea Merge pull request #589 from geekyd/master
Adds enable/disable PDF export via config
2017-10-25 15:56:17 +02:00
geekyd f7d2ef970a Adds 403 response if PDF export is disabled 2017-10-25 19:21:34 +05:30
geekyd 0be09e109f Adds HMD_ALLOW_PDF_EXPORT to readme 2017-10-25 19:20:36 +05:30
geekyd d63e6780eb Adds PDF export via config 2017-10-25 19:19:37 +05:30
Literallie af935e46fc
Externalise trivial inline styles from slide.ejs
Dynamic background images need some further work
2017-10-23 23:39:18 +02:00
Sheogorath c794412714 Merge pull request #591 from Rwing/master
support Simplified Chinese and rename original zh to Traditional Chinese
2017-10-23 11:53:31 +02:00
Rwing 362a7eaf65 support Simplified Chinese and rename original zh to Traditional Chinese 2017-10-23 17:38:04 +08:00
Literallie 567f26f5b9
Fix MathJax config not being picked up
thanks standard
2017-10-22 02:48:24 +02:00
Literallie 04f5e3a341
Move CSP logic to new file, Fix boolean config examples
Not sure why I was quoting these in the first place
2017-10-22 02:18:45 +02:00
Literallie e5f03fe135
Add dirty workaround for speakers view inline script 2017-10-22 00:03:46 +02:00
Literallie 2b2b8d6d1d
Allow any connect-src in CSP
Managing these for all the integrations seems like a lot of effort
2017-10-22 00:03:46 +02:00
Literallie d51da8c12c
Don't add nonce to CSP if unsafe-inline is on
Browsers ignore unsafe-inline if a nonce is sent
2017-10-22 00:03:46 +02:00
Literallie 91101c856c
Change CSP config format to be more intuitive 2017-10-22 00:03:46 +02:00
Literallie 5b83deb043
Load js-url lib using legacy-loader
Doesn't use eval, plus no window object access
2017-10-22 00:03:45 +02:00
Literallie 996cb37991
CSP: Workaround for ws:// protocol
The spec allows wss:// for 'self', but not ws:// :(
2017-10-22 00:03:45 +02:00
Literallie 0cbdc852cb
CSP: Allow more content types 2017-10-22 00:03:45 +02:00
Literallie 4238b9b3ef
Fix MathJax CSP issues 2017-10-22 00:03:45 +02:00
Literallie 080436aebb
CSP: Add nonce to slide view inline JS 2017-10-22 00:03:45 +02:00
Literallie 5d2d3ec875
CSP: Upgrade insecure requests if possible
Config option; default is to only upgrade if usessl
2017-10-22 00:03:45 +02:00
Literallie ba183ce654
Add basic CSP support 2017-10-22 00:03:44 +02:00
Sheogorath a23048254d Merge pull request #597 from hackmdio/fix-gist-tag-structure
Fix markdown-it gist plugin code closing tag

Fix #596
2017-10-21 14:30:09 +02:00
Yukai Huang 60b86e0250 Fix markdown-it gist plugin code closing tag
fix #596
2017-10-21 11:45:17 +08:00
Sheogorath 92b769fb26 Merge pull request #595 from geekyd/swap
Hides empty export section
2017-10-19 15:04:27 +02:00
Sheogorath 053e616be5 Merge pull request #586 from PeterDaveHello/jsonlint
Add jsonlint script to ensure all json files are valid
2017-10-18 01:18:21 +02:00
geekyd 80fb91976e Hides empty export section 2017-10-18 03:34:45 +05:30
Sheogorath 80f1c8197a Merge pull request #593 from felixonmars/patch-1
Fix a typo in README.md
2017-10-17 20:01:37 +02:00
Felix Yan b72556b915 Fix a typo in README.md 2017-10-17 23:48:33 +08:00
Claudius Coenen cc49ce55c8 Fix #521 by converting content fields to LONGTEXT in MySQL, to prevent truncation of data. 2017-10-16 10:13:11 +02:00
Sheogorath 5ce8f40eac Merge pull request #585 from xxyy/feature/hsts-cfg
Make HSTS Behaviour Configurable (Fixes #584)
2017-10-14 18:02:41 +02:00
James 76ffd398af Update en.json 2017-10-13 20:35:57 -04:00
James 2550541b69 Update en.json 2017-10-13 20:35:00 -04:00
Sheogorath ec8936a9f1 Merge pull request #569 from SISheogorath/feature/extendedPermissionDocs
Provide table for permissions
2017-10-14 01:51:29 +02:00
Peter Dave Hello f70d2df1be Add jsonlint script to ensure all json files are valid 2017-10-14 00:19:32 +08:00
Peter Dave Hello 0864b06e0c Integrate npm package "doctoc" to update README.md 2017-10-13 16:21:25 +08:00
Peter Dave Hello 6fadd9126e Add "Table of Contents" in README.md 2017-10-13 15:59:57 +08:00
Peter Dave Hello 4ebda60165 Reorganize README.md structure, cc #574 2017-10-13 15:57:58 +08:00
Literallie 6bdc90d6ff
Add env vars for extra HSTS options 2017-10-13 01:42:05 +02:00
Literallie 1634d5c567
Add on/off env var for HSTS 2017-10-13 01:42:05 +02:00
Literallie 56411ca0e1
Make HSTS behaviour configurable; Fixes #584 2017-10-13 01:42:05 +02:00
Wu Cheng-Han bee5e2a558 Update license field in package.json 2017-10-13 01:56:13 +08:00
Sheogorath f93a14e3e1 Fix LDAP problem about missing uidNumber
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2017-10-12 14:52:28 +02:00
Sheogorath a16bde70be Provide table for permissions
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2017-10-12 11:05:22 +02:00
Sheogorath 53c2d0b5ca Merge pull request #581 from SISheogorath/fix/HMD_URL_ADDPORT
Fix missing boolean setting for HMD_URL_ADDPORT
2017-10-12 00:01:27 +02:00
Sheogorath 89c60d1331
Fix missing boolean setting for HMD_URL_ADDPORT
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2017-10-11 23:13:22 +02:00
Wu Cheng-Han da5026859d Update contributing guide for signed-off and DCO 2017-10-12 02:07:03 +08:00
Wu Cheng-Han 45717da98d Fix typo 2017-10-12 02:06:08 +08:00
Wu Cheng-Han 8086cdb749 Change license from MIT to AGPLv3 2017-10-12 01:45:57 +08:00
Wu Cheng-Han 81af737ce6 Update authors list and add contributors file 2017-10-12 01:45:17 +08:00
Wu Cheng-Han 4e94f44a12 Add sign you work section in contributing and DCO 2017-10-12 01:44:55 +08:00
Sheogorath 8b65d7df1a Merge pull request #575 from PeterDaveHello/fix.travis.yml
Remove duplicated nodejs version in .travis.yml
2017-10-11 10:23:30 +02:00
Sheogorath 4dd60cee50 Merge pull request #566 from ccoenen/fix-mysql-revision-order
createdAt DESC with quotation marks did not work with MySQL fixes #565
2017-10-11 01:08:16 +02:00
Claudius Coenen 87ac05738f Merge pull request #573 from PeterDaveHello/add-version-badge
Add version badge in README.md
2017-10-10 23:45:50 +02:00
Sheogorath 11133c3cec Merge pull request #571 from SISheogorath/fix/shellcheck
Prevent argument breaking by spaces
2017-10-10 23:28:16 +02:00
Peter Dave Hello 711c38403d Remove duplicated nodejs version in .travis.yml
lts/boron is v6
2017-10-11 00:16:11 +08:00
Peter Dave Hello 121b089d96 Add version badge in README.md 2017-10-10 21:54:13 +08:00
Sheogorath 6ed44f0864
Prevent argument breaking by spaces 2017-10-10 13:36:37 +02:00
Claudius Coenen 724a6bc26f createdAt DESC with quotation marks did not work with MySQL fixes #565 2017-10-09 14:03:33 +02:00
Sheogorath a99cac0cf0 Merge pull request #550 from SISheogorath/fix/gitlabAvatar
Fix broken profile images in GitLab

Fixes #549
2017-10-08 22:20:35 +02:00
Claudius Coenen 132d4657d7 Merge pull request #564 from geekyd/pop_button
Adds button style to "new note"
2017-10-08 15:41:28 +02:00
Sheogorath a4caac6276 Merge pull request #563 from geekyd/master
Updates default max_line_len in uglifyjs
2017-10-08 01:23:22 +02:00
geekyd c6a1b65a91 Adds color to new note button 2017-10-07 23:23:03 +05:30
geekyd 4f53afe92e Increases max_line_len in uglifyjs 2017-10-07 07:21:02 +05:30
Sheogorath 74a7216a30 Merge pull request #553 from weisslj/fix-s3-bucket-documentation
Correct documentation of S3 bucket
2017-10-07 01:20:43 +02:00
Wu Cheng-Han d96385eafd Fix to filter @import CSS syntax in style tag to prevent XSS [Security Issue] 2017-10-05 10:17:26 +08:00
Wu Cheng-Han b0b417cefc Fix unescape > symbol inside the style tags to make the CSS works 2017-10-05 09:59:57 +08:00
Wu Cheng-Han 8979f215ab Fix blockquote not parse correctly in slide mode 2017-10-05 09:59:07 +08:00
Max Wu b469592db8 Update .travis.yml 2017-09-27 22:26:03 +08:00
Wu Cheng-Han 7f52a4b38a Update yarn.lock file 2017-09-27 22:07:55 +08:00
Max Wu 6f2d1d4320 Merge pull request #538 from madebyherzblut/fix-yarn-lock
Update yarn.lock
2017-09-27 21:46:13 +08:00
Max Wu fb14e121cd Merge pull request #527 from sygi/patch-1
Typo in Polish translation
2017-09-27 21:41:06 +08:00
Max Wu 8168615e10 Merge pull request #541 from Stonesjtu/patch-1
Fix naming typo.
2017-09-27 21:40:26 +08:00
Wu Cheng-Han 2bdccd3996 Fix home and end keys behavior for windows 2017-09-27 21:27:33 +08:00
Wu Cheng-Han fe384d80bf Fix the < and > symbols are doubly escaped which affected by executing preventXSS twice 2017-09-27 18:22:49 +08:00
Wu Cheng-Han f2743ff8f8 Fix slide mode contains unclosed tags might cause XSS [Security Issue] 2017-09-27 18:21:28 +08:00
Wu Cheng-Han 9b00afb863 Fix unclosed tags might cause XSS [Security Issue] 2017-09-27 18:20:04 +08:00
Johannes Weißl 89a2389586 Correct documentation of S3 bucket
Documentation added in aaf034b on Nov 17th 2016 says the S3 bucket can
be specified with `s3.bucket`, but commit c8bcc4c (#285) on Dec 18th
2016 used `s3bucket`. Instead of fixing the code (#552) to match the
documentation this commit changes just the documentation so that
existing configurations are not broken. Also, the `s3` object is passed
as is to `AWS.S3()`, which does not know the option `bucket` (but
silently ignores it in my test).

http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#constructor-property

Following the old documentation leads to this exception:

    2017-09-23T09:42:38.079Z - error:  MissingRequiredParameter: Missing required key 'Bucket' in params
        at ParamValidator.fail (/srv/hackmd/hackmd/node_modules/aws-sdk/lib/param_validator.js:50:37)
        at ParamValidator.validateStructure (/srv/hackmd/hackmd/node_modules/aws-sdk/lib/param_validator.js:61:14)
        at ParamValidator.validateMember (/srv/hackmd/hackmd/node_modules/aws-sdk/lib/param_validator.js:88:21)
        at ParamValidator.validate (/srv/hackmd/hackmd/node_modules/aws-sdk/lib/param_validator.js:34:10)
        at Request.VALIDATE_PARAMETERS (/srv/hackmd/hackmd/node_modules/aws-sdk/lib/event_listeners.js:125:42)
        at Request.callListeners (/srv/hackmd/hackmd/node_modules/aws-sdk/lib/sequential_executor.js:105:20)
        at callNextListener (/srv/hackmd/hackmd/node_modules/aws-sdk/lib/sequential_executor.js:95:12)
        at /srv/hackmd/hackmd/node_modules/aws-sdk/lib/event_listeners.js:85:9
        at finish (/srv/hackmd/hackmd/node_modules/aws-sdk/lib/config.js:315:7)
        at /srv/hackmd/hackmd/node_modules/aws-sdk/lib/config.js:333:9
        at Credentials.get (/srv/hackmd/hackmd/node_modules/aws-sdk/lib/credentials.js:126:7)
        at getAsyncCredentials (/srv/hackmd/hackmd/node_modules/aws-sdk/lib/config.js:327:24)
        at Config.getCredentials (/srv/hackmd/hackmd/node_modules/aws-sdk/lib/config.js:347:9)
        at Request.VALIDATE_CREDENTIALS (/srv/hackmd/hackmd/node_modules/aws-sdk/lib/event_listeners.js:80:26)
        at Request.callListeners (/srv/hackmd/hackmd/node_modules/aws-sdk/lib/sequential_executor.js:101:18)
        at Request.emit (/srv/hackmd/hackmd/node_modules/aws-sdk/lib/sequential_executor.js:77:10)
2017-09-23 18:28:57 +02:00
Sheogorath 500207545f
Fix broken profile images 2017-09-22 12:40:43 +02:00
James cd5e45163f Merge pull request #1 from SISheogorath/patch-2
Update en.json
2017-09-11 19:07:36 -04:00
Sheogorath 9da6c88985 Update en.json 2017-09-11 02:21:31 +02:00
James 3fa82048c1 Update en.json 2017-09-07 12:19:02 -04:00
James 5ea2b1dbe6 Update en.json 2017-09-07 12:08:41 -04:00
Kaiyu Shi 4ae8086301 Give google the correct name. 2017-09-04 16:04:20 +08:00
Marc Deop 2c780f53df
Add support for minio 2017-08-30 18:58:34 +02:00
Christian Schuhmann 355c805db8 Update yarn.lock 2017-08-29 16:53:15 +02:00
Jakub Sygnowski 3ca1255064 (nit) typo 2017-08-10 14:50:45 +02:00
Raccoon d1d6d5810b Merge pull request #499 from bd808/no-ssh
Use git URLs in package.json
2017-07-03 10:58:23 +08:00
Bryan Davis 723c9d79b6 Use git URLs in package.json
Using the "github:..." form to declare a dependency in package.json
makes npm attempt to install the package using an ssh clone rather than
an https clone. Some deployment environments may not allow ssh access
to external servers which will prevent the clones from succeeding. Using
the "git+https://..." form will clone the same repo from GitHub without
requiring ssh connectivity.
2017-07-01 15:41:56 -06:00
Max Wu ec2813f06e Merge pull request #488 from zuphilip/patch-1
Translate "revert" to "Zurücksetzen" in German
2017-06-18 15:26:41 +08:00
Philipp Zumstein 9d6c1b956c Translate "revert" to "Zurücksetzen" in German 2017-06-16 16:55:37 +02:00
Max Wu a645f28b33 Fix slide mode might hide scrollbar on some linux 2017-06-14 12:12:28 +08:00
Max Wu 3b8f4bc1a2 Merge pull request #486 from kota-row/fix_s3_url
fix s3 us-east-1 region endpoint
2017-06-14 11:59:14 +08:00
Kotaro Yamamoto 1220bbe9f6 fix s3 us-east-1 region endpoint 2017-06-14 11:08:09 +09:00
Wu Cheng-Han c8d3951d32 Add support of Danish locale 2017-06-11 15:52:04 +08:00
Max Wu 15a346bd36 Merge pull request #481 from TheBacha/sv
minor fix for swedish translation
2017-06-11 14:52:20 +08:00
Max Wu 46f657cac7 Merge pull request #480 from TheBacha/danish
add danish translation
2017-06-11 14:50:12 +08:00
Wu Cheng-Han f715e8e5a3 Fix lodash will be ignored by webpack in pack bundle 2017-06-08 00:40:32 +08:00
Patrick Andersen 9a06546117 minor fix for swedish translation 2017-06-06 17:56:14 +02:00
Max Wu ca71028dd7 Merge pull request #476 from butlerx/updated/reveal
add more reveal features to slide demo
2017-06-06 23:52:06 +08:00
Patrick Andersen 0516a83b7d add danish translation 2017-06-06 17:48:29 +02:00
butlerx dcaf38b6ce
fix grammer errors 2017-06-05 12:16:21 +01:00
Wu Cheng-Han 20c5c78c29 Fix typo in the db config 2017-06-05 03:52:25 +08:00
Wu Cheng-Han 48f8378335 Fix speaker note separator regex should only take effect on the line start 2017-06-05 01:20:21 +08:00
Wu Cheng-Han ca95901204 Fix slide might not provide slideOptions meta 2017-06-05 01:12:40 +08:00
Max Wu 9b16703819 Merge pull request #478 from SISheogorath/feature/errorExitOnFail
Use non-zero exit codes when build fails
2017-06-04 19:06:09 +08:00
Sheogorath 8acceb28ed
Use non-zero exit codes when build fails 2017-06-03 18:22:37 +02:00
butlerx 50153c65c6
add more reveal features to slide demo 2017-06-03 15:40:59 +01:00
Wu Cheng-Han 8f4be63df4 Update yams-metadata doc for slide theme 2017-06-03 13:33:07 +08:00
Max Wu 38cf2f7535 Merge pull request #471 from butlerx/reveal/theme
add the ability to set slide theme in slide options
2017-06-03 12:51:03 +08:00
butlerx 0c827703c1
switch to __dirname 2017-06-02 11:34:35 +01:00
Raccoon 6e119603ab Merge pull request #472 from tkykm/patch-1
Read to correct tlsca file path
2017-06-01 19:20:42 +08:00
tkykm bf3512f8f6 Read to correct tlsca file path 2017-06-01 19:58:55 +09:00
butlerx c531d96f66
check if reveal theme exists 2017-06-01 10:12:40 +01:00
butlerx e5834c077f
add the ability to set slide theme in slide options 2017-05-31 23:28:43 +01:00
CrazyPython f4b87dfad0 Update en.json 2017-05-25 20:49:39 -04:00
CrazyPython fff49bc8da file -> note 2017-05-25 20:49:12 -04:00
CrazyPython 66db70a085 Update en.json 2017-05-19 12:33:49 -04:00
CrazyPython 9bd26f454b Incorporate feedback 2017-05-19 09:08:41 -04:00
CrazyPython 3c790bb3ee This is a alert area -> this is an alert area 2017-05-17 08:07:29 -04:00
CrazyPython 20a2a78e56 "Todo List" -> "Checklist" and "Marked text" -> "Highlighted text" 2017-05-16 20:53:39 -04:00
CrazyPython 8cb1a3ac2b "Collaborate with URL" sounds like a command to an English native 2017-05-16 20:51:20 -04:00
CrazyPython ed74668188 Fix grammar and use best English standards 2017-05-16 20:19:47 -04:00
Max Wu 0a6793747c fix: export to gist occurred 404 not found 2017-05-17 02:42:44 +08:00
Max Wu eacbb99575 Merge pull request #458 from hackmdio/fix-heroku-port-binding
Fix error: uncaughtException: listen EACCES 0.0.0.0:80 on heroku
2017-05-15 10:39:20 +08:00
Yukai Huang a2f4d88019 Remove redundant HMD_PORT config from app.json 2017-05-14 19:07:56 +08:00
Max Wu ea9b1557f9 Merge pull request #421 from hackmdio/BackendRefactor
Backend code refactoring - part 1
2017-05-14 17:50:25 +08:00
Max Wu c37b666915 Merge branch 'master' into BackendRefactor 2017-05-14 17:42:14 +08:00
Max Wu f85d1d8801 Merge pull request #429 from hackmdio/refactor-part-3
Refactor frontend part 3
2017-05-13 19:54:43 +08:00
Wu Cheng-Han c0f13cf8d8 Merge branch 'master' of https://github.com/jackycute/HackMD 2017-05-09 22:12:20 +08:00
Wu Cheng-Han be99350655 Fix to implement toggle of TOC in HTML template 2017-05-09 22:11:57 +08:00
Raccoon Li 0c619fee91 fix(config): ssl environment configs not parse properly 2017-05-08 20:41:38 +08:00
Raccoon Li 826ad213d6 fix(config): some environment config not parse properly 2017-05-08 20:38:59 +08:00
Wu Cheng-Han cceb5b1a26 Fix import module name typo in app.js 2017-05-08 20:35:51 +08:00
Max Wu 0ef0e70579 Rename checkURiValid.js to checkURIValid.js 2017-05-08 20:13:55 +08:00
Raccoon Li d79997808a fix(imageRouter): import missing dependency: getImageMimeType 2017-05-08 20:04:05 +08:00
BoHong Li 60ca6ed56c refactor: Rename checkURiVaild to checkURIValid to fit coding standard 2017-05-08 19:29:07 +08:00
BoHong Li 8c2b00b05a style: Fixed variable already declared 2017-05-08 19:29:07 +08:00
BoHong Li 3919d4fc0e fix(app.js): Change config.maintenance to realtime.maintenance 2017-05-08 19:29:07 +08:00
BoHong Li ecb0533605 refactor(config.js): Extract config file
* Separate different config source to each files
* Freeze config object
2017-05-08 19:29:07 +08:00
BoHong Li 4738ba7d36 fix: Add 'use strict' on app.js 2017-05-08 19:29:07 +08:00
BoHong Li aca01f064d refactor: Remove `require` extension filename 2017-05-08 19:29:06 +08:00
BoHong Li 41f34735a1 chore(eslint): Remove eslint configuration files 2017-05-08 19:29:06 +08:00
BoHong Li 34c9f07669 refactor(baseRouter.js): Adjust style fit standard 2017-05-08 19:29:06 +08:00
BoHong Li a7e3c4d535 refactor(auth.js): Remove base path 2017-05-08 19:29:06 +08:00
BoHong Li d88502e331 refactor(app.js): Move passport serialize and deserialize to auth module 2017-05-08 19:29:06 +08:00
BoHong Li 7ef17fd4e6 refactor(app.js): Extract tooBusy 2017-05-08 19:29:06 +08:00
BoHong Li 768943002c refactor(app.js): Extract upload image 2017-05-08 19:29:06 +08:00
BoHong Li d90bd6da31 fix(app.js): Fixed typo 2017-05-08 19:24:38 +08:00
BoHong Li 689bade730 refactor(app.js): Extract note action 2017-05-08 19:24:38 +08:00
BoHong Li e2ac73f5a3 refactor(app.js): Extract /me page 2017-05-08 19:24:38 +08:00
BoHong Li e3fde01e3a refactor(app.js): Remove unused modules 2017-05-08 19:24:38 +08:00
BoHong Li 706df11e23 refactor(app.js): Extract history api 2017-05-08 19:24:38 +08:00
BoHong Li c99ae8e1f8 refactor(app.js): Remove unused import modules 2017-05-08 19:24:38 +08:00
BoHong Li 69a9f7ca38 refactor(app.js, auth.js): Extract all auth method to individual modules 2017-05-08 19:24:38 +08:00
BoHong Li 766022378a refactor(app.js): Extract status pages 2017-05-08 19:24:37 +08:00
BoHong Li 66c68254b4 refactor(app.js): Extract index, 403, 404, 500 pages 2017-05-08 19:24:37 +08:00
BoHong Li 9f1f16c8e3 refactor(app.js): Extract urlencodedParser to utils module 2017-05-08 19:24:37 +08:00
BoHong Li dee77c459a refactor(app.js): Extract middleware to module
extract check URi is valid, redirect without trailing slashes
2017-05-08 19:24:37 +08:00
BoHong Li 7ba0d600f1 fix(app.js): Stream log
use logger instead of logger.stream
2017-05-08 19:24:37 +08:00
BoHong Li 036b2414f3 refactor(logger): Refactor logger.js
Use class style implement write interface
2017-05-08 19:24:37 +08:00
Max Wu 90631df2ba Merge pull request #452 from LluisArevalo/master
Image Upload to S3 - ContentType not set
2017-05-08 19:14:31 +08:00
LluisArevalo 6bf32afb0b Use single quotes 2017-05-08 11:00:45 +02:00
LluisArevalo 6e277100ca Add reference to utils library 2017-05-08 10:52:30 +02:00
LluisArevalo 03ef1bf4f0 Add Content-Type to the images uploaded to AWS S3 2017-05-08 10:22:52 +02:00
Yukai Huang 4839838d0c Manage syncscroll / currentMode in appState 2017-05-07 20:38:22 +08:00
Yukai Huang 0e9afde5fa Move syncsroll under lib 2017-05-07 20:38:22 +08:00
Yukai Huang d9221f6011 Remove CodeMirror-other-cursors dom creation
Since it’s done via hackmdio/CodeMirror#1
2017-05-07 20:38:22 +08:00
Yukai Huang 88c0c68856 Change more global var to global 2017-05-07 20:38:22 +08:00
Yukai Huang 68ccee20b3 Extract modeType 2017-05-07 20:37:27 +08:00
Yukai Huang 18a6f9063e Change some global variables to local 2017-05-07 20:37:27 +08:00
Yukai Huang 432f215a45 Fix indentation 2017-05-07 20:37:27 +08:00
Yukai Huang c6c11c54ef Expose internal editor config variable 2017-05-07 20:37:27 +08:00
Yukai Huang db06a51299 Load statusbar template by string-loader 2017-05-07 20:37:26 +08:00
Max Wu 5343a61ae9 Merge pull request #450 from hackmdio/heroku-recovery
Fix heroku deployment
2017-05-07 20:14:05 +08:00
Yukai Huang be7335e92a Remove postdeploy migration 2017-05-07 19:07:03 +08:00
Yukai Huang 1af3727fef Remove npm install in heroku build
since heroku detects yarn.lock automatically
2017-05-07 18:54:18 +08:00
Wu Cheng-Han e32dd547b4 Update to support code block syntax highlighting of gherkin 2017-05-05 18:03:23 +08:00
Max Wu 38a7c373e7 Fix fb message link might not available for public 2017-04-24 12:52:09 +08:00
Max Wu 57b670d17a Merge pull request #428 from PeterDaveHello/travis-ci-optimize
Move to Ubuntu Trusty on Travis CI and remove apt add-on
2017-04-19 19:47:40 +08:00
Peter Dave Hello f1f0cb7aef Move to Ubuntu Trusty on Travis CI and remove apt add-on
Two reasons here:

1) Ubuntu Precise is reaching EOL, though Travis CI may take care of it.
we still can move to Trusty earlier as I didn't see any dependency of
Precise here.

2) g++4.8 is built-in in Travis CI's Ubuntu Trusty environment, which
means we don't need to spend time on adding ppa repository, apt update
and apt install, could save time on the CI.
2017-04-18 13:17:43 +08:00
Max Wu 450159a462 Merge pull request #427 from PeterDaveHello/fix-indent
Fix indent in views, shouldn't mix tabs with spaces
2017-04-18 10:41:58 +08:00
Max Wu 2a5a518e88 Merge pull request #426 from PeterDaveHello/cdnjs-integration
Use abcjs on cdnjs
2017-04-18 10:40:51 +08:00
Max Wu 1241b8bd44 Merge pull request #425 from PeterDaveHello/fix-file-permission
Remove executable permission from static files
2017-04-18 10:32:23 +08:00
Peter Dave Hello 5f3fe5c62c Fix indent in views, shouldn't mix tabs with spaces 2017-04-18 05:24:04 +08:00
Peter Dave Hello 08c0a0392c Use abcjs on cdnjs, cc @jackycute 2017-04-18 05:19:19 +08:00
Peter Dave Hello 7e3e0edb17 Remove executable permission from static files 2017-04-18 05:01:23 +08:00
Wu Cheng-Han 48df250491 Fix link regex should filter protocol with case insensitive flag [Security Issue] 2017-04-11 22:25:14 +08:00
Yukai Huang a39870f224 Enable source map in development build 2017-04-11 16:40:13 +08:00
Max Wu 5ecea7e118 Merge pull request #417 from hackmdio/refactor
Refactor editor cont.
2017-04-10 11:41:33 +08:00
Max Wu 3ef22fd303 Merge pull request #416 from iandees/patch-1
Clarify permission language
2017-04-05 23:13:14 +08:00
Ian Dees 3aaf1bbe24 Update body.ejs 2017-04-05 11:07:18 -04:00
Ian Dees 138170704a Clarify permission language
See https://github.com/hackmdio/hackmd/issues/415
2017-04-05 10:16:15 -04:00
Yukai Huang a4385ec19d Update editorconfig 2017-03-31 20:58:58 +08:00
BoHong Li a1fab034b4 build: Update yarn.lock 2017-03-29 19:05:29 +08:00
Wu Cheng-Han 1d51fdaa7c chore(build): Upgrade uws to 0.14.1, other npm version have been removed 2017-03-29 12:43:03 +08:00
Wu Cheng-Han 1c6f5d272f style: Fix missing newline in variables 2017-03-29 12:41:23 +08:00
Yukai Huang a938cac42a Fix indentations 2017-03-28 20:38:31 +08:00
Yukai Huang b711ecfadb Drop global variable ui exposing 2017-03-28 19:30:06 +08:00
Yukai Huang ba1bef015f Update to es6 module import style 2017-03-28 18:31:36 +08:00
Yukai Huang 7637a6a8a6 Update cm instance in changes event argument 2017-03-28 17:32:42 +08:00
Yukai Huang f5b95c5d36 Move updateStatusBar method into editor class 2017-03-28 17:16:32 +08:00
Yukai Huang df743ab902 Fix listener “this” context 2017-03-28 17:11:20 +08:00
Raccoon 0b4dac74ed Merge pull request #406 from hackmdio/feature/add_missing_migration
fix: Add missing migration
2017-03-28 16:48:30 +08:00
BoHong Li e46874d04a fix: Other dialect duplicated add index problem
Detect is using SQLite to add index
2017-03-28 15:28:33 +08:00
Yukai Huang 46ed658d8b Promisify getStatusBarTemplate method 2017-03-28 15:24:52 +08:00
BoHong Li e26bb0503f fix: Support SQlite
Move 'unique' constraint to another statement (SQLite don't support set unique when addColumn)
2017-03-28 15:16:09 +08:00
Yukai Huang af5ef52f4b Add cm instance to cursorActivity argument 2017-03-28 12:15:56 +08:00
Yukai Huang 579dda9515 Update focus argument with cm instance 2017-03-28 12:11:05 +08:00
Yukai Huang d7c068cbfd Rewrite cursorActivity with multi listener style
- adjust function order to prevent standard lint failure
2017-03-28 12:10:35 +08:00
Yukai Huang b86ecb1342 Extract selection update from updateStatusbar 2017-03-28 11:57:44 +08:00
Yukai Huang 81666a726c Impl multiple codemirror event listener 2017-03-28 11:18:36 +08:00
Yukai Huang fff7ebd1b5 Change minor TODO to FIXME 2017-03-28 11:17:30 +08:00
BoHong Li 6f14822413 fix: Add missing migration 2017-03-27 19:23:00 +08:00
Wu Cheng-Han b2985085d0 Update to change makefile syntax highlighting to Prism 2017-03-26 23:09:13 +08:00
Wu Cheng-Han a3cdc5ba80 Update to add abc in support charts of textcomplete 2017-03-26 20:46:05 +08:00
Wu Cheng-Han 961d3fab1c Fix code style 2017-03-26 20:45:23 +08:00
Wu Cheng-Han 61dc6dbc15 Add support of abcjs 2017-03-26 20:39:07 +08:00
Max Wu aaf4948c55 Merge pull request #404 from wonderchang/patch-1
Add defaultpermission protected example value
2017-03-25 20:07:11 +08:00
Wonder Chang af58a71238 Add defaultpermission protected example value 2017-03-25 17:00:43 +08:00
BoHong Li 66fc817ad4 fix: Fixed sequelize-cli db:migration cannot stop when occur error
Up and Down method must return a Promise.

breaking changes: docker-hackmd cannot initialize, because db:migration will fail
2017-03-24 11:26:04 +08:00
BoHong Li cdd8a72d04 ci: Use yarn as default dependency management system
Use yarn in TravisCI
2017-03-24 07:22:02 +08:00
BoHong Li d98993f76e build: Support yarn dependency management system
1. Add yarn.lock to support yarn
2017-03-24 07:18:42 +08:00
Wu Cheng-Han 3156c38598 Fix text complete of extra tags for list not triggered properly 2017-03-23 20:49:31 +08:00
Wu Cheng-Han 890f7089bf Fix google drive file picker not initialize properly 2017-03-23 20:17:50 +08:00
Wu Cheng-Han dde6e622a4 Fix front-end constants generation not getting config properly 2017-03-23 20:00:48 +08:00
Wu Cheng-Han 7e3b74d0da Mark as 0.5.1 2017-03-23 00:22:44 +08:00
Wu Cheng-Han 011d043b2a Update to indicate version in status API header 2017-03-22 23:44:09 +08:00
Wu Cheng-Han e629800457 Fix XSS vulnerability in link regex [Security Issue] 2017-03-22 18:26:35 +08:00
Wu Cheng-Han 0f3b028ed6 Fix render.js code styles 2017-03-22 18:26:30 +08:00
Wu Cheng-Han cac618eca8 Fix front-end index.js code styles 2017-03-22 17:48:26 +08:00
Wu Cheng-Han 802ed406e6 Fix todo list item class might add in wrong element 2017-03-22 15:42:38 +08:00
Wu Cheng-Han 9ff3649025 Fix unnecessary global calling of ownerui 2017-03-22 15:42:11 +08:00
Wu Cheng-Han e751684aa3 Update to print info on exit term signals handled 2017-03-22 15:31:39 +08:00
Wu Cheng-Han 0bcd83576f Update to handle SIGQUIT 2017-03-22 15:26:35 +08:00
Wu Cheng-Han b17c2404b1 Fix duplicated loading of reveal markdown plugin 2017-03-21 20:44:12 +08:00
Wu Cheng-Han 10a7a9b37e Update to use CDN css for emojify.js when applicable 2017-03-21 00:27:58 +08:00
Wu Cheng-Han 7989b89591 Add support of Catalan locale 2017-03-20 14:52:25 +08:00
Wu Cheng-Han afc4f269bc Update to make removeDOMEvents only process once in slide mode 2017-03-20 11:28:50 +08:00
Wu Cheng-Han 19a64f6b06 Fix typo and possible wrong value on provider is false on generating front-end constants 2017-03-20 01:54:44 +08:00
Wu Cheng-Han 448b006194 Update to generate front-end constants on server startup
To avoid extra webpacking on changing configs and follow the 12 factor app
2017-03-20 01:39:09 +08:00
Wu Cheng-Han b07eeed0c5 Merge branch 'master' of https://github.com/jackycute/HackMD 2017-03-15 22:13:05 +08:00
Wu Cheng-Han 4a1d08c653 Fix strip null byte in model should cast to string to use replace function 2017-03-15 22:12:24 +08:00
Max Wu 16d80edc65 Fix badges and links in README.md 2017-03-14 23:30:35 +08:00
Max Wu f6bd238b0f Merge pull request #387 from hackmdio/cm-refactor
Extract CodeMirror instance
2017-03-14 23:11:56 +08:00
Wu Cheng-Han f55a4b8497 Update to fix pagination error in list.js over v1.5.0 2017-03-14 23:08:15 +08:00
Wu Cheng-Han 506a381eca Add config option for gitlab api scope and auto adapt gitlab snippet feature on it 2017-03-14 18:04:23 +08:00
Wu Cheng-Han baf13072c1 Fix update doc from filesystem cause redundant authorship stringify 2017-03-14 17:11:52 +08:00
Wu Cheng-Han 2fa51fb4ba Fix export html to replace fallen cdn tortue.me to cdnjs 2017-03-14 16:37:38 +08:00
Wu Cheng-Han 0fc8e7c30e Merge branch 'master' of https://github.com/jackycute/HackMD 2017-03-14 16:28:30 +08:00
Wu Cheng-Han f491cdabc1 Fix rendering might result XSS attribute on self closing tag [Security Issue] 2017-03-14 16:27:55 +08:00
BoHong Li 5870d988b5 Use strict mode in all backend files
add ‘use strict’ in all backend file
2017-03-14 13:02:43 +08:00
Yukai Huang 24f1413654 Add inlineAttachment to global 2017-03-13 22:00:29 +08:00
Yukai Huang cc30d370f7 Fix variable exporting error 2017-03-13 22:00:20 +08:00
Yukai Huang e97b609d91 Update new editorconfig indent favor 2017-03-13 21:42:33 +08:00
Yukai Huang b4424419c0 Add standarjs globals 2017-03-13 21:42:09 +08:00
Yukai Huang 93e41f3a40 Merge branch 'master' into cm-refactor 2017-03-13 21:32:50 +08:00
Wu Cheng-Han edb1b4aa0a Merge branch 'master' of https://github.com/jackycute/HackMD 2017-03-13 18:56:32 +08:00
Wu Cheng-Han c818cde782 Update facebook message link in features doc 2017-03-13 18:55:44 +08:00
BoHong Li 8246ac3850 Add JavaScript Standard Style badge in README
add badge to let people know that code is using the standard style
2017-03-13 18:42:22 +08:00
BoHong Li 6cf06837f8 Remove eslint
1. Remove eslint , bacause we use JavaScript Standard Style.
2. Add lts/boron version to travis CI, web use it in docker version

Signed-off-by: BoHong Li <a60814billy@gmail.com>
2017-03-13 02:23:58 +08:00
BoHong Li befa89be8b Merge branch 'use_javascript_standard_style'
Introduce JavaScript Standard Style

Signed-off-by: BoHong Li <a60814billy@gmail.com>
2017-03-13 02:09:52 +08:00
Yukai Huang 747da6772d Fix webpack copy relative path in #384 2017-03-12 21:10:35 +08:00
Max Wu 4153403a8b Merge pull request #384 from hackmdio/webpack-fixes
Webpack fixes
2017-03-12 17:40:42 +08:00
Yukai Huang 8241d945dc Do not log assets info in webpack build 2017-03-12 16:53:04 +08:00
Max Wu 8dd91fbe66 Merge pull request #382 from Himura2la/patch-1
Fixed style in promo text
2017-03-11 15:07:07 +08:00
Himura Kazuto ef8c4ecdc6 Fixed style in promo text 2017-03-10 19:17:41 +03:00
Yukai Huang 9b513f619f Use JavaScript standard style 2017-03-09 15:39:42 +08:00
BoHong Li 5bc642d02e Use JavaScript Standard Style (part 2)
Fixed all fail on frontend code.
2017-03-09 02:41:05 +08:00
Yukai Huang 6556c284e5 Extract editor related code
- in public/js/lib/editor/index.js
2017-03-08 21:43:32 +08:00
BoHong Li 4889e9732d Use JavaScript Standard Style
Introduce JavaScript Standard Style as project style rule,
and fixed all fail on backend code.
2017-03-08 18:45:51 +08:00
Yukai Huang 121d84863a Extract UI jquery node 2017-03-07 21:59:18 +08:00
BoHong Li 8f1c97f4a4 Fixed Syntax Error 2017-03-04 17:06:11 +08:00
Raccoon bbde79c7d7 Merge pull request #325 from SISheogorath/feature/addSecrets
Add basics for secret management by Docker 1.13
2017-03-03 09:27:57 +08:00
Raccoon 48592d692c Merge branch 'master' into feature/addSecrets 2017-03-03 09:22:35 +08:00
Sheogorath a8b99638b2 Add basics for secret management by Docker 1.13
See https://docs.docker.com/engine/swarm/secrets/
2017-02-07 02:46:23 +01:00
261 changed files with 33179 additions and 13890 deletions

View File

@ -1,6 +1,11 @@
{
"presets": [
"es2015"
["env", {
"targets": {
"node": "8",
"uglify": true
}
}]
],
"plugins": [
"transform-runtime"

View File

@ -1,11 +1,15 @@
root = true
# Tab indentation
[*]
indent_style = space
indent_size = 2
trim_trailing_whitespace = true
insert_final_newline = true
[{*.html,*.ejs}]
indent_style = space
indent_size = 4
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false
@ -13,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

View File

@ -1 +1,3 @@
*.min.js
lib/ot
public/vendor
public/build

268
.eslintrc
View File

@ -1,268 +0,0 @@
{
"env": {
"browser": true,
"es6": true,
"node": true
},
"extends": "eslint:recommended",
"parserOptions": {
"sourceType": "module"
},
"rules": {
"accessor-pairs": "error",
"array-bracket-spacing": [
"error",
"never"
],
"array-callback-return": "error",
"arrow-body-style": "error",
"arrow-spacing": "error",
"block-scoped-var": "off",
"block-spacing": "error",
"brace-style": [
"error",
"1tbs"
],
"callback-return": "off",
"camelcase": "error",
"class-methods-use-this": "error",
"comma-dangle": "error",
"comma-spacing": [
"error", {
"after": true,
"before": false
}
],
"comma-style": [
"error",
"last"
],
"complexity": "error",
"computed-property-spacing": [
"error",
"never"
],
"consistent-return": "off",
"consistent-this": "error",
"curly": "off",
"default-case": "error",
"dot-location": [
"error",
"property"
],
"dot-notation": [
"error", {
"allowKeywords": true
}
],
"eol-last": "error",
"eqeqeq": "off",
"func-call-spacing": "error",
"func-names": [
"error",
"never"
],
"func-style": [
"error",
"declaration"
],
"generator-star-spacing": "error",
"global-require": "off",
"guard-for-in": "error",
"handle-callback-err": "error",
"id-blacklist": "error",
"id-length": "off",
"id-match": "error",
"indent": 2,
"init-declarations": "off",
"jsx-quotes": "error",
"key-spacing": "error",
"keyword-spacing": [
"error", {
"after": true,
"before": true
}
],
"line-comment-position": "off",
"linebreak-style": [
"error",
"unix"
],
"lines-around-comment": "error",
"lines-around-directive": "error",
"max-depth": "error",
"max-len": "off",
"max-lines": "off",
"max-nested-callbacks": "error",
"max-params": "error",
"max-statements": "error",
"max-statements-per-line": "error",
"multiline-ternary": [
"error",
"never"
],
"new-cap": "error",
"new-parens": "error",
"newline-after-var": "off",
"newline-before-return": "off",
"newline-per-chained-call": "off",
"no-alert": "error",
"no-array-constructor": "error",
"no-bitwise": "error",
"no-caller": "error",
"no-catch-shadow": "off",
"no-confusing-arrow": "error",
"no-continue": "error",
"no-div-regex": "error",
"no-duplicate-imports": "error",
"no-else-return": "error",
"no-empty-function": "error",
"no-eq-null": "error",
"no-eval": "error",
"no-extend-native": "error",
"no-extra-bind": "error",
"no-extra-label": "error",
"no-extra-parens": "warn",
"no-floating-decimal": "error",
"no-global-assign": "error",
"no-implicit-coercion": "error",
"no-implicit-globals": "error",
"no-implied-eval": "error",
"no-inline-comments": "off",
"no-inner-declarations": [
"error",
"functions"
],
"no-invalid-this": "error",
"no-iterator": "error",
"no-label-var": "error",
"no-labels": "error",
"no-lone-blocks": "error",
"no-lonely-if": "error",
"no-loop-func": "error",
"no-magic-numbers": "off",
"no-mixed-operators": "error",
"no-mixed-requires": "error",
"no-multi-spaces": "error",
"no-multi-str": "error",
"no-multiple-empty-lines": "error",
"no-negated-condition": "off",
"no-nested-ternary": "error",
"no-new": "error",
"no-new-func": "error",
"no-new-object": "error",
"no-new-require": "error",
"no-new-wrappers": "error",
"no-octal-escape": "error",
"no-param-reassign": [
"error", {
"props": false
}
],
"no-path-concat": "off",
"no-plusplus": [
"error", {
"allowForLoopAfterthoughts": true
}
],
"no-process-env": "error",
"no-process-exit": "off",
"no-proto": "error",
"no-prototype-builtins": "error",
"no-restricted-globals": "error",
"no-restricted-imports": "error",
"no-restricted-modules": "error",
"no-restricted-properties": "error",
"no-restricted-syntax": "error",
"no-return-assign": "error",
"no-script-url": "error",
"no-self-compare": "error",
"no-sequences": "error",
"no-shadow": "off",
"no-shadow-restricted-names": "error",
"no-spaced-func": "error",
"no-sync": "off",
"no-tabs": "error",
"no-template-curly-in-string": "error",
"no-ternary": "off",
"no-throw-literal": "error",
"no-trailing-spaces": "error",
"no-undef-init": "error",
"no-undefined": "error",
"no-underscore-dangle": "error",
"no-unmodified-loop-condition": "error",
"no-unneeded-ternary": "error",
"no-unsafe-negation": "error",
"no-unused-expressions": "error",
"no-use-before-define": "warn",
"no-useless-call": "error",
"no-useless-computed-key": "error",
"no-useless-concat": "error",
"no-useless-constructor": "error",
"no-useless-escape": "error",
"no-useless-rename": "error",
"no-var": "off",
"no-void": "error",
"no-warning-comments": "error",
"no-whitespace-before-property": "error",
"no-with": "error",
"object-curly-newline": "off",
"object-curly-spacing": [
"error",
"always"
],
"object-property-newline": "error",
"object-shorthand": "off",
"one-var": "off",
"one-var-declaration-per-line": [
"error",
"initializations"
],
"operator-assignment": "error",
"operator-linebreak": "error",
"padded-blocks": "off",
"prefer-arrow-callback": "off",
"prefer-const": "error",
"prefer-numeric-literals": "error",
"prefer-reflect": "error",
"prefer-rest-params": "error",
"prefer-spread": "error",
"prefer-template": "off",
"quote-props": "off",
"quotes": "off",
"radix": "error",
"require-jsdoc": "off",
"rest-spread-spacing": "error",
"semi": "off",
"semi-spacing": [
"error", {
"after": true,
"before": false
}
],
"sort-imports": "error",
"sort-keys": "off",
"sort-vars": "error",
"space-before-blocks": "error",
"space-before-function-paren": "off",
"space-in-parens": [
"error",
"never"
],
"space-infix-ops": "error",
"space-unary-ops": "error",
"spaced-comment": "off",
"strict": "error",
"symbol-description": "error",
"template-curly-spacing": "error",
"unicode-bom": [
"error",
"never"
],
"valid-jsdoc": "error",
"vars-on-top": "off",
"wrap-regex": "error",
"yield-star-spacing": "error",
"yoda": "off"
}
}

22
.eslintrc.js Normal file
View File

@ -0,0 +1,22 @@
module.exports = {
"root": true,
"extends": "standard",
"env": {
"node": true
},
"rules": {
// at some point all of these should return to their default "error" state
// but right now, this is not a good choice, because too many places are
// wrong.
"import/first": ["warn"],
"indent": ["warn"],
"no-console": ["warn"],
"no-multiple-empty-lines": ["warn"],
"no-multi-spaces": ["warn"],
"object-curly-spacing": ["warn"],
"one-var": ["warn"],
"quotes": ["warn"],
"semi": ["warn"],
"space-infix-ops": ["warn"]
}
};

2
.gitignore vendored
View File

@ -1,4 +1,5 @@
node_modules
package-lock.json
composer.phar
composer.lock
.env.*.php
@ -7,7 +8,6 @@ composer.lock
.idea/
Thumbs.db
npm-debug.log
hackmd_io
newrelic_agent.log
logs/
tmp/

14
.mailmap Normal file
View File

@ -0,0 +1,14 @@
Max Wu <jackymaxj@gmail.com> Wu Cheng-Han <jacky_cute0808@hotmail.com>
Max Wu <jackymaxj@gmail.com> Cheng-Han, Wu <jackymaxj@gmail.com>
Max Wu <jackymaxj@gmail.com> jackycute <jackymaxj@gmail.com>
Max Wu <jackymaxj@gmail.com> Wu, Cheng-Han <jackymaxj@gmail.com>
Max Wu <jackymaxj@gmail.com> jackycute <jacky_cute0808@hotmail.com>
Sheogorath <sheogorath@shivering-isles.com> Christoph (Sheogorath) Kern <sheogorath@shivering-isles.com>
Raccoon <raccoon@hackmd.io> Raccoon Li <a60814billy@gmail.com>
Raccoon <raccoon@hackmd.io> Raccoon <a60814billy@gmail.com>
Peter Dave Hello <hsu@peterdavehello.org> Peter Dave Hello <PeterDaveHello@users.noreply.github.com>
Claudius Coenen <github@amenthes.de> Claudius Coenen <opensource@amenthes.de>

View File

@ -1,13 +1,40 @@
language: node_js
node_js:
- 6
- 7
- stable
env:
- CXX=g++-4.8
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-4.8
dist: xenial
cache: yarn
jobs:
include:
- stage: Static Tests
name: eslint
node_js:
- 10
script:
- yarn run eslint
- name: ShellCheck
script:
- shellcheck bin/heroku bin/setup
language: generic
- name: json-lint
addons:
apt:
packages:
- jq
script:
- yarn run jsonlint
language: generic
- stage: Dynamic Tests
name: Node.js 8
node_js:
- 8
script:
- yarn run mocha-suite
- name: Node.js 10
node_js:
- 10
script:
- yarn run mocha-suite
- name: Node.js 12
node_js:
- 12
script:
- yarn run mocha-suite

104
AUTHORS
View File

@ -1,35 +1,69 @@
List of HackMD contributors.
bananaapple
Bartlomiej Szala
Colin Maudry
Dmytro Kytsmen
Fabien Meghazi
Florian Rhiem
Ikumi Shimizu
ivanorsolic
Jason Croft
Jannik Lorenz
James Stephenson
Jordan Matelsky
Kenji Doi
Lars Kajes
Lapinot
Laura Kyle
Marcelo Alencar
Martijnpold
Massimo Ghinassi
Max Wu
Ömer Erdinç Yağmurlu
p0v1n0m
Pablo Guerrero
paraschadha2052
Peter Dave Hello
Qubo
Sergio Valverde
Tom Wyckhuys
Yukai Huang
Zacharias Traianos
Zankio
Xavier
葉家郡
alecdwm <alec@owls.io>
bananaappletw <bananaappletw@gmail.com>
Bartlomiej Szala <fenix440@gmail.com>
BoHong Li <a60814billy@gmail.com>
Bryan Davis <bd808@wikimedia.org>
butlerx <butlerx@notthe.cloud>
Cheng-Han, Wu <jackymaxj@gmail.com>
Christian Schuhmann <madebyherzblut@users.noreply.github.com>
Colin Maudry <colin@maudry.com>
Dmytro Kytsmen <dmitrokytsmen@gmail.com>
Fabien Meghazi <agr@amigrave.com>
Florian Rhiem <florian.rhiem@gmail.com>
geekyd <singhsince94@gmail.com>
GhiMax <ghina8@gmail.com>
greenkeeperio-bot <support@greenkeeper.io>
Himura Kazuto <Himura2la@users.noreply.github.com>
Ho33e5 <ho33e5@gmail.com>
Ian Dees <ian.dees@gmail.com>
Ikumi Shimizu <193s@users.noreply.github.com>
ivanorsolic <ivanorsolic@users.noreply.github.com>
jackycute <jacky_cute0808@hotmail.com>
jackycute <jackymaxj@gmail.com>
Jakub Sygnowski <sygnowski@gmail.com>
James Stephenson <c4p7.fl1n7@gmail.com>
Jan Kunzmann <jan-github@phobia.de>
Jannik Lorenz <dev@janniklorenz.de>
Jason Croft <jcroft@velocity.org>
Johannes Weißl <jargon@molb.org>
Jordan Matelsky <j6k4m8@gmail.com>
Jun SAKATA <jun.bj141400@gmail.com>
Kaiyu Shi <skyisno.1@gmail.com>
knjcode <knjcode@gmail.com>
Kotaro Yamamoto <kota.crk@gmail.com>
Lars Karlsson <lars@kajes.se>
Laura Kyle <laura.kyle91@gmail.com>
LluisArevalo <thorin119@gmail.com>
Marcelo Alencar <marceloalves@ufpa.br>
Martijnpold <martijntje7@gmail.com>
Max Wu <jackymaxj@gmail.com>
neopostmodern <clemens@neopostmodern.com>
NV <nvsofts@gmail.com>
Ömer Erdinç Yağmurlu <omeryagmurlu@gmail.com>
p0v1n0m <p0v1n0m@gmail.com>
Pablo Guerrero <pablo.guerrero@gmail.com>
Pablo Guerrero <pablo.guerrero@sap.com>
Paras <paraschadha2052@gmail.com>
Patrick Andersen <patrick@bacha.dk>
Peter Dave Hello <hsu@peterdavehello.org>
Peter Dave Hello <PeterDaveHello@users.noreply.github.com>
Philipp Zumstein <zuphilip@users.noreply.github.com>
Raccoon Li <a60814billy@gmail.com>
robert <ahmerov.rt@molodost.bz>
Sergio Valverde <svg153@users.noreply.github.com>
Sheogorath <sheogorath@shivering-isles.com>
Simon Joda Stößer <SimJoSt@users.noreply.github.com>
S.Noda <noda@fenrir.co.jp>
Stratos Gerakakis <stratosgear@gmail.com>
The Gitter Badger <badger@gitter.im>
tkqubo <tk.qubo@gmail.com>
tkykm <tkykm@users.noreply.github.com>
Tom Wyckhuys <tomwyckhuys@gmail.com>
Wonder Chang <iwonder.tw@gmail.com>
Wu Cheng-Han <jacky_cute0808@hotmail.com>
Xavier Marques <xaviermarques4f@gmail.com>
xnum <s000032001@gmail.com>
Yukai Huang <yukaihuangtw@gmail.com>
zachariast <zachariastraianos@gmail.com>
Zankio <xxoojoeooxx1@gmail.com>
蒼時弦也 <elct9620@frost.tw>

7
CHANGELOG.md Normal file
View 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
View 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/)

View File

@ -1,54 +1,37 @@
# Contributing
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.
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 any install or build dependencies are removed before the end of the layer when doing a
1. Ensure you signed all your commits with Developer Certificate of Origin (DCO).
2. Ensure any install or build dependencies are removed before the end of the layer when doing a
build.
2. Update the README.md with details of changes to the interface, this includes new environment
3. Update the README.md with details of changes to the interface, this includes new environment
variables, exposed ports, useful file locations and container parameters.
3. Increase the version numbers in any examples files and the README.md to the new version that this
4. Increase the version numbers in any examples files and the README.md to the new version that this
Pull Request would represent. The versioning scheme we use is [SemVer](http://semver.org/).
4. You may merge the Pull Request in once you have the sign-off of two other developers, or if you
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
## Sign your work
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 use the Developer Certificate of Origin (DCO) as a additional safeguard
for the CodiMD project. This is a well established and widely used
mechanism to assure contributors have confirmed their right to license
their contribution under the project's license.
Please read [docs/legal/developer-certificate-of-origin.txt][dcofile].
If you can certify it, then just add a line to every git commit message:
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.
````
Signed-off-by: Random J Developer <random@developer.example.org>
````
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/)
Use your real name (sorry, no pseudonyms or anonymous contributions).
If you set your `user.name` and `user.email` git configs, you can sign your
commit automatically with `git commit -s`. You can also use git [aliases](https://git-scm.com/book/tr/v2/Git-Basics-Git-Aliases)
like `git config --global alias.ci 'commit -s'`. Now you can commit with
`git ci` and the commit will be signed.

680
LICENSE
View File

@ -1,22 +1,668 @@
The MIT License (MIT)
GNU AFFERO GENERAL PUBLIC LICENSE
Version 3, 19 November 2007
Copyright (c) 2017 Max Wu <jackymaxj@gmail.com> and others
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
Preamble
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The GNU Affero General Public License is a free, copyleft license for
software and other kinds of works, specifically designed to ensure
cooperation with the community in the case of network server software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
our General Public Licenses are intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
Developers that use our General Public Licenses protect your rights
with two steps: (1) assert copyright on the software, and (2) offer
you this License which gives you legal permission to copy, distribute
and/or modify the software.
A secondary benefit of defending all users' freedom is that
improvements made in alternate versions of the program, if they
receive widespread use, become available for other developers to
incorporate. Many developers of free software are heartened and
encouraged by the resulting cooperation. However, in the case of
software used on network servers, this result may fail to come about.
The GNU General Public License permits making a modified version and
letting the public access it on a server without ever releasing its
source code to the public.
The GNU Affero General Public License is designed specifically to
ensure that, in such cases, the modified source code becomes available
to the community. It requires the operator of a network server to
provide the source code of the modified version running there to the
users of that server. Therefore, public use of a modified version, on
a publicly accessible server, gives the public access to the source
code of the modified version.
An older license, called the Affero General Public License and
published by Affero, was designed to accomplish similar goals. This is
a different license, not a version of the Affero GPL, but Affero has
released a new version of the Affero GPL which permits relicensing under
this license.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU Affero General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Remote Network Interaction; Use with the GNU General Public License.
Notwithstanding any other provision of this License, if you modify the
Program, your modified version must prominently offer all users
interacting with it remotely through a computer network (if your version
supports such interaction) an opportunity to receive the Corresponding
Source of your version by providing access to the Corresponding Source
from a network server at no charge, through some standard or customary
means of facilitating copying of software. This Corresponding Source
shall include the Corresponding Source for any work covered by version 3
of the GNU General Public License that is incorporated pursuant to the
following paragraph.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the work with which it is combined will remain governed by version
3 of the GNU General Public License.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU Affero General Public License from time to time. Such new versions
will be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU Affero General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU Affero General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU Affero General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
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.
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
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If your software can interact with users remotely through a computer
network, you should also make sure that it provides a way for users to
get its source. For example, if your program is a web application, its
interface could display a "Source" link that leads users to an archive
of the code. There are many ways you could offer source, and different
solutions will be better for different programs; see section 13 for the
specific requirements.
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU AGPL, see
<http://www.gnu.org/licenses/>.

284
README.md
View File

@ -1,230 +1,104 @@
HackMD
CodiMD
===
[![Join the chat at https://gitter.im/hackmdio/hackmd][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]
[![Mastodon][social-mastodon-image]][social-mastodon]
CodiMD lets you create real-time collaborative markdown notes. You can test-drive
it by visiting our [CodiMD demo server][codimd-demo].
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).
[![CodiMD 1.3.2 with its feature demonstration page open](docs/images/CodiMD-1.3.2-features.png)][codimd-demo-features]
HackMD lets you create realtime collaborative markdown notes on all platforms.
Inspired by Hackpad, with more focus on speed and flexibility.
Still in the early stage, feel free to fork or contribute to HackMD.
## Community and Contributions
Thanks for using! :smile:
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.
[docker-hackmd](https://github.com/hackmdio/docker-hackmd)
---
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.
Before you go too far, here is the great docker repo for HackMD.
With docker, you can deploy a server in minutes without any downtime.
Heroku Deployment
---
## Installation / Upgrading
You can quickly setup a sample heroku hackmd application by clicking the button below.
You can run CodiMD in a number of ways, and we created setup instructions for
all of these:
[![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy)
* [Docker](docs/setup/docker.md)
* [Kubernetes](docs/setup/kubernetes.md)
* [Cloudron](docs/setup/cloudron.md)
* [LinuxServer.io (multi-arch docker)](docs/setup/docker-linuxserver.md)
* [Heroku](docs/setup/heroku.md)
* [Manual setup](docs/setup/manual-setup.md)
[migration-to-0.5.0](https://github.com/hackmdio/migration-to-0.5.0)
---
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.
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)
---
## Configuration
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.
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.
Browsers Requirement
---
CodiMD can integrate with
- Chrome >= 47, Chrome for Android >= 47
- Safari >= 9, iOS Safari >= 8.4
- Firefox >= 44
- IE >= 9, Edge >= 12
- Opera >= 34, Opera Mini not supported
* 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
- ![Firefox](http://browserbadge.com/firefox/44/18px) Firefox >= 44
- ![IE](http://browserbadge.com/ie/9/18px) IE >= 9, Edge >= 12
- ![Opera](http://browserbadge.com/opera/34/18px) Opera >= 34, Opera Mini not supported
- Android Browser >= 4.4
Prerequisite
---
- Node.js 6.x or up (test up to 7.5.0)
- 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))
## Related Tools
Get started
---
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.
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. Run the server as you like (node, forever, pm2)
Upgrade guide
---
# License
If you are upgrading HackMD from an older version, follow these steps:
Licensed under AGPLv3. For our list of contributors, see [AUTHORS](AUTHORS).
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/hackmd`
6. Run `node_modules/.bin/sequelize db:migrate`, this step will migrate your db to the latest schema
7. Start your whole new server!
Structure
---
```text
hackmd/
├── tmp/ --- temporary files
├── docs/ --- document files
├── lib/ --- server libraries
└── public/ --- client files
├── css/ --- css styles
├── js/ --- js scripts
├── vendor/ --- vendor includes
└── views/ --- view templates
```
Configuration files
---
There are some configs 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 |
| HMD_DOMAIN | `hackmd.io` | domain name |
| HMD_URL_PATH | `hackmd` | sub url path, like `www.example.com/<URL_PATH>` |
| HMD_PORT | `80` | web app port |
| HMD_ALLOW_ORIGIN | `localhost, hackmd.io` | domain name whitelist (use comma to separate) |
| HMD_PROTOCOL_USESSL | `true` or `false` | set to use ssl protocol for resources path (only applied when domain is set) |
| HMD_URL_ADDPORT | `true` or `false` | set to add port on callback url (port 80 or 443 won't applied) (only applied when domain is set) |
| HMD_USECDN | `true` or `false` | set to use CDN resources or not (default is `true`) |
| HMD_ALLOW_ANONYMOUS | `true` or `false` | set to allow anonymous usage (default is `true`) |
| HMD_ALLOW_FREEURL | `true` or `false` | set to allow new note by accessing not exist note url |
| HMD_DEFAULT_PERMISSION | `freely`, `editable`, `limited`, `locked` or `private` | set notes default permission (only applied on signed users) |
| HMD_DB_URL | `mysql://localhost:3306/database` | set the db url |
| HMD_FACEBOOK_CLIENTID | no example | Facebook API client id |
| HMD_FACEBOOK_CLIENTSECRET | no example | Facebook API client secret |
| HMD_TWITTER_CONSUMERKEY | no example | Twitter API consumer key |
| HMD_TWITTER_CONSUMERSECRET | no example | Twitter API consumer secret |
| HMD_GITHUB_CLIENTID | no example | GitHub API client id |
| HMD_GITHUB_CLIENTSECRET | no example | GitHub API client secret |
| HMD_GITLAB_BASEURL | no example | GitLab authentication endpoint, set to use other endpoint than GitLab.com (optional) |
| HMD_GITLAB_CLIENTID | no example | GitLab API client id |
| HMD_GITLAB_CLIENTSECRET | no example | GitLab API client secret |
| HMD_DROPBOX_CLIENTID | no example | Dropbox API client id |
| HMD_DROPBOX_CLIENTSECRET | no example | Dropbox API client secret |
| HMD_GOOGLE_CLIENTID | no example | Google API client id |
| HMD_GOOGLE_CLIENTSECRET | no example | Google API client secret |
| HMD_LDAP_URL | `ldap://example.com` | url of LDAP server |
| HMD_LDAP_BINDDN | no example | bindDn for LDAP access |
| HMD_LDAP_BINDCREDENTIALS | no example | bindCredentials for LDAP access |
| HMD_LDAP_TOKENSECRET | `supersecretkey` | secret used for generating access/refresh tokens |
| HMD_LDAP_SEARCHBASE | `o=users,dc=example,dc=com` | LDAP directory to begin search from |
| HMD_LDAP_SEARCHFILTER | `(uid={{username}})` | LDAP filter to search with |
| HMD_LDAP_SEARCHATTRIBUTES | no example | LDAP attributes to search with |
| HMD_LDAP_TLS_CA | `server-cert.pem, root.pem` | Root CA for LDAP TLS in PEM format (use comma to separate) |
| HMD_LDAP_PROVIDERNAME | `My institution` | Optional name to be displayed at login form indicating the LDAP provider |
| HMD_IMGUR_CLIENTID | no example | Imgur API client id |
| HMD_EMAIL | `true` or `false` | set to allow email signin |
| HMD_ALLOW_EMAIL_REGISTER | `true` or `false` | set to allow email register (only applied when email is set, default is `true`) |
| HMD_IMAGE_UPLOAD_TYPE | `imgur`, `s3` or `filesystem` | Where to upload image. For S3, see our [S3 Image Upload Guide](docs/guides/s3-image-upload.md) |
| HMD_S3_ACCESS_KEY_ID | no example | AWS access key id |
| HMD_S3_SECRET_ACCESS_KEY | no example | AWS secret key |
| HMD_S3_REGION | `ap-northeast-1` | AWS S3 region |
| HMD_S3_BUCKET | no example | AWS S3 bucket name |
Application settings `config.json`
---
| variables | example values | description |
| --------- | ------ | ----------- |
| debug | `true` or `false` | set debug mode, show more logs |
| domain | `localhost` | domain name |
| urlpath | `hackmd` | sub url path, like `www.example.com/<urlpath>` |
| port | `80` | web app port |
| alloworigin | `['localhost']` | domain name whitelist |
| usessl | `true` or `false` | set to use ssl server (if true will auto turn on `protocolusessl`) |
| protocolusessl | `true` or `false` | set to use ssl protocol for resources path (only applied when domain is set) |
| urladdport | `true` or `false` | set to add port on callback url (port 80 or 443 won't applied) (only applied when domain is set) |
| usecdn | `true` or `false` | set to use CDN resources or not (default is `true`) |
| allowanonymous | `true` or `false` | set to allow anonymous usage (default is `true`) |
| allowfreeurl | `true` or `false` | set to allow new note by accessing not exist note url |
| defaultpermission | `freely`, `editable`, `limited`, `locked` or `private` | set notes default permission (only applied on signed users) |
| dburl | `mysql://localhost:3306/database` | set the db url, if set this variable then below db config won't be applied |
| db | `{ "dialect": "sqlite", "storage": "./db.hackmd.sqlite" }` | set the db configs, [see more here](http://sequelize.readthedocs.org/en/latest/api/sequelize/) |
| sslkeypath | `./cert/client.key` | ssl key path (only need when you set usessl) |
| sslcertpath | `./cert/hackmd_io.crt` | ssl cert path (only need when you set usessl) |
| sslcapath | `['./cert/COMODORSAAddTrustCA.crt']` | ssl ca chain (only need when you set usessl) |
| dhparampath | `./cert/dhparam.pem` | ssl dhparam path (only need when you set usessl) |
| tmppath | `./tmp/` | temp directory path |
| defaultnotepath | `./public/default.md` | default note file path |
| docspath | `./public/docs` | docs directory path |
| indexpath | `./public/views/index.ejs` | index template file path |
| hackmdpath | `./public/views/hackmd.ejs` | hackmd template file path |
| errorpath | `./public/views/error.ejs` | error template file path |
| prettypath | `./public/views/pretty.ejs` | pretty template file path |
| slidepath | `./public/views/slide.hbs` | slide template file path |
| 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 |
| allowemailregister | `true` or `false` | set to allow email register (only applied when email is set, default is `true`) |
| imageUploadType | `imgur`(default), `s3` or `filesystem` | Where to upload image
| s3 | `{ "accessKeyId": "YOUR_S3_ACCESS_KEY_ID", "secretAccessKey": "YOUR_S3_ACCESS_KEY", "region": "YOUR_S3_REGION", "bucket": "YOUR_S3_BUCKET_NAME" }` | When `imageUploadType` be setted to `s3`, you would also need to setup this key, check our [S3 Image Upload Guide](docs/guides/s3-image-upload.md) |
Third-party integration api key settings
---
| service | settings location | description |
| ------- | --------- | ----------- |
| facebook, twitter, github, gitlab, dropbox, google, ldap | environment variables or `config.json` | for signin |
| imgur | environment variables or `config.json` | for image upload |
| google drive(`google/apiKey`, `google/clientID`), 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` |
| dropbox | `/auth/dropbox/callback` |
| google | `/auth/google/callback` |
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/)
**License under MIT.**
[gitter-image]: https://badges.gitter.im/Join%20Chat.svg
[gitter-url]: https://gitter.im/hackmdio/hackmd?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge
[travis-image]: https://travis-ci.org/hackmdio/hackmd.svg?branch=master
[travis-url]: https://travis-ci.org/hackmdio/hackmd
[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/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
[social-mastodon]: https://social.codimd.org/mastodon
[social-mastodon-image]: https://img.shields.io/badge/social-mastodon-3c99dc.svg

851
app.js
View File

@ -1,654 +1,309 @@
//app
//external modules
var express = require('express');
var toobusy = require('toobusy-js');
var ejs = require('ejs');
var passport = require('passport');
var methodOverride = require('method-override');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
'use strict'
// app
// external modules
var express = require('express')
var ejs = require('ejs')
var passport = require('passport')
var methodOverride = require('method-override')
var cookieParser = require('cookie-parser')
var compression = require('compression')
var session = require('express-session');
var SequelizeStore = require('connect-session-sequelize')(session.Store);
var fs = require('fs');
var url = require('url');
var path = require('path');
var imgur = require('imgur');
var formidable = require('formidable');
var morgan = require('morgan');
var passportSocketIo = require("passport.socketio");
var helmet = require('helmet');
var i18n = require('i18n');
var flash = require('connect-flash');
var validator = require('validator');
var session = require('express-session')
var SequelizeStore = require('connect-session-sequelize')(session.Store)
var fs = require('fs')
var path = require('path')
//core
var config = require("./lib/config.js");
var logger = require("./lib/logger.js");
var auth = require("./lib/auth.js");
var response = require("./lib/response.js");
var models = require("./lib/models");
var morgan = require('morgan')
var passportSocketIo = require('passport.socketio')
var helmet = require('helmet')
var i18n = require('i18n')
var flash = require('connect-flash')
//server setup
if (config.usessl) {
var ca = (function () {
var i, len, results;
results = [];
for (i = 0, len = config.sslcapath.length; i < len; i++) {
results.push(fs.readFileSync(config.sslcapath[i], 'utf8'));
}
return results;
})();
var options = {
key: fs.readFileSync(config.sslkeypath, 'utf8'),
cert: fs.readFileSync(config.sslcertpath, 'utf8'),
ca: ca,
dhparam: fs.readFileSync(config.dhparampath, 'utf8'),
requestCert: false,
rejectUnauthorized: false
};
var app = express();
var server = require('https').createServer(options, app);
// core
var config = require('./lib/config')
var logger = require('./lib/logger')
var response = require('./lib/response')
var models = require('./lib/models')
var csp = require('./lib/csp')
// server setup
var app = express()
var server = null
if (config.useSSL) {
var ca = (function () {
var i, len, results
results = []
for (i = 0, len = config.sslCAPath.length; i < len; i++) {
results.push(fs.readFileSync(config.sslCAPath[i], 'utf8'))
}
return results
})()
var options = {
key: fs.readFileSync(config.sslKeyPath, 'utf8'),
cert: fs.readFileSync(config.sslCertPath, 'utf8'),
ca: ca,
dhparam: fs.readFileSync(config.dhParamPath, 'utf8'),
requestCert: false,
rejectUnauthorized: false
}
server = require('https').createServer(options, app)
} else {
var app = express();
var server = require('http').createServer(app);
server = require('http').createServer(app)
}
//logger
// logger
app.use(morgan('combined', {
"stream": logger.stream
}));
'stream': logger.stream
}))
//socket io
var io = require('socket.io')(server);
io.engine.ws = new (require('uws').Server)({
noServer: true,
perMessageDeflate: false
});
// socket io
var io = require('socket.io')(server)
io.engine.ws = new (require('ws').Server)({
noServer: true,
perMessageDeflate: false
})
//others
var realtime = require("./lib/realtime.js");
// others
var realtime = require('./lib/realtime.js')
//assign socket io to realtime
realtime.io = io;
// assign socket io to realtime
realtime.io = io
//methodOverride
app.use(methodOverride('_method'));
// methodOverride
app.use(methodOverride('_method'))
// create application/json parser
var jsonParser = bodyParser.json({
limit: 1024 * 1024 * 10 // 10 mb
});
// create application/x-www-form-urlencoded parser
var urlencodedParser = bodyParser.urlencoded({
extended: false,
limit: 1024 * 1024 * 10 // 10 mb
});
//session store
// session store
var sessionStore = new SequelizeStore({
db: models.sequelize
});
db: models.sequelize
})
//compression
app.use(compression());
// compression
app.use(compression())
// use hsts to tell https users stick to this
app.use(helmet.hsts({
maxAge: 31536000 * 1000, // 365 days
includeSubdomains: true,
preload: true
}));
if (config.hsts.enable) {
app.use(helmet.hsts({
maxAge: config.hsts.maxAgeSeconds,
includeSubdomains: config.hsts.includeSubdomains,
preload: config.hsts.preload
}))
} else if (config.useSSL) {
logger.info('Consider enabling HSTS for extra security:')
logger.info('https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security')
}
// Add referrer policy to improve privacy
app.use(
helmet.referrerPolicy({
policy: 'same-origin'
})
)
// Generate a random nonce per request, for CSP with inline scripts
app.use(csp.addNonceToLocals)
// use Content-Security-Policy to limit XSS, dangerous plugins, etc.
// https://helmetjs.github.io/docs/csp/
if (config.csp.enable) {
app.use(helmet.contentSecurityPolicy({
directives: csp.computeDirectives()
}))
} else {
logger.info('Content-Security-Policy is disabled. This may be a security risk.')
}
i18n.configure({
locales: ['en', 'zh', 'fr', 'de', 'ja', 'es', 'el', 'pt', 'it', 'tr', 'ru', 'nl', 'hr', 'pl', 'uk', 'hi', 'sv', 'eo'],
cookie: 'locale',
directory: __dirname + '/locales'
});
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', 'vi'],
cookie: 'locale',
indent: ' ', // this is the style poeditor.com exports it, this creates less churn
directory: path.join(__dirname, '/locales'),
updateFiles: config.updateI18nFiles
})
app.use(cookieParser());
app.use(cookieParser())
app.use(i18n.init);
app.use(i18n.init)
// routes without sessions
// static files
app.use('/', express.static(__dirname + '/public', { maxAge: config.staticcachetime }));
app.use('/', express.static(path.join(__dirname, '/public'), { maxAge: config.staticCacheTime, index: false }))
app.use('/docs', express.static(path.resolve(__dirname, config.docsPath), { maxAge: config.staticCacheTime }))
app.use('/uploads', express.static(path.resolve(__dirname, config.uploadsPath), { maxAge: config.staticCacheTime }))
app.use('/default.md', express.static(path.resolve(__dirname, config.defaultNotePath), { maxAge: config.staticCacheTime }))
//session
// session
app.use(session({
name: config.sessionname,
secret: config.sessionsecret,
resave: false, //don't save session if unmodified
saveUninitialized: true, //always create session to ensure the origin
rolling: true, // reset maxAge on every response
cookie: {
maxAge: config.sessionlife
},
store: sessionStore
}));
name: config.sessionName,
secret: config.sessionSecret,
resave: false, // don't save session if unmodified
saveUninitialized: true, // always create session to ensure the origin
rolling: true, // reset maxAge on every response
cookie: {
maxAge: config.sessionLife
},
store: sessionStore
}))
// session resumption
var tlsSessionStore = {};
var tlsSessionStore = {}
server.on('newSession', function (id, data, cb) {
tlsSessionStore[id.toString('hex')] = data;
cb();
});
tlsSessionStore[id.toString('hex')] = data
cb()
})
server.on('resumeSession', function (id, cb) {
cb(null, tlsSessionStore[id.toString('hex')] || null);
});
cb(null, tlsSessionStore[id.toString('hex')] || null)
})
//middleware which blocks requests when we're too busy
app.use(function (req, res, next) {
if (toobusy()) {
response.errorServiceUnavailable(res);
} else {
next();
}
});
// middleware which blocks requests when we're too busy
app.use(require('./lib/web/middleware/tooBusy'))
app.use(flash());
app.use(flash())
//passport
app.use(passport.initialize());
app.use(passport.session());
//serialize and deserialize
passport.serializeUser(function (user, done) {
logger.info('serializeUser: ' + user.id);
return done(null, user.id);
});
passport.deserializeUser(function (id, done) {
models.User.findOne({
where: {
id: id
}
}).then(function (user) {
logger.info('deserializeUser: ' + user.id);
return done(null, user);
}).catch(function (err) {
logger.error(err);
return done(err, null);
});
});
// passport
app.use(passport.initialize())
app.use(passport.session())
// check uri is valid before going further
app.use(function(req, res, next) {
try {
decodeURIComponent(req.path);
} catch (err) {
logger.error(err);
return response.errorBadRequest(res);
}
next();
});
app.use(require('./lib/web/middleware/checkURIValid'))
// redirect url without trailing slashes
app.use(function(req, res, next) {
if ("GET" == req.method && req.path.substr(-1) == '/' && req.path.length > 1) {
var query = req.url.slice(req.path.length);
var urlpath = req.path.slice(0, -1);
var serverurl = config.serverurl;
if (config.urlpath) serverurl = serverurl.slice(0, -(config.urlpath.length + 1));
res.redirect(301, serverurl + urlpath + query);
} else {
next();
}
});
app.use(require('./lib/web/middleware/redirectWithoutTrailingSlashes'))
app.use(require('./lib/web/middleware/codiMDVersion'))
// routes need sessions
//template files
app.set('views', __dirname + '/public/views');
//set render engine
app.engine('ejs', ejs.renderFile);
//set view engine
app.set('view engine', 'ejs');
//get index
app.get("/", response.showIndex);
//get 403 forbidden
app.get("/403", function (req, res) {
response.errorForbidden(res);
});
//get 404 not found
app.get("/404", function (req, res) {
response.errorNotFound(res);
});
//get 500 internal error
app.get("/500", function (req, res) {
response.errorInternalError(res);
});
//get status
app.get("/status", function (req, res, next) {
realtime.getStatus(function (data) {
res.set({
'Cache-Control': 'private', // only cache by client
'X-Robots-Tag': 'noindex, nofollow' // prevent crawling
});
res.send(data);
});
});
//get status
app.get("/temp", function (req, res) {
var host = req.get('host');
if (config.alloworigin.indexOf(host) == -1)
response.errorForbidden(res);
else {
var tempid = req.query.tempid;
if (!tempid)
response.errorForbidden(res);
else {
models.Temp.findOne({
where: {
id: tempid
}
}).then(function (temp) {
if (!temp)
response.errorNotFound(res);
else {
res.header("Access-Control-Allow-Origin", "*");
res.send({
temp: temp.data
});
temp.destroy().catch(function (err) {
if (err)
logger.error('remove temp failed: ' + err);
});
}
}).catch(function (err) {
logger.error(err);
return response.errorInternalError(res);
});
}
}
});
//post status
app.post("/temp", urlencodedParser, function (req, res) {
var host = req.get('host');
if (config.alloworigin.indexOf(host) == -1)
response.errorForbidden(res);
else {
var data = req.body.data;
if (!data)
response.errorForbidden(res);
else {
if (config.debug)
logger.info('SERVER received temp from [' + host + ']: ' + req.body.data);
models.Temp.create({
data: data
}).then(function (temp) {
if (temp) {
res.header("Access-Control-Allow-Origin", "*");
res.send({
status: 'ok',
id: temp.id
});
} else
response.errorInternalError(res);
}).catch(function (err) {
logger.error(err);
return response.errorInternalError(res);
});
}
}
});
function setReturnToFromReferer(req) {
var referer = req.get('referer');
if (!req.session) req.session = {};
req.session.returnTo = referer;
// template files
app.set('views', config.viewPath)
// set render engine
app.engine('ejs', ejs.renderFile)
// set view engine
app.set('view engine', 'ejs')
// set generally available variables for all views
app.locals.useCDN = config.useCDN
app.locals.serverURL = config.serverURL
app.locals.sourceURL = config.sourceURL
app.locals.allowAnonymous = config.allowAnonymous
app.locals.allowAnonymousEdits = config.allowAnonymousEdits
app.locals.allowPDFExport = config.allowPDFExport
app.locals.authProviders = {
facebook: config.isFacebookEnable,
twitter: config.isTwitterEnable,
github: config.isGitHubEnable,
gitlab: config.isGitLabEnable,
mattermost: config.isMattermostEnable,
dropbox: config.isDropboxEnable,
google: config.isGoogleEnable,
ldap: config.isLDAPEnable,
ldapProviderName: config.ldap.providerName,
saml: config.isSAMLEnable,
oauth2: config.isOAuth2Enable,
oauth2ProviderName: config.oauth2.providerName,
openID: config.isOpenIDEnable,
email: config.isEmailEnable,
allowEmailRegister: config.allowEmailRegister
}
//facebook auth
if (config.facebook) {
app.get('/auth/facebook', function (req, res, next) {
setReturnToFromReferer(req);
passport.authenticate('facebook')(req, res, next);
});
//facebook auth callback
app.get('/auth/facebook/callback',
passport.authenticate('facebook', {
successReturnToOrRedirect: config.serverurl + '/',
failureRedirect: config.serverurl + '/'
}));
}
//twitter auth
if (config.twitter) {
app.get('/auth/twitter', function (req, res, next) {
setReturnToFromReferer(req);
passport.authenticate('twitter')(req, res, next);
});
//twitter auth callback
app.get('/auth/twitter/callback',
passport.authenticate('twitter', {
successReturnToOrRedirect: config.serverurl + '/',
failureRedirect: config.serverurl + '/'
}));
}
//github auth
if (config.github) {
app.get('/auth/github', function (req, res, next) {
setReturnToFromReferer(req);
passport.authenticate('github')(req, res, next);
});
//github auth callback
app.get('/auth/github/callback',
passport.authenticate('github', {
successReturnToOrRedirect: config.serverurl + '/',
failureRedirect: config.serverurl + '/'
}));
//github callback actions
app.get('/auth/github/callback/:noteId/:action', response.githubActions);
}
//gitlab auth
if (config.gitlab) {
app.get('/auth/gitlab', function (req, res, next) {
setReturnToFromReferer(req);
passport.authenticate('gitlab')(req, res, next);
});
//gitlab auth callback
app.get('/auth/gitlab/callback',
passport.authenticate('gitlab', {
successReturnToOrRedirect: config.serverurl + '/',
failureRedirect: config.serverurl + '/'
}));
//gitlab callback actions
app.get('/auth/gitlab/callback/:noteId/:action', response.gitlabActions);
}
//dropbox auth
if (config.dropbox) {
app.get('/auth/dropbox', function (req, res, next) {
setReturnToFromReferer(req);
passport.authenticate('dropbox-oauth2')(req, res, next);
});
//dropbox auth callback
app.get('/auth/dropbox/callback',
passport.authenticate('dropbox-oauth2', {
successReturnToOrRedirect: config.serverurl + '/',
failureRedirect: config.serverurl + '/'
}));
}
//google auth
if (config.google) {
app.get('/auth/google', function (req, res, next) {
setReturnToFromReferer(req);
passport.authenticate('google', { scope: ['profile'] })(req, res, next);
});
//google auth callback
app.get('/auth/google/callback',
passport.authenticate('google', {
successReturnToOrRedirect: config.serverurl + '/',
failureRedirect: config.serverurl + '/'
}));
}
// ldap auth
if (config.ldap) {
app.post('/auth/ldap', urlencodedParser, function (req, res, next) {
if (!req.body.username || !req.body.password) return response.errorBadRequest(res);
setReturnToFromReferer(req);
passport.authenticate('ldapauth', {
successReturnToOrRedirect: config.serverurl + '/',
failureRedirect: config.serverurl + '/',
failureFlash: true
})(req, res, next);
});
}
// email auth
if (config.email) {
if (config.allowemailregister)
app.post('/register', urlencodedParser, function (req, res, next) {
if (!req.body.email || !req.body.password) return response.errorBadRequest(res);
if (!validator.isEmail(req.body.email)) return response.errorBadRequest(res);
models.User.findOrCreate({
where: {
email: req.body.email
},
defaults: {
password: req.body.password
}
}).spread(function (user, created) {
if (user) {
if (created) {
if (config.debug) logger.info('user registered: ' + user.id);
req.flash('info', "You've successfully registered, please signin.");
} else {
if (config.debug) logger.info('user found: ' + user.id);
req.flash('error', "This email has been used, please try another one.");
}
return res.redirect(config.serverurl + '/');
}
req.flash('error', "Failed to register your account, please try again.");
return res.redirect(config.serverurl + '/');
}).catch(function (err) {
logger.error('auth callback failed: ' + err);
return response.errorInternalError(res);
});
});
// Export/Import menu items
app.locals.enableDropBoxSave = config.isDropboxEnable
app.locals.enableGitHubGist = config.isGitHubEnable
app.locals.enableGitlabSnippets = config.isGitlabSnippetsEnable
app.post('/login', urlencodedParser, function (req, res, next) {
if (!req.body.email || !req.body.password) return response.errorBadRequest(res);
if (!validator.isEmail(req.body.email)) return response.errorBadRequest(res);
setReturnToFromReferer(req);
passport.authenticate('local', {
successReturnToOrRedirect: config.serverurl + '/',
failureRedirect: config.serverurl + '/',
failureFlash: 'Invalid email or password.'
})(req, res, next);
});
}
//logout
app.get('/logout', function (req, res) {
if (config.debug && req.isAuthenticated())
logger.info('user logout: ' + req.user.id);
req.logout();
res.redirect(config.serverurl + '/');
});
var history = require("./lib/history.js");
//get history
app.get('/history', history.historyGet);
//post history
app.post('/history', urlencodedParser, history.historyPost);
//post history by note id
app.post('/history/:noteId', urlencodedParser, history.historyPost);
//delete history
app.delete('/history', history.historyDelete);
//delete history by note id
app.delete('/history/:noteId', history.historyDelete);
//get me info
app.get('/me', function (req, res) {
if (req.isAuthenticated()) {
models.User.findOne({
where: {
id: req.user.id
}
}).then(function (user) {
if (!user)
return response.errorNotFound(res);
var profile = models.User.getProfile(user);
res.send({
status: 'ok',
id: req.user.id,
name: profile.name,
photo: profile.photo
});
}).catch(function (err) {
logger.error('read me failed: ' + err);
return response.errorInternalError(res);
});
} else {
res.send({
status: 'forbidden'
});
}
});
app.use(require('./lib/web/baseRouter'))
app.use(require('./lib/web/statusRouter'))
app.use(require('./lib/web/auth'))
app.use(require('./lib/web/historyRouter'))
app.use(require('./lib/web/userRouter'))
app.use(require('./lib/web/imageRouter'))
app.use(require('./lib/web/noteRouter'))
//upload image
app.post('/uploadimage', function (req, res) {
var form = new formidable.IncomingForm();
form.keepExtensions = true;
if (config.imageUploadType === 'filesystem') {
form.uploadDir = "public/uploads";
}
form.parse(req, function (err, fields, files) {
if (err || !files.image || !files.image.path) {
response.errorForbidden(res);
} else {
if (config.debug)
logger.info('SERVER received uploadimage: ' + JSON.stringify(files.image));
try {
switch (config.imageUploadType) {
case 'filesystem':
res.send({
link: url.resolve(config.serverurl + '/', files.image.path.match(/^public\/(.+$)/)[1])
});
break;
case 's3':
var AWS = require('aws-sdk');
var awsConfig = new AWS.Config(config.s3);
var s3 = new AWS.S3(awsConfig);
fs.readFile(files.image.path, function (err, buffer) {
var params = {
Bucket: config.s3bucket,
Key: path.join('uploads', path.basename(files.image.path)),
Body: buffer
};
s3.putObject(params, function (err, data) {
if (err) {
logger.error(err);
res.status(500).end('upload image error');
} else {
res.send({
link: `https://s3-${config.s3.region}.amazonaws.com/${config.s3bucket}/${params.Key}`
});
}
});
});
break;
case 'imgur':
default:
imgur.setClientId(config.imgur.clientID);
imgur.uploadFile(files.image.path)
.then(function (json) {
if (config.debug)
logger.info('SERVER uploadimage success: ' + JSON.stringify(json));
res.send({
link: json.data.link.replace(/^http:\/\//i, 'https://')
});
})
.catch(function (err) {
logger.error(err);
return res.status(500).end('upload image error');
});
break;
}
} catch (err) {
logger.error(err);
return res.status(500).end('upload image error');
}
}
});
});
//get new note
app.get("/new", response.newNote);
//get publish note
app.get("/s/:shortid", response.showPublishNote);
//publish note actions
app.get("/s/:shortid/:action", response.publishNoteActions);
//get publish slide
app.get("/p/:shortid", response.showPublishSlide);
//publish slide actions
app.get("/p/:shortid/:action", response.publishSlideActions);
//get note by id
app.get("/:noteId", response.showNote);
//note actions
app.get("/:noteId/:action", response.noteActions);
//note actions with action id
app.get("/:noteId/:action/:actionId", response.noteActions);
// response not found if no any route matches
// response not found if no any route matxches
app.get('*', function (req, res) {
response.errorNotFound(res);
});
response.errorNotFound(res)
})
//socket.io secure
io.use(realtime.secure);
//socket.io auth
// socket.io secure
io.use(realtime.secure)
// socket.io auth
io.use(passportSocketIo.authorize({
cookieParser: cookieParser,
key: config.sessionname,
secret: config.sessionsecret,
store: sessionStore,
success: realtime.onAuthorizeSuccess,
fail: realtime.onAuthorizeFail
}));
//socket.io heartbeat
io.set('heartbeat interval', config.heartbeatinterval);
io.set('heartbeat timeout', config.heartbeattimeout);
//socket.io connection
io.sockets.on('connection', realtime.connection);
cookieParser: cookieParser,
key: config.sessionName,
secret: config.sessionSecret,
store: sessionStore,
success: realtime.onAuthorizeSuccess,
fail: realtime.onAuthorizeFail
}))
// socket.io heartbeat
io.set('heartbeat interval', config.heartbeatInterval)
io.set('heartbeat timeout', config.heartbeatTimeout)
// socket.io connection
io.sockets.on('connection', realtime.connection)
//listen
function startListen() {
server.listen(config.port, function () {
var schema = config.usessl ? 'HTTPS' : 'HTTP';
logger.info('%s Server listening at port %d', schema, config.port);
config.maintenance = false;
});
// listen
function startListen () {
var address
var listenCallback = function () {
var schema = config.useSSL ? 'HTTPS' : 'HTTP'
logger.info('%s Server listening at %s', schema, address)
realtime.maintenance = false
}
// use unix domain socket if 'path' is specified
if (config.path) {
address = config.path
server.listen(config.path, listenCallback)
} else {
address = config.host + ':' + config.port
server.listen(config.port, config.host, listenCallback)
}
}
// sync db then start listen
models.sequelize.sync().then(function () {
// check if realtime is ready
if (realtime.isReady()) {
models.Revision.checkAllNotesRevision(function (err, notes) {
if (err) throw new Error(err);
if (!notes || notes.length <= 0) return startListen();
});
} else {
throw new Error('server still not ready after db synced');
}
});
// check if realtime is ready
if (realtime.isReady()) {
models.Revision.checkAllNotesRevision(function (err, notes) {
if (err) throw new Error(err)
if (!notes || notes.length <= 0) return startListen()
})
} else {
throw new Error('server still not ready after db synced')
}
})
// log uncaught exception
process.on('uncaughtException', function (err) {
logger.error('An uncaught exception has occured.');
logger.error(err);
logger.error('Process will exit now.');
process.exit(1);
});
logger.error('An uncaught exception has occured.')
logger.error(err)
logger.error('Process will exit now.')
process.exit(1)
})
// install exit handler
function handleTermSignals() {
config.maintenance = true;
// disconnect all socket.io clients
Object.keys(io.sockets.sockets).forEach(function (key) {
var socket = io.sockets.sockets[key];
// notify client server going into maintenance status
socket.emit('maintenance');
setTimeout(function () {
socket.disconnect(true);
}, 0);
});
var checkCleanTimer = setInterval(function () {
if (realtime.isReady()) {
models.Revision.checkAllNotesRevision(function (err, notes) {
if (err) return logger.error(err);
if (!notes || notes.length <= 0) {
clearInterval(checkCleanTimer);
return process.exit(0);
}
});
function handleTermSignals () {
logger.info('CodiMD has been killed by signal, try to exit gracefully...')
realtime.maintenance = true
// disconnect all socket.io clients
Object.keys(io.sockets.sockets).forEach(function (key) {
var socket = io.sockets.sockets[key]
// notify client server going into maintenance status
socket.emit('maintenance')
setTimeout(function () {
socket.disconnect(true)
}, 0)
})
if (config.path) {
fs.unlink(config.path)
}
var checkCleanTimer = setInterval(function () {
if (realtime.isReady()) {
models.Revision.checkAllNotesRevision(function (err, notes) {
if (err) return logger.error(err)
if (!notes || notes.length <= 0) {
clearInterval(checkCleanTimer)
return process.exit(0)
}
}, 100);
})
}
}, 100)
}
process.on('SIGINT', handleTermSignals);
process.on('SIGTERM', handleTermSignals);
process.on('SIGINT', handleTermSignals)
process.on('SIGTERM', handleTermSignals)
process.on('SIGQUIT', handleTermSignals)

111
app.json
View File

@ -1,23 +1,16 @@
{
"name": "HackMD",
"name": "CodiMD",
"description": "Realtime collaborative markdown notes on all platforms",
"keywords": [
"Collaborative",
"Markdown",
"Notes"
],
"website": "https://hackmd.io",
"repository": "https://github.com/hackmdio/hackmd",
"logo": "https://github.com/hackmdio/hackmd/raw/master/public/hackmd-icon-1024.png",
"website": "https://codimd.org",
"repository": "https://github.com/codimd/server",
"logo": "https://github.com/codimd/server/raw/master/public/codimd-icon-1024.png",
"success_url": "/",
"scripts": {
"postdeploy": "./node_modules/.bin/sequelize db:migrate"
},
"env": {
"BUILD_ASSETS": {
"description": "Our build script variable",
"value": "true"
},
"NPM_CONFIG_PRODUCTION": {
"description": "Let npm also install development build tool",
"value": "false"
@ -26,99 +19,129 @@
"description": "Specify database type. See sequelize available databases. Default using postgres",
"value": "postgres"
},
"HMD_DOMAIN": {
"CMD_SESSION_SECRET": {
"description": "Secret used to secure session cookies.",
"required": false
},
"CMD_HSTS_ENABLE": {
"description": "whether to also use HSTS if HTTPS is enabled",
"required": false
},
"CMD_HSTS_MAX_AGE": {
"description": "max duration, in seconds, to tell clients to keep HSTS status",
"required": false
},
"CMD_HSTS_INCLUDE_SUBDOMAINS": {
"description": "whether to tell clients to also regard subdomains as HSTS hosts",
"required": false
},
"CMD_HSTS_PRELOAD": {
"description": "whether to allow at all adding of the site to HSTS preloads (e.g. in browsers)",
"required": false
},
"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_PORT": {
"description": "web app port",
"required": false,
"value": "80"
},
"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_DROPBOX_CLIENTID": {
"CMD_GITLAB_SCOPE": {
"description": "GitLab API client scope (optional)",
"required": false
},
"CMD_MATTERMOST_BASEURL": {
"description": "Mattermost authentication endpoint",
"required": false
},
"CMD_MATTERMOST_CLIENTID": {
"description": "Mattermost API client id",
"required": false
},
"CMD_MATTERMOST_CLIENTSECRET": {
"description": "Mattermost API client secret",
"required": false
},
"CMD_DROPBOX_CLIENTID": {
"description": "Dropbox API client id",
"required": false
},
"HMD_DROPBOX_CLIENTSECRET": {
"CMD_DROPBOX_CLIENTSECRET": {
"description": "Dropbox API client secret",
"required": false
},
"HMD_GOOGLE_CLIENTID": {
"CMD_DROPBOX_APP_KEY": {
"description": "Dropbox app key (for import/export)",
"required": false
},
"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
},
"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"
}
]
}

View File

@ -2,11 +2,7 @@
set -e
if [ "$BUILD_ASSETS" = true ]; then
BUILD_ASSETS=false npm install
# setup config files
cat << EOF > .sequelizerc
cat << EOF > .sequelizerc
var path = require('path');
module.exports = {
@ -19,7 +15,7 @@ module.exports = {
EOF
cat << EOF > config.json
cat << EOF > config.json
{
"production": {
@ -27,7 +23,3 @@ EOF
}
EOF
# build app
npm run build
fi

119
bin/manage_users Executable file
View File

@ -0,0 +1,119 @@
#!/usr/bin/env node
// First configure the logger so it does not spam the console
const logger = require("../lib/logger");
logger.transports.forEach((transport) => transport.level = "warning")
const models = require("../lib/models/");
const readline = require("readline-sync");
const minimist = require("minimist");
function showUsage(tips) {
console.log(`${tips}
Command-line utility to create users for email-signin.
Usage: bin/manage_users [--pass password] (--add | --del) user-email
Options:
--add Add user with the specified user-email
--del Delete user with specified user-email
--reset Reset user password with specified user-email
--pass Use password from cmdline rather than prompting
`);
process.exit(1);
}
function getPass(argv, action) {
// Find whether we use cmdline or prompt password
if(typeof argv["pass"] !== 'string') {
return readline.question(`Password for ${argv[action]}:`, {hideEchoBack: true});
}
console.log("Using password from commandline...");
return argv["pass"];
}
// Using an async function to be able to use await inside
async function createUser(argv) {
const existing_user = await models.User.findOne({where: {email: argv["add"]}});
// Cannot create already-existing users
if(existing_user != undefined) {
console.log(`User with e-mail ${existing_user.email} already exists! Aborting ...`);
process.exit(1);
}
const pass = getPass(argv, "add");
// Lets try to create, and check success
const ref = await models.User.create({email: argv["add"], password: pass});
if(ref == undefined) {
console.log(`Could not create user with email ${argv["add"]}`);
process.exit(1);
} else
console.log(`Created user with email ${argv["add"]}`);
}
// Using an async function to be able to use await inside
async function deleteUser(argv) {
// Cannot delete non-existing users
const existing_user = await models.User.findOne({where: {email: argv["del"]}});
if(existing_user === undefined) {
console.log(`User with e-mail ${argv["del"]} does not exist, cannot delete`);
process.exit(1);
}
// Sadly .destroy() does not return any success value with all
// backends. See sequelize #4124
await existing_user.destroy();
console.log(`Deleted user ${argv["del"]} ...`);
}
// Using an async function to be able to use await inside
async function resetUser(argv) {
const existing_user = await models.User.findOne({where: {email: argv["reset"]}});
// Cannot reset non-existing users
if(existing_user == undefined) {
console.log(`User with e-mail ${argv["reset"]} does not exist, cannot reset`);
process.exit(1);
}
const pass = getPass(argv, "reset");
// set password and save
existing_user.password = pass;
await existing_user.save();
console.log(`User with email ${argv["reset"]} password has been reset`);
}
const options = {
add: createUser,
del: deleteUser,
reset: resetUser,
};
// Perform commandline-parsing
const argv = minimist(process.argv.slice(2));
const keys = Object.keys(options);
const opts = keys.filter((key) => argv[key] !== undefined);
const action = opts[0];
// Check for options missing
if (opts.length === 0) {
showUsage(`You did not specify either ${keys.map((key) => `--${key}`).join(' or ')}!`);
}
// Check if both are specified
if (opts.length > 1) {
showUsage(`You cannot ${action.join(' and ')} at the same time!`);
}
// Check if not string
if (typeof argv[action] !== 'string') {
showUsage(`You must follow an email after --${action}`);
}
// Call respective processing functions
options[action](argv).then(function() {
process.exit(0);
});

View File

@ -5,14 +5,15 @@ set -e
# run command at repo root
CURRENT_PATH=$PWD
if [ -d .git ]; then
cd $(git rev-parse --show-toplevel)
cd "$(git rev-parse --show-toplevel)"
fi
if ! type npm > /dev/null
if ! type yarn > /dev/null
then
cat << EOF
npm is not installed, please install Node.js and npm.
yarn is not installed, please install Node.js, npm and yarn.
Read more on Node.js official website: https://nodejs.org
And for yarn package manager at: https://yarnpkg.com/en/
Setup will not be run
EOF
exit 0
@ -27,20 +28,20 @@ if [ ! -f .sequelizerc ]; then
cp .sequelizerc.example .sequelizerc
fi
echo "install npm packages"
BUILD_ASSETS=false npm install
echo "install packages"
yarn install --pure-lockfile
yarn install --production=false --pure-lockfile
cat << EOF
Edit the following config file to setup hackmd server and client.
Read more info at https://github.com/hackmdio/hackmd#configuration-files
Edit the following config file to setup CodiMD server and client.
Read more info at https://github.com/codimd/server#configuration-files
* config.json -- server config
* public/js/config.js -- client config
* config.json -- CodiMD config
* .sequelizerc -- db config
EOF
# change directory back
cd $CURRENT_PATH
cd "$CURRENT_PATH"

View File

@ -6,17 +6,37 @@
}
},
"development": {
"loglevel": "debug",
"hsts": {
"enable": false
},
"db": {
"dialect": "sqlite",
"storage": "./db.hackmd.sqlite"
"storage": "./db.codimd.sqlite"
}
},
"production": {
"domain": "localhost",
"loglevel": "info",
"hsts": {
"enable": true,
"maxAgeSeconds": 31536000,
"includeSubdomains": true,
"preload": true
},
"csp": {
"enable": true,
"directives": {
},
"upgradeInsecureRequests": "auto",
"addDefaults": true,
"addDisqus": true,
"addGoogleAnalytics": true
},
"db": {
"username": "",
"password": "",
"database": "hackmd",
"database": "codimd",
"host": "localhost",
"port": "5432",
"dialect": "postgres"
@ -34,6 +54,13 @@
"clientSecret": "change this"
},
"gitlab": {
"baseURL": "change this",
"clientID": "change this",
"clientSecret": "change this",
"scope": "use 'read_user' scope for auth user only or remove this property if you need gitlab snippet import/export support (will result to be default scope 'api')",
"version": "use 'v4' if gitlab version > 11, 'v3' otherwise. Default to 'v4'"
},
"mattermost": {
"baseURL": "change this",
"clientID": "change this",
"clientSecret": "change this"
@ -52,16 +79,50 @@
"url": "ldap://change_this",
"bindDn": null,
"bindCredentials": null,
"tokenSecret": "change this",
"searchBase": "change this",
"searchFilter": "change this",
"searchAttributes": "change this",
"searchAttributes": ["change this"],
"usernameField": "change this e.g. cn",
"useridField": "change this e.g. uid",
"tlsOptions": {
"changeme": "See https://nodejs.org/api/tls.html#tls_tls_connect_options_callback"
}
},
"saml": {
"idpSsoUrl": "change: authentication endpoint of IdP",
"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" ],
"attribute": {
"id": "change or delete this: attribute map for `id` (default: NameID)",
"username": "change or delete this: attribute map for `username` (default: NameID)",
"email": "change or delete this: attribute map for `email` (default: NameID)"
}
},
"imgur": {
"clientID": "change this"
},
"minio": {
"accessKey": "change this",
"secretKey": "change this",
"endPoint": "change this",
"secure": true,
"port": 9000
},
"s3": {
"accessKeyId": "change this",
"secretAccessKey": "change this",
"region": "change this"
},
"s3bucket": "change this",
"azure":
{
"connectionString": "change this",
"container": "change this"
}
}
}

View File

@ -0,0 +1,154 @@
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 |
| `tooBusyLag` | `70` | CPU time for one eventloop tick until node throttles connections. (milliseconds) |
| `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

View File

@ -0,0 +1,256 @@
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) |
| `CMD_TOOBUSY_LAG` | `70` | CPU time for one eventloop tick until node throttles connections. (milliseconds) |
## 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*

View 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
View 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

33
docs/dev/webpack.md Normal file
View File

@ -0,0 +1,33 @@
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.
**TODO:** Document which entry points are used for what.
## `webpack.htmlexport.js`
Separate config for the "save as html" feature.
Packs all CSS from `public/js/htmlExport.js` to `build/html.min.css`.
This file is then downloaded by client-side JS and used to create the HTML.
See `exportToHTML()` in `public/js/extra.js`.
## `webpack.dev.js`
The development config uses both common configs, enables development mode and enables "cheap" source maps (lines only).
If you need more detailed source maps while developing, you might want to use the `source-maps` option.
See https://webpack.js.org/configuration/devtool/ for details.
## `webpack.prod.js`
The production config uses both common configs and enables production mode.
This automatically enables various optimizations (e.g. UglifyJS). See https://webpack.js.org/concepts/mode/ for details.
For the global app config, the name of the emitted chunks is changed to include the content hash.
See https://webpack.js.org/guides/caching/ on why this is a good idea.
For the HTML export config, CSS minification is enabled.

View File

@ -0,0 +1,35 @@
Authentication guide - GitHub
===
**Note:** *This guide was written before the renaming. Just replace `HackMD` with `CodiMD` in your mind :smile: thanks!*
1. Sign-in or sign-up for a GitHub account
2. Navigate to developer settings in your GitHub account [here](https://github.com/settings/developers) and select the "OAuth Apps" tab
3. Click on the **New OAuth App** button, to create a new OAuth App:
![create-oauth-app](../../images/auth/create-oauth-app.png)
4. Fill out the new OAuth application registration form, and click **Register Application**
![register-oauth-application-form](../../images/auth/register-oauth-application-form.png)
**Note:** *The callback URL is <your-codimd-url>/auth/github/callback*
5. After successfully registering the application, you'll receive the Client ID and Client Secret for the application
![application-page](../../images/auth/application-page.png)
6. Add the Client ID and Client Secret to your config.json file or pass them as environment variables
* `config.json`:
```js
{
"production": {
"github": {
"clientID": "3747d30eaccXXXXXXXXX",
"clientSecret": "2a8e682948eee0c580XXXXXXXXXXXXXXXXXXXXXX"
}
}
}
```
* environment variables:
```sh
CMD_GITHUB_CLIENTID=3747d30eaccXXXXXXXXX
CMD_GITHUB_CLIENTSECRET=2a8e682948eee0c580XXXXXXXXXXXXXXXXXXXXXX
````

View File

@ -0,0 +1,32 @@
GitLab (self-hosted)
===
**Note:** *This guide was written before the renaming. Just replace `HackMD` with `CodiMD` in your mind :smile: thanks!*
1. Sign in to your GitLab
2. Navigate to the application management page at `https://your.gitlab.domain/admin/applications` (admin permissions required)
3. Click **New application** to create a new application and fill out the registration form:
![New GitLab application](../../images/auth/gitlab-new-application.png)
4. Click **Submit**
5. In the list of applications select **HackMD**. Leave that site open to copy the application ID and secret in the next step.
![Application: HackMD](../../images/auth/gitlab-application-details.png)
6. In the `docker-compose.yml` add the following environment variables to `app:` `environment:`
```
- HMD_DOMAIN=your.codimd.domain
- HMD_URL_ADDPORT=443
- HMD_PROTOCOL_USESSL=true
- HMD_GITLAB_BASEURL=https://your.gitlab.domain
- HMD_GITLAB_CLIENTID=23462a34example99XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
- HMD_GITLAB_CLIENTSECRET=5532e9dexamplXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
```
7. Run `docker-compose up -d` to apply your settings.
8. Sign in to your CodiMD using your GitLab ID:
![Sign in via GitLab](../../images/auth/gitlab-sign-in.png)

View File

@ -0,0 +1,50 @@
Keycloak/Red Hat SSO (self-hosted)
===
## Prerequisites
This guide assumes you have run and configured Keycloak. If you'd like to meet this prerequisite quickly, it can be achieved by running a `jboss/keycloak` container and attaching it to your network. Set the environment variables KEYCLOAK_USER and `KEYCLOAK_PASSWORD`, and expose port 8080.
Where HTTPS is specified throughout, use HTTP instead. You may also have to specify the exposed port, 8080.
## Steps
1. Sign in to the administration portal for your Keycloak instance at https://keycloak.example.com/auth/admin/master/console
You may note that a separate realm is specified throughout this tutorial. It is best practice not to use the master realm, as it normally contains the realm-management client that federates access using the policies and permissions you can create.
2. Navigate to the client management page at `https://keycloak.example.com/auth/admin/master/console/#/realms/your-realm/clients` (admin permissions required)
3. Click **Create** to create a new client and fill out the registration form. You should set the Root URL to the fully qualified public URL of your CodiMD instance.
4. Click **Save**
5. Set the **Access Type** of the client to `confidential`. This will make your client require a client secret upon authentication.
---
### Additional steps to circumvent generic OAuth2 issue:
1. Select Client Scopes from the sidebar, and begin to create a new client scope using the Create button.
2. Ensure that the **Name** field is set to `id`.
3. Create a new mapper under the Mappers tab. This should reference the User Property `id`. `Claim JSON Type` should be String and all switches below should be enabled. Save the mapper.
4. Go to the client you set up in the previous steps using the Clients page, then choose the Client Scopes tab. Apply the scope you've created. This should mitigate errors as seen in [codimd/server#56](https://github.com/codimd/server/issues/56), as the `/userinfo` endpoint should now bring back the user's ID under the `id` key as well as `sub`.
---
6. In the `docker-compose.yml` add the following environment variables to `app:` `environment:`
```
CMD_OAUTH2_USER_PROFILE_URL=https://keycloak.example.com/auth/realms/your-realm/protocol/openid-connect/userinfo
CMD_OAUTH2_USER_PROFILE_USERNAME_ATTR=preferred_username
CMD_OAUTH2_USER_PROFILE_DISPLAY_NAME_ATTR=name
CMD_OAUTH2_USER_PROFILE_EMAIL_ATTR=email
CMD_OAUTH2_TOKEN_URL=https://keycloak.example.com/auth/realms/your-realm/protocol/openid-connect/token
CMD_OAUTH2_AUTHORIZATION_URL=https://keycloak.example.com/auth/realms/your-realm/protocol/openid-connect/auth
CMD_OAUTH2_CLIENT_ID=<your client ID>
CMD_OAUTH2_CLIENT_SECRET=<your client secret, which you can find under the Credentials tab for your client>
CMD_OAUTH2_PROVIDERNAME=Keycloak
CMD_DOMAIN=<codimd.example.com>
CMD_PROTOCOL_USESSL=true
CMD_URL_ADDPORT=false
```
7. Run `docker-compose up -d` to apply your settings.
8. Sign in to your CodiMD using your Keycloak ID

View File

@ -0,0 +1,41 @@
AD LDAP auth
===
To setup your CodiMD instance with Active Directory you need the following configs:
```
CMD_LDAP_URL=ldap://internal.example.com
CMD_LDAP_BINDDN=cn=binduser,cn=Users,dc=internal,dc=example,dc=com
CMD_LDAP_BINDCREDENTIALS=<super secret password>
CMD_LDAP_SEARCHBASE=dc=internal,dc=example,dc=com
CMD_LDAP_SEARCHFILTER=(&(objectcategory=person)(objectclass=user)(|(sAMAccountName={{username}})(mail={{username}})))
CMD_LDAP_USERIDFIELD=sAMAccountName
CMD_LDAP_PROVIDERNAME=Example Inc AD
```
`CMD_LDAP_BINDDN` is either the `distinguishedName` or the `userPrincipalName`. *This can cause "username/password is invalid" when either this value or the password from `CMD_LDAP_BINDCREDENTIALS` are incorrect.*
`CMD_LDAP_SEARCHFILTER` matches on all users and uses either the email address or the `sAMAccountName` (usually the login name you also use to login to Windows).
*Only using `sAMAccountName` looks like this:* `(&(objectcategory=person)(objectclass=user)(sAMAccountName={{username}}))`
`CMD_LDAP_USERIDFIELD` says we want to use `sAMAccountName` as unique identifier for the account itself.
`CMD_LDAP_PROVIDERNAME` just the name written above the username and password field on the login page.
Same in json:
```json
"ldap": {
"url": "ldap://internal.example.com",
"bindDn": "cn=binduser,cn=Users,dc=internal,dc=example,dc=com",
"bindCredentials": "<super secret password>",
"searchBase": "dc=internal,dc=example,dc=com",
"searchFilter": "(&(objectcategory=person)(objectclass=user)(|(sAMAccountName={{username}})(mail={{username}})))",
"useridField": "sAMAccountName",
},
```
More details and example: https://www.npmjs.com/package/passport-ldapauth

View File

@ -0,0 +1,54 @@
Authentication guide - Mattermost (self-hosted)
===
**Note:** *The Mattermost setup portion of this document is just a quick guide. See the [official documentation](https://docs.mattermost.com/developer/oauth-2-0-applications.html) for more details.*
This guide uses the generic OAuth2 module for compatibility with Mattermost version 5.0 and above.
1. Sign-in with an administrator account to your Mattermost instance
2. Make sure **OAuth 2.0 Service Provider** is enabled in the Main Menu (menu button next to your username in the top left corner) --> System Console --> Custom Integrations menu, which you can find at `https://your.mattermost.domain/admin_console/integrations/custom`
![mattermost-enable-oauth2](../../images/auth/mattermost-enable-oauth2.png)
3. Navigate to the OAuth integration settings through Main Menu --> Integrations --> OAuth 2.0 Applications, at `https://your.mattermost.domain/yourteam/integrations/oauth2-apps`
4. Click on the **Add OAuth 2.0 Application** button to add a new OAuth application
![mattermost-oauth-app-add](../../images/auth/mattermost-oauth-app-add.png)
5. Fill out the form and click **Save**
![mattermost-oauth-app-form](../../images/auth/mattermost-oauth-app-form.png)
*Note: The callback URL is \<your-codimd-url\>/auth/oauth2/callback*
6. After saving the application, you'll receive the Client ID and Client Secret
![mattermost-oauth-app-done](../../images/auth/mattermost-oauth-app-done.png)
7. Add the Client ID and Client Secret to your config.json file or pass them as environment variables
* `config.json`:
```javascript
{
"production": {
"oauth2": {
"baseURL": "https://your.mattermost.domain",
"userProfileURL": "https://your.mattermost.domain/api/v4/users/me",
"userProfileUsernameAttr": "id",
"userProfileDisplayNameAttr": "username",
"userProfileEmailAttr": "email",
"tokenURL": "https://your.mattermost.domain/oauth/access_token",
"authorizationURL": "https://your.mattermost.domain/oauth/authorize",
"clientID": "ii4p1u3jz7dXXXXXXXXXXXXXXX",
"clientSecret": "mqzzx6fydbXXXXXXXXXXXXXXXX"
}
}
}
```
* environment variables:
```sh
CMD_OAUTH2_BASEURL=https://your.mattermost.domain
CMD_OAUTH2_USER_PROFILE_URL=https://your.mattermost.domain/api/v4/users/me
CMD_OAUTH2_USER_PROFILE_USERNAME_ATTR=id
CMD_OAUTH2_USER_PROFILE_DISPLAY_NAME_ATTR=username
CMD_OAUTH2_USER_PROFILE_EMAIL_ATTR=email
CMD_OAUTH2_TOKEN_URL=https://your.mattermost.domain/oauth/access_token
CMD_OAUTH2_AUTHORIZATION_URL=https://your.mattermost.domain/oauth/authorize
CMD_OAUTH2_CLIENT_ID=ii4p1u3jz7dXXXXXXXXXXXXXXX
CMD_OAUTH2_CLIENT_SECRET=mqzzx6fydbXXXXXXXXXXXXXXXX
```

View File

@ -0,0 +1,52 @@
Authentication guide - Nextcloud (self-hosted)
===
*This has been constructed using the [Nextcloud OAuth2 Documentation](https://docs.nextcloud.com/server/14/admin_manual/configuration_server/oauth2.html?highlight=oauth2) combined with [this issue comment on the nextcloud bugtracker](https://github.com/nextcloud/server/issues/5694#issuecomment-314761326).*
This guide uses the generic OAuth2 module for compatibility with Nextcloud 13 and above (this guide has been tested successfully with Nextcloud 14).
1. Sign-in with an administrator account to your Nextcloud server
2. Navigate to the OAuth integration settings: Profile Icon (top right) --> Settings
Then choose Security Settings from the *Administration* part of the list - Don't confuse this with Personal Security Settings, where you would change your personal password!
At the top there's OAuth 2.0-Clients.
![Where to find OAuth2 in Nextcloud](../../images/auth/nextcloud-oauth2-1-settings.png)
3. Add your CodiMD instance by giving it a *name* (perhaps CodiMD, but could be anything) and a *Redirection-URI*. The Redirection-URI will be `\<your-codimd-url\>/auth/oauth2/callback`. Click <kbd>Add</kbd>.
![Adding a client to Nextcloud](../../images/auth/nextcloud-oauth2-2-client-add.png)
4. You'll now see a line containing a *client identifier* and a *Secret*.
![Successfully added OAuth2-client](../../images/auth/nextcloud-oauth2-3-clientid-secret.png)
5. That's it for Nextcloud, the rest is configured in your CodiMD `config.json` or via the `CMD_` environment variables!
6. Add the Client ID and Client Secret to your `config.json` file or pass them as environment variables. Make sure you also replace `<your-nextcloud-domain>` with the right domain name.
* `config.json`:
```javascript
{
"production": {
"oauth2": {
"clientID": "ii4p1u3jz7dXXXXXXXXXXXXXXX",
"clientSecret": "mqzzx6fydbXXXXXXXXXXXXXXXX",
"authorizationURL": "https://<your-nextcloud-domain>/apps/oauth2/authorize",
"tokenURL": "https://<your-nextcloud-domain>/apps/oauth2/api/v1/token",
"userProfileURL": "https://<your-nextcloud-domain>/ocs/v2.php/cloud/user?format=json",
"userProfileUsernameAttr": "ocs.data.id",
"userProfileDisplayNameAttr": "ocs.data.display-name",
"userProfileEmailAttr": "ocs.data.email"
}
}
}
```
* environment variables:
```sh
CMD_OAUTH2_CLIENT_ID=ii4p1u3jz7dXXXXXXXXXXXXXXX
CMD_OAUTH2_CLIENT_SECRET=mqzzx6fydbXXXXXXXXXXXXXXXX
CMD_OAUTH2_AUTHORIZATION_URL=https://<your-nextcloud-domain>/apps/oauth2/authorize
CMD_OAUTH2_TOKEN_URL=https://<your-nextcloud-domain>/apps/oauth2/api/v1/token
CMD_OAUTH2_USER_PROFILE_URL=https://<your-nextcloud-domain>/ocs/v2.php/cloud/user?format=json
CMD_OAUTH2_USER_PROFILE_USERNAME_ATTR=ocs.data.id
CMD_OAUTH2_USER_PROFILE_DISPLAY_NAME_ATTR=ocs.data.display-name
CMD_OAUTH2_USER_PROFILE_EMAIL_ATTR=ocs.data.email
```

12
docs/guides/auth/oauth.md Normal file
View 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` |

View File

@ -0,0 +1,48 @@
Authentication guide - SAML (OneLogin)
===
**Note:** *This guide was written before the renaming. Just replace `HackMD` with `CodiMD` in your mind :smile: thanks!*
1. Sign-in or sign-up for an OneLogin account. (available free trial for 2 weeks)
2. Go to the administration page.
3. Select the **APPS** menu and click on the **Add Apps**.
![onelogin-add-app](../../images/auth/onelogin-add-app.png)
4. Find "SAML Test Connector (SP)" for template of settings and select it.
![onelogin-select-template](../../images/auth/onelogin-select-template.png)
5. Edit display name and icons for OneLogin dashboard as you want, and click **SAVE**.
![onelogin-edit-app-name](../../images/auth/onelogin-edit-app-name.png)
6. After that other tabs will appear, click the **Configuration**, and fill out the below items, and click **SAVE**.
* RelayState: The base URL of your CodiMD, which is issuer. (last slash is not needed)
* ACS (Consumer) URL Validator: The callback URL of your CodiMD. (serverurl + /auth/saml/callback)
* ACS (Consumer) URL: same as above.
* Login URL: login URL(SAML requester) of your CopiMD. (serverurl + /auth/saml)
![onelogin-edit-sp-metadata](../../images/auth/onelogin-edit-sp-metadata.png)
7. The registration is completed. Next, click **SSO** and copy or download the items below.
* X.509 Certificate: Click **View Details** and **DOWNLOAD** or copy the content of certificate ....(A)
* SAML 2.0 Endpoint (HTTP): Copy the URL ....(B)
![onelogin-copy-idp-metadata](../../images/auth/onelogin-copy-idp-metadata.png)
8. In your CodiMD server, create IdP certificate file from (A)
9. Add the IdP URL (B) and the Idp certificate file path to your config.json file or pass them as environment variables.
* `config.json`:
```javascript
{
"production": {
"saml": {
"idpSsoUrl": "https://*******.onelogin.com/trust/saml2/http-post/sso/******",
"idpCert": "/path/to/idp_cert.pem"
}
}
}
```
* environment variables
```sh
CMD_SAML_IDPSSOURL=https://*******.onelogin.com/trust/saml2/http-post/sso/******
CMD_SAML_IDPCERT=/path/to/idp_cert.pem
```
10. Try sign-in with SAML from your CodiMD sign-in button or OneLogin dashboard (like the screenshot below).
![onelogin-use-dashboard](../../images/auth/onelogin-use-dashboard.png)

85
docs/guides/auth/saml.md Normal file
View File

@ -0,0 +1,85 @@
Authentication guide - SAML
===
**Note:** *This guide was written before the renaming. Just replace `HackMD` with `CodiMD` in your mind :smile: thanks!*
The basic procedure is the same as the case of OneLogin which is mentioned in [OneLogin-Guide](./saml-onelogin.md). If you want to match your IdP, you can use more configurations as below.
* If your IdP accepts metadata XML of the service provider to ease configuration, use this url to download metadata XML.
* {{your-serverurl}}/auth/saml/metadata
* _Note: If not accessible from IdP, download to local once and upload to IdP._
* Change the value of `issuer`, `identifierFormat` to match your IdP.
* `issuer`: A unique id to identify the application to the IdP, which is the base URL of your CodiMD as default
* `identifierFormat`: A format of unique id to identify the user of IdP, which is the format based on email address as default. It is recommend that you use as below.
* urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress (default)
* urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified
* `config.json`:
```javascript
{
"production": {
"saml": {
/* omitted */
"issuer": "mycodimd"
"identifierFormat": "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"
}
}
}
```
* environment variables
```
CMD_SAML_ISSUER=mycodimd
CMD_SAML_IDENTIFIERFORMAT=urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified
```
* Change mapping of attribute names to customize the displaying user name and email address to match your IdP.
* `attribute`: A dictionary to map attribute names
* `attribute.id`: A primary key of user table for your CodiMD
* `attribute.username`: Attribute name of displaying user name on CodiMD
* `attribute.email`: Attribute name of email address, which will be also used for Gravatar
* _Note: Default value of all attributes is NameID of SAML response, which is email address if `identifierFormat` is default._
* `config.json`:
```javascript
{
"production": {
"saml": {
/* omitted */
"attribute": {
"id": "sAMAccountName",
"username": "displayName",
"email": "mail"
}
}
}
}
```
* environment variables
```sh
CMD_SAML_ATTRIBUTE_ID=sAMAccountName
CMD_SAML_ATTRIBUTE_USERNAME=nickName
CMD_SAML_ATTRIBUTE_EMAIL=mail
```
* If you want to control permission by group membership, add group attribute name and required group (allowed) or external group (not allowed).
* `groupAttribute`: An attribute name of group membership
* `requiredGroups`: Group names array for allowed access to CodiMD. Use vertical bar to separate for environment variables.
* `externalGroups`: Group names array for not allowed access to CodiMD. Use vertical bar to separate for environment variables.
* _Note: Evaluates `externalGroups` first_
* `config.json`:
```javascript
{
"production": {
"saml": {
/* omitted */
"groupAttribute": "memberOf",
"requiredGroups": [ "codimd-users", "board-members" ],
"externalGroups": [ "temporary-staff" ]
}
}
}
```
* environment variables
```sh
CMD_SAML_GROUPATTRIBUTE=memberOf
CMD_SAML_REQUIREDGROUPS=codimd-users|board-members
CMD_SAML_EXTERNALGROUPS=temporary-staff
```

View File

@ -0,0 +1,40 @@
Authentication guide - Twitter
===
**Note:** *This guide was written before the renaming. Just replace `HackMD` with `CodiMD` in your mind :smile: thanks!*
1. Sign-in or sign-up for a Twitter account
2. Go to the Twitter Application management page [here](https://apps.twitter.com/)
3. Click on the **Create New App** button to create a new Twitter app:
![create-twitter-app](../../images/auth/create-twitter-app.png)
4. Fill out the create application form, check the developer agreement box, and click **Create Your Twitter Application**
![register-twitter-application](../../images/auth/register-twitter-application.png)
*Note: you may have to register your phone number with Twitter to create a Twitter application*
To do this Click your profile icon --> Settings and privacy --> Mobile --> Select Country/region --> Enter phone number --> Click Continue
5. After you receive confirmation that the Twitter application was created, click **Keys and Access Tokens**
![twitter-app-confirmation](../../images/auth/twitter-app-confirmation.png)
6. Obtain your Twitter Consumer Key and Consumer Secret
![twitter-app-keys](../../images/auth/twitter-app-keys.png)
7. Add your Consumer Key and Consumer Secret to your `config.json` file or pass them as environment variables:
* `config.json`:
```javascript
{
"production": {
"twitter": {
"consumerKey": "esTCJFXXXXXXXXXXXXXXXXXXX",
"consumerSecret": "zpCs4tU86pRVXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
}
}
}
```
* environment variables:
```sh
CMD_TWITTER_CONSUMERKEY=esTCJFXXXXXXXXXXXXXXXXXXX
CMD_TWITTER_CONSUMERSECRET=zpCs4tU86pRVXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
```

View File

@ -0,0 +1,131 @@
Pad migration guide from etherpad-lite
===
The goal of this migration is to do a "dumb" import from all the pads in Etherpad, to notes in
CodiMD. In particular, the url locations of the pads in Etherpad will be lost. Furthermore, any
metadata in Etherpad, such as revisions, author data and also formatted text will not be migrated
to CodiMD (only the plain text contents).
Note that this guide is not really meant as a support guide. I migrated my own Etherpad to CodiMD,
and it turned out to be quite easy in my opinion. In this guide I share my experience. Stuff may
require some creativity to work properly in your case. When I wrote this guide, I was using
[Etherpad 1.7.0] and [CodiMD 1.2.1]. Good luck!
[Etherpad 1.7.0]: https://github.com/ether/etherpad-lite/tree/1.7.0
[CodiMD 1.2.1]: https://github.com/codimd/server/tree/1.2.1
## 0. Requirements
- `curl`
- running Etherpad server
- running CodiMD server
- [codimd-cli]
[codimd-cli]: https://github.com/codimd/cli/blob/master/bin/codimd
## 1. Retrieve the list of pads
First, compose a list of all the pads that you want to have migrated from your Etherpad. Other than
the admin interface, Etherpad does not have a dedicated function to dump a list of all the pads.
However, the Etherpad wiki explains how to list all the pads by [talking directly to the
database][howtolistallpads].
You will end up with a file containing a pad name on each line:
```
date-ideas
groceries
london
weddingchecklist
(...)
```
[howtolistallpads]: https://github.com/ether/etherpad-lite/wiki/How-to-list-all-pads/49701ecdcbe07aea7ad27ffa23aed0d99c2e17db
## 2. Run the migration
Download [codimd-cli] and put the script in the same directory as the file containing the pad names.
Add to this directory the file listed below, I called it `migrate-etherpad.sh`. Modify at least the
configuration settings `ETHERPAD_SERVER` and `CODIMD_SERVER`.
```shell
#!/bin/sh
# migrate-etherpad.sh
#
# Description: Migrate pads from etherpad to codimd
# Author: Daan Sprenkels <hello@dsprenkels.com>
# This script uses the codimd command line script[1] to import a list of pads from
# [1]: https://github.com/codimd/cli/blob/master/bin/codimd
# The base url to where etherpad is hosted
ETHERPAD_SERVER="https://etherpad.example.com"
# The base url where codimd is hosted
CODIMD_SERVER="https://codimd.example.com"
# Write a list of pads and the urls which they were migrated to
REDIRECTS_FILE="redirects.txt"
# Fail if not called correctly
if (( $# != 1 )); then
echo "Usage: $0 PAD_NAMES_FILE"
exit 2
fi
# Do the migration
for PAD_NAME in $1; do
# Download the pad
PAD_FILE="$(mktemp)"
curl "$ETHERPAD_SERVER/p/$PAD_NAME/export/txt" >"$PAD_FILE"
# Import the pad into codimd
OUTPUT="$(./codimd import "$PAD_FILE")"
echo "$PAD_NAME -> $OUTPUT" >>"$REDIRECTS_FILE"
done
```
Call this file like this:
```shell
./migrate-etherpad.sh pad_names.txt
```
This will download all the pads in `pad_names.txt` and put them on CodiMD. They will get assigned
random ids, so you won't be able to find them. The script will save the mappings to a file though
(in my case `redirects.txt`). You can use this file to redirect your users when they visit your
etherpad using a `301 Permanent Redirect` status code (see the next section).
## 3. Setup redirects (optional)
I got a `redirects.txt` file that looked a bit like this:
```
date-ideas -> Found. Redirecting to https://codimd.example.com/mPt0KfiKSBOTQ3mNcdfn
groceries -> Found. Redirecting to https://codimd.example.com/UukqgwLfhYyUUtARlcJ2_y
london -> Found. Redirecting to https://codimd.example.com/_d3wa-BE8t4Swv5w7O2_9R
weddingchecklist -> Found. Redirecting to https://codimd.example.com/XcQGqlBjl0u40wfT0N8TzQ
(...)
```
Using some `sed` magic, I changed it to an nginx config snippet:
```
location = /p/date-ideas {
return 301 https://codimd.example.com/mPt0M1KfiKSBOTQ3mNcdfn;
}
location = /p/groceries {
return 301 https://codimd.example.com/UukqgwLfhYyUUtARlcJ2_y;
}
location = /p/london {
return 301 https://codimd.example.com/_d3wa-BE8t4Swv5w7O2_9R;
}
location = /p/weddingchecklist {
return 301 https://codimd.example.com/XcQGqlBjl0u40wfT0N8TzQ;
}
```
I put this file into my `etherpad.example.com` nginx config, such that all the users would be
redirected accordingly.

View File

@ -0,0 +1,56 @@
Migrations and Notable Changes
===
## Migrating to 1.4.0
We dropped support for node 6 with this version. If you have any trouble running this version, please double check that you are running at least node 8!
## Migrating to 1.3.2
This is not a breaking change, but to stay up to date with the community
repository, you may need to update a few urls. This is not a breaking change.
See more at [issue #10](https://github.com/codimd/server/issues/10)
**Native setup using git:**
Change the upstream remote using `git remote set-url origin https://github.com/codimd/server.git`.
**Docker:**
When you use our [container repository](https://github.com/codimd/container)
(which was previously `codimd-container`) all you can simply run `git pull` and
your `docker-compose.yml` will be updated.
When you setup things yourself, make sure you use the new image:
[`quay.io/codimd/server`](https://quay.io/repository/codimd/server?tab=tags).
**Heroku:**
All you need to do is [disconnect GitHub](https://devcenter.heroku.com/articles/github-integration#disconnecting-from-github)
and [reconnect it](https://devcenter.heroku.com/articles/github-integration#enabling-github-integration)
with this new repository.
Or you can use our Heroku button and redeploy your instance and link the old
database again.
## Migrating to 1.1.0
We deprecated the older lower case config style and moved on to camel case style. Please have a look at the current `config.json.example` and check the warnings on startup.
*Notice: This is not a breaking change right now but will be in the future*
## Migrating to 0.5.0
[migration-to-0.5.0 migration tool](https://github.com/hackmdio/migration-to-0.5.0)
We don't use LZString to compress socket.io data and DB data after version 0.5.0.
Please run the migration tool if you're upgrading from the old version.
## Migrating to 0.4.0
[migration-to-0.4.0 migration tool](https://github.com/hackmdio/migration-to-0.4.0)
We've dropped MongoDB after version 0.4.0.
So here is the migration tool for you to transfer the old DB data to the new DB.
This tool is also used for official service.

View File

@ -0,0 +1,85 @@
Minio Guide for CodiMD
===
**Note:** *This guide was written before the renaming. Just replace `HackMD` with `CodiMD` in your mind :smile: thanks!*
1. First of all you need to setup Minio itself.
Please refer to the [official Minio docs](https://docs.minio.io/) for an
production setup.
For checking it out and development purposes a non-persistent setup is enough:
```sh
docker run --name test-minio --rm -d -p 9000:9000 minio/minio server /data
```
*Please notice this is not for productive use as all your data gets lost
when you stop this container*
2. Next step is to get the credentials form the container:
```sh
docker logs test-minio
```
![docker logs](../images/minio-image-upload/docker-logs.png)
3. Open http://localhost:9000 and login with the shown credentials.
![minio default view](../images/minio-image-upload/default-view.png)
4. Create a bucket for CodiMD
![minio create bucket](../images/minio-image-upload/create-bucket.png)
5. Add a policy for the prefix `uploads` and make it read-only.
![minio edit policy](../images/minio-image-upload/open-edit-policy.png)
*Open policy editor*
![minio policy adding](../images/minio-image-upload/create-policy.png)
*Add policy for uploads*
6. Set credentials and configs for Minio in CodiMD's `config.json`
```JSON
"minio": {
"accessKey": "888MXJ7EP4XXXXXXXXX",
"secretKey": "yQS2EbM1Y6IJrp/1BUKWq2/XXXXXXXXXXXXXXX",
"endPoint": "localhost",
"port": 9000,
"secure": false
}
```
*You have to use different values for `endpoint` and `port` for a production
setup. Keep in mind the `endpoint`-address has to be public accessible from
your browser.*
7. Set bucket name
```JSON
"s3bucket": "codimd"
```
8. Set upload type.
```JSON
"imageuploadtype": "minio"
```
9. Review your config.
```json
{
// all your other config…
"minio": {
"accessKey": "888MXJ7EP4XXXXXXXXX",
"secretKey": "yQS2EbM1Y6IJrp/1BUKWq2/XXXXXXXXXXXXXXX",
"endPoint": "localhost",
"port": 9000,
"secure": false
},
"s3bucket": "codimd",
"imageuploadtype": "minio"
}
```

View File

@ -0,0 +1,17 @@
Setup your terms of use
===
To setup your terms of use, you need to provide a document called `terms-of-use.md` which contains them. Of course written in Markdown.
It has to be provided under `./public/docs/` and will be automatically turned into a CodiMD document. It will also automatically updated as soon as you change the document on disk.
As soon as the file exists a link will show up in the bottom part along with the release notes and link to them.
Setup your privacy policy
===
To add a privacy policy you can use the same technique as for the terms of use. The main difference is that the document is called `privacy.md`.
See our example file `./public/docs/privacy.md.example` container some useful hints for writing your own privacy policy.
As with the terms of use, a link to the privacy notices will show up in the area where the release notes are provided on the index page.

View File

@ -1,16 +1,19 @@
# Guide - Setup HackMD 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!*
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
{
@ -30,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
{
@ -63,18 +66,18 @@
{
"production": {
...
"imageUploadType": "s3",
"imageuploadtype": "s3",
"s3": {
"accessKeyId": "YOUR_S3_ACCESS_KEY_ID",
"secretAccessKey": "YOUR_S3_ACCESS_KEY",
"region": "YOUR_S3_REGION", // example: ap-northeast-1
"bucket": "YOUR_S3_BUCKET_NAME"
}
"region": "YOUR_S3_REGION" // example: ap-northeast-1
},
"s3bucket": "YOUR_S3_BUCKET_NAME"
}
}
```
9. In additional to edit `config.json` directly, you could also try [environment variable](https://github.com/hackmdio/hackmd#environment-variables-will-overwrite-other-server-configs).
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
View 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).*

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 234 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 198 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 187 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 159 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

Before

Width:  |  Height:  |  Size: 53 KiB

After

Width:  |  Height:  |  Size: 53 KiB

View File

Before

Width:  |  Height:  |  Size: 70 KiB

After

Width:  |  Height:  |  Size: 70 KiB

View File

Before

Width:  |  Height:  |  Size: 69 KiB

After

Width:  |  Height:  |  Size: 69 KiB

View File

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 54 KiB

View File

Before

Width:  |  Height:  |  Size: 89 KiB

After

Width:  |  Height:  |  Size: 89 KiB

View File

Before

Width:  |  Height:  |  Size: 98 KiB

After

Width:  |  Height:  |  Size: 98 KiB

View File

@ -0,0 +1,35 @@
Developer Certificate of Origin
Version 1.1
Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
660 York Street, Suite 102,
San Francisco, CA 94110 USA
Everyone is permitted to copy and distribute verbatim copies of this
license document, but changing it is not allowed.
Developer's Certificate of Origin 1.1
By making a contribution to this project, I certify that:
(a) The contribution was created in whole or in part by me and I
have the right to submit it under the open source license
indicated in the file; or
(b) The contribution is based upon previous work that, to the best
of my knowledge, is covered under an appropriate open source
license and I have the right under that license to submit that
work with modifications, whether created in whole or in part
by me, under the same open source license (unless I am
permitted to submit under a different license), as indicated
in the file; or
(c) The contribution was provided directly to me by some other
person who certified (a), (b) or (c) and I have not modified
it.
(d) I understand and agree that this project and the contribution
are public and that a record of the contribution (including all
personal information I submit with it, including my sign-off) is
maintained indefinitely and may be redistributed consistent with
this project or the open source license(s) involved.

6
docs/setup/cloudron.md Normal file
View 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)

View File

@ -0,0 +1,14 @@
LinuxServer.io CodiMD Image
===
[![LinuxServer.io Discord](https://img.shields.io/discord/354974912613449730.svg?logo=discord&label=LSIO%20Discord&style=flat-square)](https://discord.gg/YWrKVTn)[![container version badge](https://images.microbadger.com/badges/version/linuxserver/codimd.svg)](https://microbadger.com/images/linuxserver/codimd "Get your own version badge on microbadger.com")[![container image size badge](https://images.microbadger.com/badges/image/linuxserver/codimd.svg)](https://microbadger.com/images/linuxserver/codimd "Get your own version badge on microbadger.com")![Docker Pulls](https://img.shields.io/docker/pulls/linuxserver/codimd.svg)![Docker Stars](https://img.shields.io/docker/stars/linuxserver/codimd.svg)[![Build Status](https://ci.linuxserver.io/buildStatus/icon?job=Docker-Pipeline-Builders/docker-codimd/master)](https://ci.linuxserver.io/job/Docker-Pipeline-Builders/job/docker-codimd/job/master/)[![LinuxServer.io CI summary](https://lsio-ci.ams3.digitaloceanspaces.com/linuxserver/codimd/latest/badge.svg)](https://lsio-ci.ams3.digitaloceanspaces.com/linuxserver/codimd/latest/index.html)
[LinuxServer.io](https://linuxserver.io) have created an Ubuntu-based multi-arch container image for x86-64, arm64 and armhf which supports PDF export from all architectures using [PhantomJS](https://phantomjs.org/).
- It supports all the environment variables detailed in the [configuration documentation](../configuration-env-vars.md) to modify it according to your needs.
- It gets rebuilt on new releases from CodiMD and also weekly if necessary to update any other package changes in the underlying container, making it easy to keep your CodiMD instance up to date.
- It also details how to easily [utilize Docker networking to reverse proxy](https://github.com/linuxserver/docker-codimd/#application-setup) CodiMD using their [LetsEncrypt docker image](https://github.com/linuxserver/docker-letsencrypt)
In order to contribute check the LinuxServer.io [GitHub repository](https://github.com/linuxserver/docker-codimd/) for CodiMD.
And to find all tags and versions of the image, check the [Docker Hub repository](https://hub.docker.com/r/linuxserver/codimd).

23
docs/setup/docker.md Normal file
View File

@ -0,0 +1,23 @@
CodiMD Docker Image
===
[![Try in PWD](https://cdn.rawgit.com/play-with-docker/stacks/cff22438/assets/images/button.png)](http://play-with-docker.com?stack=https://github.com/codimd/container/raw/master/docker-compose.yml&stack_name=codimd)
**Debian-based version:**
[![Docker Repository on Quay](https://quay.io/repository/codimd/server/status "Docker Repository on Quay")](https://quay.io/repository/codimd/server)
**Alpine-based version:**
[![Docker Repository on Quay](https://quay.io/repository/codimd/server/status "Docker Repository on Quay")](https://quay.io/repository/codimd/server)
The easiest way to setup CodiMD using docker are using the following three commands:
```sh
git clone https://github.com/codimd/container.git codimd-container
cd codimd-container
docker-compose up
```
Read more about it in the [container repository](https://github.com/codimd/container).

7
docs/setup/heroku.md Normal file
View 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
View 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).

View File

@ -0,0 +1,39 @@
Manual Installation
===
## Requirements on your server
- Node.js 8.5 or up
- Database (PostgreSQL, MySQL, MariaDB, SQLite, MSSQL) use charset `utf8`
- npm (and its dependencies, [node-gyp](https://github.com/nodejs/node-gyp#installation))
- yarn
- Bash (for the setup script)
- For **building** CodiMD we recommend to use a machine with at least **2GB** RAM
## Instructions
1. Check if you meet the [requirements at the top of this document](#requirements-on-your-server).
2. Clone this repository (preferred) or download a release and unzip it.
3. Enter the directory and type `bin/setup`, which will install npm dependencies and create configs.
4. Setup the configs, see more below
5. Setup environment variables which will overwrite the configs
6. Build front-end bundle by `npm run build` (use `npm run dev` if you are in development)
7. Modify the file named `.sequelizerc`, change the value of the variable `url` with your db connection string
For example: `postgres://username:password@localhost:5432/codimd`
8. It is recommended to start your server manually once: `npm start --production`, this way it's easier to see warnings or errors that might occur (leave out `--production` for development).
9. Run the server as you like (node, forever, pm2, SystemD, Init-Scripts)
## How to upgrade your installation
If you are upgrading CodiMD from an older version, follow these steps:
1. Check if you meet the [requirements at the top of this document](#requirements-on-your-server).
2. Verify which version you were running before and take a look at [migrations and breaking changes](../guides/migrations-and-breaking-changes.md) to see if additional steps, or configuration changes are necessary!
3. Fully stop your old CodiMD server.
4. `git pull` or unzip a new release in the directory.
5. Run `bin/setup`. This will take care of installing dependencies. It is safe to run on an existing installation.
6. Build front-end bundle by `npm run build` (use `npm run dev` if you are in development).
7. It is recommended to start your server manually once: `npm start --production`, this way it's easier to see warnings or errors that might occur (leave out `--production` for development).
8. You can now restart the CodiMD server!

161
docs/slide-options.md Normal file
View 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
---
```

View File

@ -1,190 +0,0 @@
//auth
//external modules
var passport = require('passport');
var FacebookStrategy = require('passport-facebook').Strategy;
var TwitterStrategy = require('passport-twitter').Strategy;
var GithubStrategy = require('passport-github').Strategy;
var GitlabStrategy = require('passport-gitlab2').Strategy;
var DropboxStrategy = require('passport-dropbox-oauth2').Strategy;
var GoogleStrategy = require('passport-google-oauth20').Strategy;
var LdapStrategy = require('passport-ldapauth');
var LocalStrategy = require('passport-local').Strategy;
var validator = require('validator');
//core
var config = require('./config.js');
var logger = require("./logger.js");
var models = require("./models");
function callback(accessToken, refreshToken, profile, done) {
//logger.info(profile.displayName || profile.username);
var stringifiedProfile = JSON.stringify(profile);
models.User.findOrCreate({
where: {
profileid: profile.id.toString()
},
defaults: {
profile: stringifiedProfile,
accessToken: accessToken,
refreshToken: refreshToken
}
}).spread(function (user, created) {
if (user) {
var needSave = false;
if (user.profile != stringifiedProfile) {
user.profile = stringifiedProfile;
needSave = true;
}
if (user.accessToken != accessToken) {
user.accessToken = accessToken;
needSave = true;
}
if (user.refreshToken != refreshToken) {
user.refreshToken = refreshToken;
needSave = true;
}
if (needSave) {
user.save().then(function () {
if (config.debug)
logger.info('user login: ' + user.id);
return done(null, user);
});
} else {
if (config.debug)
logger.info('user login: ' + user.id);
return done(null, user);
}
}
}).catch(function (err) {
logger.error('auth callback failed: ' + err);
return done(err, null);
});
}
//facebook
if (config.facebook) {
module.exports = passport.use(new FacebookStrategy({
clientID: config.facebook.clientID,
clientSecret: config.facebook.clientSecret,
callbackURL: config.serverurl + '/auth/facebook/callback'
}, callback));
}
//twitter
if (config.twitter) {
passport.use(new TwitterStrategy({
consumerKey: config.twitter.consumerKey,
consumerSecret: config.twitter.consumerSecret,
callbackURL: config.serverurl + '/auth/twitter/callback'
}, callback));
}
//github
if (config.github) {
passport.use(new GithubStrategy({
clientID: config.github.clientID,
clientSecret: config.github.clientSecret,
callbackURL: config.serverurl + '/auth/github/callback'
}, callback));
}
//gitlab
if (config.gitlab) {
passport.use(new GitlabStrategy({
baseURL: config.gitlab.baseURL,
clientID: config.gitlab.clientID,
clientSecret: config.gitlab.clientSecret,
callbackURL: config.serverurl + '/auth/gitlab/callback'
}, callback));
}
//dropbox
if (config.dropbox) {
passport.use(new DropboxStrategy({
apiVersion: '2',
clientID: config.dropbox.clientID,
clientSecret: config.dropbox.clientSecret,
callbackURL: config.serverurl + '/auth/dropbox/callback'
}, callback));
}
//google
if (config.google) {
passport.use(new GoogleStrategy({
clientID: config.google.clientID,
clientSecret: config.google.clientSecret,
callbackURL: config.serverurl + '/auth/google/callback'
}, callback));
}
// ldap
if (config.ldap) {
passport.use(new LdapStrategy({
server: {
url: config.ldap.url || null,
bindDn: config.ldap.bindDn || null,
bindCredentials: config.ldap.bindCredentials || null,
searchBase: config.ldap.searchBase || null,
searchFilter: config.ldap.searchFilter || null,
searchAttributes: config.ldap.searchAttributes || null,
tlsOptions: config.ldap.tlsOptions || null
},
},
function(user, done) {
var profile = {
id: 'LDAP-' + user.uidNumber,
username: user.uid,
displayName: user.displayName,
emails: user.mail ? [user.mail] : [],
avatarUrl: null,
profileUrl: null,
provider: 'ldap',
}
var stringifiedProfile = JSON.stringify(profile);
models.User.findOrCreate({
where: {
profileid: profile.id.toString()
},
defaults: {
profile: stringifiedProfile,
}
}).spread(function (user, created) {
if (user) {
var needSave = false;
if (user.profile != stringifiedProfile) {
user.profile = stringifiedProfile;
needSave = true;
}
if (needSave) {
user.save().then(function () {
if (config.debug)
logger.info('user login: ' + user.id);
return done(null, user);
});
} else {
if (config.debug)
logger.info('user login: ' + user.id);
return done(null, user);
}
}
}).catch(function (err) {
logger.error('ldap auth failed: ' + err);
return done(err, null);
});
}));
}
// email
if (config.email) {
passport.use(new LocalStrategy({
usernameField: 'email'
},
function(email, password, done) {
if (!validator.isEmail(email)) return done(null, false);
models.User.findOne({
where: {
email: email
}
}).then(function (user) {
if (!user) return done(null, false);
if (!user.verifyPassword(password)) return done(null, false);
return done(null, user);
}).catch(function (err) {
logger.error(err);
return done(err);
});
}));
}

View File

@ -1,219 +0,0 @@
// external modules
var fs = require('fs');
var path = require('path');
// configs
var env = process.env.NODE_ENV || 'development';
var config = require(path.join(__dirname, '..', 'config.json'))[env];
var debug = process.env.DEBUG ? (process.env.DEBUG === 'true') : ((typeof config.debug === 'boolean') ? config.debug : (env === 'development'));
// url
var domain = process.env.DOMAIN || process.env.HMD_DOMAIN || config.domain || '';
var urlpath = process.env.URL_PATH || process.env.HMD_URL_PATH || config.urlpath || '';
var port = process.env.PORT || process.env.HMD_PORT || config.port || 3000;
var alloworigin = process.env.HMD_ALLOW_ORIGIN ? process.env.HMD_ALLOW_ORIGIN.split(',') : (config.alloworigin || ['localhost']);
var usessl = !!config.usessl;
var protocolusessl = (usessl === true && typeof process.env.HMD_PROTOCOL_USESSL === 'undefined' && typeof config.protocolusessl === 'undefined')
? true : (process.env.HMD_PROTOCOL_USESSL ? (process.env.HMD_PROTOCOL_USESSL === 'true') : !!config.protocolusessl);
var urladdport = process.env.HMD_URL_ADDPORT ? (process.env.HMD_URL_ADDPORT === 'true') : !!config.urladdport;
var usecdn = process.env.HMD_USECDN ? (process.env.HMD_USECDN === 'true') : ((typeof config.usecdn === 'boolean') ? config.usecdn : true);
var allowanonymous = process.env.HMD_ALLOW_ANONYMOUS ? (process.env.HMD_ALLOW_ANONYMOUS === 'true') : ((typeof config.allowanonymous === 'boolean') ? config.allowanonymous : true);
var allowfreeurl = process.env.HMD_ALLOW_FREEURL ? (process.env.HMD_ALLOW_FREEURL === 'true') : !!config.allowfreeurl;
var permissions = ['editable', 'limited', 'locked', 'protected', 'private'];
if (allowanonymous) {
permissions.unshift('freely');
}
var defaultpermission = process.env.HMD_DEFAULT_PERMISSION || config.defaultpermission;
defaultpermission = permissions.indexOf(defaultpermission) != -1 ? defaultpermission : 'editable';
// db
var dburl = process.env.HMD_DB_URL || process.env.DATABASE_URL || config.dburl;
var db = config.db || {};
// ssl path
var sslkeypath = config.sslkeypath || '';
var sslcertpath = config.sslcertpath || '';
var sslcapath = config.sslcapath || '';
var dhparampath = config.dhparampath || '';
// other path
var tmppath = config.tmppath || './tmp';
var defaultnotepath = config.defaultnotepath || './public/default.md';
var docspath = config.docspath || './public/docs';
var indexpath = config.indexpath || './public/views/index.ejs';
var hackmdpath = config.hackmdpath || './public/views/hackmd.ejs';
var errorpath = config.errorpath || './public/views/error.ejs';
var prettypath = config.prettypath || './public/views/pretty.ejs';
var slidepath = config.slidepath || './public/views/slide.ejs';
// session
var sessionname = config.sessionname || 'connect.sid';
var sessionsecret = config.sessionsecret || 'secret';
var sessionlife = config.sessionlife || 14 * 24 * 60 * 60 * 1000; //14 days
// static files
var staticcachetime = config.staticcachetime || 1 * 24 * 60 * 60 * 1000; // 1 day
// socket.io
var heartbeatinterval = config.heartbeatinterval || 5000;
var heartbeattimeout = config.heartbeattimeout || 10000;
// document
var documentmaxlength = config.documentmaxlength || 100000;
// image upload setting, available options are imgur/s3/filesystem
var imageUploadType = process.env.HMD_IMAGE_UPLOAD_TYPE || config.imageUploadType || 'imgur';
config.s3 = config.s3 || {};
var s3 = {
accessKeyId: process.env.HMD_S3_ACCESS_KEY_ID || config.s3.accessKeyId,
secretAccessKey: process.env.HMD_S3_SECRET_ACCESS_KEY || config.s3.secretAccessKey,
region: process.env.HMD_S3_REGION || config.s3.region
}
var s3bucket = process.env.HMD_S3_BUCKET || config.s3.bucket;
// auth
var facebook = (process.env.HMD_FACEBOOK_CLIENTID && process.env.HMD_FACEBOOK_CLIENTSECRET) ? {
clientID: process.env.HMD_FACEBOOK_CLIENTID,
clientSecret: process.env.HMD_FACEBOOK_CLIENTSECRET
} : config.facebook || false;
var twitter = (process.env.HMD_TWITTER_CONSUMERKEY && process.env.HMD_TWITTER_CONSUMERSECRET) ? {
consumerKey: process.env.HMD_TWITTER_CONSUMERKEY,
consumerSecret: process.env.HMD_TWITTER_CONSUMERSECRET
} : config.twitter || false;
var github = (process.env.HMD_GITHUB_CLIENTID && process.env.HMD_GITHUB_CLIENTSECRET) ? {
clientID: process.env.HMD_GITHUB_CLIENTID,
clientSecret: process.env.HMD_GITHUB_CLIENTSECRET
} : config.github || false;
var gitlab = (process.env.HMD_GITLAB_CLIENTID && process.env.HMD_GITLAB_CLIENTSECRET) ? {
baseURL: process.env.HMD_GITLAB_BASEURL,
clientID: process.env.HMD_GITLAB_CLIENTID,
clientSecret: process.env.HMD_GITLAB_CLIENTSECRET
} : config.gitlab || false;
var dropbox = (process.env.HMD_DROPBOX_CLIENTID && process.env.HMD_DROPBOX_CLIENTSECRET) ? {
clientID: process.env.HMD_DROPBOX_CLIENTID,
clientSecret: process.env.HMD_DROPBOX_CLIENTSECRET
} : (config.dropbox && config.dropbox.clientID && config.dropbox.clientSecret && config.dropbox) || false;
var google = (process.env.HMD_GOOGLE_CLIENTID && process.env.HMD_GOOGLE_CLIENTSECRET) ? {
clientID: process.env.HMD_GOOGLE_CLIENTID,
clientSecret: process.env.HMD_GOOGLE_CLIENTSECRET
} : (config.google && config.google.clientID && config.google.clientSecret && config.google) || false;
var ldap = config.ldap || ((
process.env.HMD_LDAP_URL ||
process.env.HMD_LDAP_BINDDN ||
process.env.HMD_LDAP_BINDCREDENTIALS ||
process.env.HMD_LDAP_TOKENSECRET ||
process.env.HMD_LDAP_SEARCHBASE ||
process.env.HMD_LDAP_SEARCHFILTER ||
process.env.HMD_LDAP_SEARCHATTRIBUTES ||
process.env.HMD_LDAP_TLS_CA ||
process.env.HMD_LDAP_PROVIDERNAME
) ? {} : false);
if (process.env.HMD_LDAP_URL)
ldap.url = process.env.HMD_LDAP_URL;
if (process.env.HMD_LDAP_BINDDN)
ldap.bindDn = process.env.HMD_LDAP_BINDDN;
if (process.env.HMD_LDAP_BINDCREDENTIALS)
ldap.bindCredentials = process.env.HMD_LDAP_BINDCREDENTIALS;
if (process.env.HMD_LDAP_TOKENSECRET)
ldap.tokenSecret = process.env.HMD_LDAP_TOKENSECRET;
if (process.env.HMD_LDAP_SEARCHBASE)
ldap.searchBase = process.env.HMD_LDAP_SEARCHBASE;
if (process.env.HMD_LDAP_SEARCHFILTER)
ldap.searchFilter = process.env.HMD_LDAP_SEARCHFILTER;
if (process.env.HMD_LDAP_SEARCHATTRIBUTES)
ldap.searchAttributes = process.env.HMD_LDAP_SEARCHATTRIBUTES;
if (process.env.HMD_LDAP_TLS_CA) {
var ca = {
ca: process.env.HMD_LDAP_TLS_CA.split(',')
}
ldap.tlsOptions = ldap.tlsOptions ? Object.assign(ldap.tlsOptions, ca) : ca;
if (Array.isArray(ldap.tlsOptions.ca) && ldap.tlsOptions.ca.length > 0) {
var i, len, results;
results = [];
for (i = 0, len = ldap.tlsOptions.ca.length; i < len; i++) {
results.push(fs.readFileSync(ldap.tlsOptions.ca[i], 'utf8'));
}
ldap.tlsOptions.ca = results;
}
}
if (process.env.HMD_LDAP_PROVIDERNAME) {
ldap.providerName = process.env.HMD_LDAP_PROVIDERNAME;
}
var imgur = process.env.HMD_IMGUR_CLIENTID || config.imgur || false;
var email = process.env.HMD_EMAIL ? (process.env.HMD_EMAIL === 'true') : !!config.email;
var allowemailregister = process.env.HMD_ALLOW_EMAIL_REGISTER ? (process.env.HMD_ALLOW_EMAIL_REGISTER === 'true') : ((typeof config.allowemailregister === 'boolean') ? config.allowemailregister : true);
function getserverurl() {
var url = '';
if (domain) {
var protocol = protocolusessl ? 'https://' : 'http://';
url = protocol + domain;
if (urladdport && ((usessl && port != 443) || (!usessl && port != 80)))
url += ':' + port;
}
if (urlpath)
url += '/' + urlpath;
return url;
}
var version = '0.5.0';
var minimumCompatibleVersion = '0.5.0';
var maintenance = true;
var cwd = path.join(__dirname, '..');
module.exports = {
version: version,
minimumCompatibleVersion: minimumCompatibleVersion,
maintenance: maintenance,
debug: debug,
urlpath: urlpath,
port: port,
alloworigin: alloworigin,
usessl: usessl,
serverurl: getserverurl(),
usecdn: usecdn,
allowanonymous: allowanonymous,
allowfreeurl: allowfreeurl,
defaultpermission: defaultpermission,
dburl: dburl,
db: db,
sslkeypath: path.join(cwd, sslkeypath),
sslcertpath: path.join(cwd, sslcertpath),
sslcapath: path.join(cwd, sslcapath),
dhparampath: path.join(cwd, dhparampath),
tmppath: path.join(cwd, tmppath),
defaultnotepath: path.join(cwd, defaultnotepath),
docspath: path.join(cwd, docspath),
indexpath: path.join(cwd, indexpath),
hackmdpath: path.join(cwd, hackmdpath),
errorpath: path.join(cwd, errorpath),
prettypath: path.join(cwd, prettypath),
slidepath: path.join(cwd, slidepath),
sessionname: sessionname,
sessionsecret: sessionsecret,
sessionlife: sessionlife,
staticcachetime: staticcachetime,
heartbeatinterval: heartbeatinterval,
heartbeattimeout: heartbeattimeout,
documentmaxlength: documentmaxlength,
facebook: facebook,
twitter: twitter,
github: github,
gitlab: gitlab,
dropbox: dropbox,
google: google,
ldap: ldap,
imgur: imgur,
email: email,
allowemailregister: allowemailregister,
imageUploadType: imageUploadType,
s3: s3,
s3bucket: s3bucket
};

161
lib/config/default.js Normal file
View File

@ -0,0 +1,161 @@
'use strict'
const os = require('os')
module.exports = {
domain: '',
urlPath: '',
host: '0.0.0.0',
port: 3000,
loglevel: 'info',
urlAddPort: false,
allowOrigin: ['localhost'],
useSSL: false,
hsts: {
enable: true,
maxAgeSeconds: 60 * 60 * 24 * 365,
includeSubdomains: true,
preload: true
},
csp: {
enable: true,
directives: {
},
addDefaults: true,
addDisqus: true,
addGoogleAnalytics: true,
upgradeInsecureRequests: 'auto',
reportURI: undefined
},
protocolUseSSL: false,
useCDN: true,
allowAnonymous: true,
allowAnonymousEdits: false,
allowFreeURL: false,
forbiddenNoteIDs: ['robots.txt', 'favicon.ico', 'api'],
defaultPermission: 'editable',
dbURL: '',
db: {},
// ssl path
sslKeyPath: '',
sslCertPath: '',
sslCAPath: '',
dhParamPath: '',
// other path
viewPath: './public/views',
tmpPath: os.tmpdir(),
defaultNotePath: './public/default.md',
docsPath: './public/docs',
uploadsPath: './public/uploads',
// session
sessionName: 'connect.sid',
sessionSecret: 'secret',
sessionSecretLen: 128,
sessionLife: 14 * 24 * 60 * 60 * 1000, // 14 days
staticCacheTime: 1 * 24 * 60 * 60 * 1000, // 1 day
// socket.io
heartbeatInterval: 5000,
heartbeatTimeout: 10000,
// too busy timeout
tooBusyLag: 70,
// document
documentMaxLength: 100000,
// image upload setting, available options are imgur/s3/filesystem/azure/lutim
imageUploadType: 'filesystem',
lutim: {
url: 'https://framapic.org/'
},
imgur: {
clientID: undefined
},
s3: {
accessKeyId: undefined,
secretAccessKey: undefined,
region: undefined
},
minio: {
accessKey: undefined,
secretKey: undefined,
endPoint: undefined,
secure: true,
port: 9000
},
s3bucket: undefined,
azure: {
connectionString: undefined,
container: undefined
},
// authentication
oauth2: {
providerName: undefined,
authorizationURL: undefined,
tokenURL: undefined,
clientID: undefined,
clientSecret: undefined
},
facebook: {
clientID: undefined,
clientSecret: undefined
},
twitter: {
consumerKey: undefined,
consumerSecret: undefined
},
github: {
clientID: undefined,
clientSecret: undefined
},
gitlab: {
baseURL: undefined,
clientID: undefined,
clientSecret: undefined,
scope: undefined,
version: 'v4'
},
mattermost: {
baseURL: undefined,
clientID: undefined,
clientSecret: undefined
},
dropbox: {
clientID: undefined,
clientSecret: undefined,
appKey: undefined
},
google: {
clientID: undefined,
clientSecret: undefined
},
ldap: {
providerName: undefined,
url: undefined,
bindDn: undefined,
bindCredentials: undefined,
searchBase: undefined,
searchFilter: undefined,
searchAttributes: undefined,
usernameField: undefined,
useridField: undefined,
tlsca: undefined
},
saml: {
idpSsoUrl: undefined,
idpCert: undefined,
issuer: undefined,
identifierFormat: 'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress',
disableRequestedAuthnContext: false,
groupAttribute: undefined,
externalGroups: [],
requiredGroups: [],
attribute: {
id: undefined,
username: undefined,
email: undefined
}
},
email: true,
allowEmailRegister: true,
allowGravatar: true,
allowPDFExport: true,
openID: false
}

17
lib/config/defaultSSL.js Normal file
View File

@ -0,0 +1,17 @@
'use strict'
const fs = require('fs')
function getFile (path) {
if (fs.existsSync(path)) {
return path
}
return undefined
}
module.exports = {
sslKeyPath: getFile('/run/secrets/key.pem'),
sslCertPath: getFile('/run/secrets/cert.pem'),
sslCAPath: getFile('/run/secrets/ca.pem') !== undefined ? [getFile('/run/secrets/ca.pem')] : [],
dhParamPath: getFile('/run/secrets/dhparam.pem')
}

View File

@ -0,0 +1,60 @@
'use strict'
const fs = require('fs')
const path = require('path')
const basePath = path.resolve('/var/run/secrets/')
function getSecret (secret) {
const filePath = path.join(basePath, secret)
if (fs.existsSync(filePath)) return fs.readFileSync(filePath)
return undefined
}
if (fs.existsSync(basePath)) {
module.exports = {
dbURL: getSecret('dbURL'),
sessionsecret: getSecret('sessionsecret'),
sslkeypath: getSecret('sslkeypath'),
sslcertpath: getSecret('sslcertpath'),
sslcapath: getSecret('sslcapath'),
dhparampath: getSecret('dhparampath'),
s3: {
accessKeyId: getSecret('s3_acccessKeyId'),
secretAccessKey: getSecret('s3_secretAccessKey')
},
azure: {
connectionString: getSecret('azure_connectionString')
},
facebook: {
clientID: getSecret('facebook_clientID'),
clientSecret: getSecret('facebook_clientSecret')
},
twitter: {
consumerKey: getSecret('twitter_consumerKey'),
consumerSecret: getSecret('twitter_consumerSecret')
},
github: {
clientID: getSecret('github_clientID'),
clientSecret: getSecret('github_clientSecret')
},
gitlab: {
clientID: getSecret('gitlab_clientID'),
clientSecret: getSecret('gitlab_clientSecret')
},
mattermost: {
clientID: getSecret('mattermost_clientID'),
clientSecret: getSecret('mattermost_clientSecret')
},
dropbox: {
clientID: getSecret('dropbox_clientID'),
clientSecret: getSecret('dropbox_clientSecret'),
appKey: getSecret('dropbox_appKey')
},
google: {
clientID: getSecret('google_clientID'),
clientSecret: getSecret('google_clientSecret')
},
imgur: getSecret('imgur_clientid')
}
}

16
lib/config/enum.js Normal file
View File

@ -0,0 +1,16 @@
'use strict'
exports.Environment = {
development: 'development',
production: 'production',
test: 'test'
}
exports.Permission = {
freely: 'freely',
editable: 'editable',
limited: 'limited',
locked: 'locked',
protected: 'protected',
private: 'private'
}

137
lib/config/environment.js Normal file
View File

@ -0,0 +1,137 @@
'use strict'
const { toBooleanConfig, toArrayConfig, toIntegerConfig } = require('./utils')
module.exports = {
sourceURL: process.env.CMD_SOURCE_URL,
domain: process.env.CMD_DOMAIN,
urlPath: process.env.CMD_URL_PATH,
host: process.env.CMD_HOST,
port: toIntegerConfig(process.env.CMD_PORT),
path: process.env.CMD_PATH,
loglevel: process.env.CMD_LOGLEVEL,
urlAddPort: toBooleanConfig(process.env.CMD_URL_ADDPORT),
useSSL: toBooleanConfig(process.env.CMD_USESSL),
hsts: {
enable: toBooleanConfig(process.env.CMD_HSTS_ENABLE),
maxAgeSeconds: toIntegerConfig(process.env.CMD_HSTS_MAX_AGE),
includeSubdomains: toBooleanConfig(process.env.CMD_HSTS_INCLUDE_SUBDOMAINS),
preload: toBooleanConfig(process.env.CMD_HSTS_PRELOAD)
},
csp: {
enable: toBooleanConfig(process.env.CMD_CSP_ENABLE),
reportURI: process.env.CMD_CSP_REPORTURI
},
protocolUseSSL: toBooleanConfig(process.env.CMD_PROTOCOL_USESSL),
allowOrigin: toArrayConfig(process.env.CMD_ALLOW_ORIGIN),
useCDN: toBooleanConfig(process.env.CMD_USECDN),
allowAnonymous: toBooleanConfig(process.env.CMD_ALLOW_ANONYMOUS),
allowAnonymousEdits: toBooleanConfig(process.env.CMD_ALLOW_ANONYMOUS_EDITS),
allowFreeURL: toBooleanConfig(process.env.CMD_ALLOW_FREEURL),
forbiddenNoteIDs: toArrayConfig(process.env.CMD_FORBIDDEN_NOTE_IDS),
defaultPermission: process.env.CMD_DEFAULT_PERMISSION,
dbURL: process.env.CMD_DB_URL,
sessionSecret: process.env.CMD_SESSION_SECRET,
sessionLife: toIntegerConfig(process.env.CMD_SESSION_LIFE),
tooBusyLag: toIntegerConfig(process.env.CMD_TOOBUSY_LAG),
imageUploadType: process.env.CMD_IMAGE_UPLOAD_TYPE,
imgur: {
clientID: process.env.CMD_IMGUR_CLIENTID
},
s3: {
accessKeyId: process.env.CMD_S3_ACCESS_KEY_ID,
secretAccessKey: process.env.CMD_S3_SECRET_ACCESS_KEY,
region: process.env.CMD_S3_REGION
},
minio: {
accessKey: process.env.CMD_MINIO_ACCESS_KEY,
secretKey: process.env.CMD_MINIO_SECRET_KEY,
endPoint: process.env.CMD_MINIO_ENDPOINT,
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,
container: process.env.CMD_AZURE_CONTAINER
},
facebook: {
clientID: process.env.CMD_FACEBOOK_CLIENTID,
clientSecret: process.env.CMD_FACEBOOK_CLIENTSECRET
},
twitter: {
consumerKey: process.env.CMD_TWITTER_CONSUMERKEY,
consumerSecret: process.env.CMD_TWITTER_CONSUMERSECRET
},
github: {
clientID: process.env.CMD_GITHUB_CLIENTID,
clientSecret: process.env.CMD_GITHUB_CLIENTSECRET
},
gitlab: {
baseURL: process.env.CMD_GITLAB_BASEURL,
clientID: process.env.CMD_GITLAB_CLIENTID,
clientSecret: process.env.CMD_GITLAB_CLIENTSECRET,
scope: process.env.CMD_GITLAB_SCOPE
},
mattermost: {
baseURL: process.env.CMD_MATTERMOST_BASEURL,
clientID: process.env.CMD_MATTERMOST_CLIENTID,
clientSecret: process.env.CMD_MATTERMOST_CLIENTSECRET
},
oauth2: {
providerName: process.env.CMD_OAUTH2_PROVIDERNAME,
baseURL: process.env.CMD_OAUTH2_BASEURL,
userProfileURL: process.env.CMD_OAUTH2_USER_PROFILE_URL,
userProfileUsernameAttr: process.env.CMD_OAUTH2_USER_PROFILE_USERNAME_ATTR,
userProfileDisplayNameAttr: process.env.CMD_OAUTH2_USER_PROFILE_DISPLAY_NAME_ATTR,
userProfileEmailAttr: process.env.CMD_OAUTH2_USER_PROFILE_EMAIL_ATTR,
tokenURL: process.env.CMD_OAUTH2_TOKEN_URL,
authorizationURL: process.env.CMD_OAUTH2_AUTHORIZATION_URL,
clientID: process.env.CMD_OAUTH2_CLIENT_ID,
clientSecret: process.env.CMD_OAUTH2_CLIENT_SECRET
},
dropbox: {
clientID: process.env.CMD_DROPBOX_CLIENTID,
clientSecret: process.env.CMD_DROPBOX_CLIENTSECRET,
appKey: process.env.CMD_DROPBOX_APPKEY
},
google: {
clientID: process.env.CMD_GOOGLE_CLIENTID,
clientSecret: process.env.CMD_GOOGLE_CLIENTSECRET
},
ldap: {
providerName: process.env.CMD_LDAP_PROVIDERNAME,
url: process.env.CMD_LDAP_URL,
bindDn: process.env.CMD_LDAP_BINDDN,
bindCredentials: process.env.CMD_LDAP_BINDCREDENTIALS,
searchBase: process.env.CMD_LDAP_SEARCHBASE,
searchFilter: process.env.CMD_LDAP_SEARCHFILTER,
searchAttributes: toArrayConfig(process.env.CMD_LDAP_SEARCHATTRIBUTES),
usernameField: process.env.CMD_LDAP_USERNAMEFIELD,
useridField: process.env.CMD_LDAP_USERIDFIELD,
tlsca: process.env.CMD_LDAP_TLS_CA
},
saml: {
idpSsoUrl: process.env.CMD_SAML_IDPSSOURL,
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, '|', []),
attribute: {
id: process.env.CMD_SAML_ATTRIBUTE_ID,
username: process.env.CMD_SAML_ATTRIBUTE_USERNAME,
email: process.env.CMD_SAML_ATTRIBUTE_EMAIL
}
},
email: toBooleanConfig(process.env.CMD_EMAIL),
allowEmailRegister: toBooleanConfig(process.env.CMD_ALLOW_EMAIL_REGISTER),
allowGravatar: toBooleanConfig(process.env.CMD_ALLOW_GRAVATAR),
allowPDFExport: toBooleanConfig(process.env.CMD_ALLOW_PDF_EXPORT),
openID: toBooleanConfig(process.env.CMD_OPENID)
}

View File

@ -0,0 +1,125 @@
'use strict'
const { toBooleanConfig, toArrayConfig, toIntegerConfig } = require('./utils')
module.exports = {
domain: process.env.HMD_DOMAIN,
urlPath: process.env.HMD_URL_PATH,
port: toIntegerConfig(process.env.HMD_PORT),
urlAddPort: toBooleanConfig(process.env.HMD_URL_ADDPORT),
useSSL: toBooleanConfig(process.env.HMD_USESSL),
hsts: {
enable: toBooleanConfig(process.env.HMD_HSTS_ENABLE),
maxAgeSeconds: toIntegerConfig(process.env.HMD_HSTS_MAX_AGE),
includeSubdomains: toBooleanConfig(process.env.HMD_HSTS_INCLUDE_SUBDOMAINS),
preload: toBooleanConfig(process.env.HMD_HSTS_PRELOAD)
},
csp: {
enable: toBooleanConfig(process.env.HMD_CSP_ENABLE),
reportURI: process.env.HMD_CSP_REPORTURI
},
protocolUseSSL: toBooleanConfig(process.env.HMD_PROTOCOL_USESSL),
allowOrigin: toArrayConfig(process.env.HMD_ALLOW_ORIGIN),
useCDN: toBooleanConfig(process.env.HMD_USECDN),
allowAnonymous: toBooleanConfig(process.env.HMD_ALLOW_ANONYMOUS),
allowAnonymousEdits: toBooleanConfig(process.env.HMD_ALLOW_ANONYMOUS_EDITS),
allowFreeURL: toBooleanConfig(process.env.HMD_ALLOW_FREEURL),
defaultPermission: process.env.HMD_DEFAULT_PERMISSION,
dbURL: process.env.HMD_DB_URL,
sessionSecret: process.env.HMD_SESSION_SECRET,
sessionLife: toIntegerConfig(process.env.HMD_SESSION_LIFE),
imageUploadType: process.env.HMD_IMAGE_UPLOAD_TYPE,
imgur: {
clientID: process.env.HMD_IMGUR_CLIENTID
},
s3: {
accessKeyId: process.env.HMD_S3_ACCESS_KEY_ID,
secretAccessKey: process.env.HMD_S3_SECRET_ACCESS_KEY,
region: process.env.HMD_S3_REGION
},
minio: {
accessKey: process.env.HMD_MINIO_ACCESS_KEY,
secretKey: process.env.HMD_MINIO_SECRET_KEY,
endPoint: process.env.HMD_MINIO_ENDPOINT,
secure: toBooleanConfig(process.env.HMD_MINIO_SECURE),
port: toIntegerConfig(process.env.HMD_MINIO_PORT)
},
s3bucket: process.env.HMD_S3_BUCKET,
azure: {
connectionString: process.env.HMD_AZURE_CONNECTION_STRING,
container: process.env.HMD_AZURE_CONTAINER
},
facebook: {
clientID: process.env.HMD_FACEBOOK_CLIENTID,
clientSecret: process.env.HMD_FACEBOOK_CLIENTSECRET
},
twitter: {
consumerKey: process.env.HMD_TWITTER_CONSUMERKEY,
consumerSecret: process.env.HMD_TWITTER_CONSUMERSECRET
},
github: {
clientID: process.env.HMD_GITHUB_CLIENTID,
clientSecret: process.env.HMD_GITHUB_CLIENTSECRET
},
gitlab: {
baseURL: process.env.HMD_GITLAB_BASEURL,
clientID: process.env.HMD_GITLAB_CLIENTID,
clientSecret: process.env.HMD_GITLAB_CLIENTSECRET,
scope: process.env.HMD_GITLAB_SCOPE
},
mattermost: {
baseURL: process.env.HMD_MATTERMOST_BASEURL,
clientID: process.env.HMD_MATTERMOST_CLIENTID,
clientSecret: process.env.HMD_MATTERMOST_CLIENTSECRET
},
oauth2: {
baseURL: process.env.HMD_OAUTH2_BASEURL,
userProfileURL: process.env.HMD_OAUTH2_USER_PROFILE_URL,
userProfileUsernameAttr: process.env.HMD_OAUTH2_USER_PROFILE_USERNAME_ATTR,
userProfileDisplayNameAttr: process.env.HMD_OAUTH2_USER_PROFILE_DISPLAY_NAME_ATTR,
userProfileEmailAttr: process.env.HMD_OAUTH2_USER_PROFILE_EMAIL_ATTR,
tokenURL: process.env.HMD_OAUTH2_TOKEN_URL,
authorizationURL: process.env.HMD_OAUTH2_AUTHORIZATION_URL,
clientID: process.env.HMD_OAUTH2_CLIENT_ID,
clientSecret: process.env.HMD_OAUTH2_CLIENT_SECRET
},
dropbox: {
clientID: process.env.HMD_DROPBOX_CLIENTID,
clientSecret: process.env.HMD_DROPBOX_CLIENTSECRET,
appKey: process.env.HMD_DROPBOX_APPKEY
},
google: {
clientID: process.env.HMD_GOOGLE_CLIENTID,
clientSecret: process.env.HMD_GOOGLE_CLIENTSECRET
},
ldap: {
providerName: process.env.HMD_LDAP_PROVIDERNAME,
url: process.env.HMD_LDAP_URL,
bindDn: process.env.HMD_LDAP_BINDDN,
bindCredentials: process.env.HMD_LDAP_BINDCREDENTIALS,
searchBase: process.env.HMD_LDAP_SEARCHBASE,
searchFilter: process.env.HMD_LDAP_SEARCHFILTER,
searchAttributes: toArrayConfig(process.env.HMD_LDAP_SEARCHATTRIBUTES),
usernameField: process.env.HMD_LDAP_USERNAMEFIELD,
useridField: process.env.HMD_LDAP_USERIDFIELD,
tlsca: process.env.HMD_LDAP_TLS_CA
},
saml: {
idpSsoUrl: process.env.HMD_SAML_IDPSSOURL,
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, '|', []),
attribute: {
id: process.env.HMD_SAML_ATTRIBUTE_ID,
username: process.env.HMD_SAML_ATTRIBUTE_USERNAME,
email: process.env.HMD_SAML_ATTRIBUTE_EMAIL
}
},
email: toBooleanConfig(process.env.HMD_EMAIL),
allowEmailRegister: toBooleanConfig(process.env.HMD_ALLOW_EMAIL_REGISTER),
allowPDFExport: toBooleanConfig(process.env.HMD_ALLOW_PDF_EXPORT)
}

209
lib/config/index.js Normal file
View File

@ -0,0 +1,209 @@
'use strict'
const crypto = require('crypto')
const fs = require('fs')
const path = require('path')
const { merge } = require('lodash')
const deepFreeze = require('deep-freeze')
const { Environment, Permission } = require('./enum')
const logger = require('../logger')
const { getGitCommit, getGitHubURL } = require('./utils')
const appRootPath = path.resolve(__dirname, '../../')
const env = process.env.NODE_ENV || Environment.development
const debugConfig = {
debug: (env === Environment.development)
}
// Get version string from package.json
const { version, repository } = require(path.join(appRootPath, 'package.json'))
const commitID = getGitCommit(appRootPath)
const sourceURL = getGitHubURL(repository.url, commitID || version)
const fullversion = commitID ? `${version}-${commitID}` : version
const packageConfig = {
version: version,
minimumCompatibleVersion: '0.5.0',
fullversion: fullversion,
sourceURL: sourceURL
}
const configFilePath = path.resolve(appRootPath, process.env.CMD_CONFIG_FILE ||
'config.json')
const fileConfig = fs.existsSync(configFilePath) ? require(configFilePath)[env] : undefined
let config = require('./default')
merge(config, require('./defaultSSL'))
merge(config, require('./oldDefault'))
merge(config, debugConfig)
merge(config, packageConfig)
merge(config, fileConfig)
merge(config, require('./oldEnvironment'))
merge(config, require('./hackmdEnvironment'))
merge(config, require('./environment'))
merge(config, require('./dockerSecret'))
if (['debug', 'verbose', 'info', 'warn', 'error'].includes(config.loglevel)) {
logger.level = config.loglevel
} else {
logger.error('Selected loglevel %s doesn\'t exist, using default level \'debug\'. Available options: debug, verbose, info, warn, error', config.loglevel)
}
// load LDAP CA
if (config.ldap.tlsca) {
let ca = config.ldap.tlsca.split(',')
let caContent = []
for (let i of ca) {
if (fs.existsSync(i)) {
caContent.push(fs.readFileSync(i, 'utf8'))
}
}
let tlsOptions = {
ca: caContent
}
config.ldap.tlsOptions = config.ldap.tlsOptions ? Object.assign(config.ldap.tlsOptions, tlsOptions) : tlsOptions
}
// Permission
config.permission = Permission
if (!config.allowAnonymous && !config.allowAnonymousEdits) {
delete config.permission.freely
}
if (!(config.defaultPermission in config.permission)) {
config.defaultPermission = config.permission.editable
}
// cache result, cannot change config in runtime!!!
config.isStandardHTTPsPort = (function isStandardHTTPsPort () {
return config.useSSL && config.port === 443
})()
config.isStandardHTTPPort = (function isStandardHTTPPort () {
return !config.useSSL && config.port === 80
})()
// cache serverURL
config.serverURL = (function getserverurl () {
var url = ''
if (config.domain) {
var protocol = config.protocolUseSSL ? 'https://' : 'http://'
url = protocol + config.domain
if (config.urlAddPort) {
if (!config.isStandardHTTPPort || !config.isStandardHTTPsPort) {
url += ':' + config.port
}
}
}
if (config.urlPath) {
url += '/' + config.urlPath
}
return url
})()
if (config.serverURL === '') {
logger.warn('Neither \'domain\' nor \'CMD_DOMAIN\' is configured. This can cause issues with various components.\nHint: Make sure \'protocolUseSSL\' and \'urlAddPort\' or \'CMD_PROTOCOL_USESSL\' and \'CMD_URL_ADDPORT\' are configured properly.')
}
config.Environment = Environment
// auth method
config.isFacebookEnable = config.facebook.clientID && config.facebook.clientSecret
config.isGoogleEnable = config.google.clientID && config.google.clientSecret
config.isDropboxEnable = config.dropbox.clientID && config.dropbox.clientSecret
config.isTwitterEnable = config.twitter.consumerKey && config.twitter.consumerSecret
config.isEmailEnable = config.email
config.isOpenIDEnable = config.openID
config.isGitHubEnable = config.github.clientID && config.github.clientSecret
config.isGitLabEnable = config.gitlab.clientID && config.gitlab.clientSecret
config.isMattermostEnable = config.mattermost.clientID && config.mattermost.clientSecret
config.isLDAPEnable = config.ldap.url
config.isSAMLEnable = config.saml.idpSsoUrl
config.isOAuth2Enable = config.oauth2.clientID && config.oauth2.clientSecret
config.isPDFExportEnable = config.allowPDFExport
// Check gitlab api version
if (config.gitlab && config.gitlab.version !== 'v4' && config.gitlab.version !== 'v3') {
logger.warn('config.js contains wrong version (' + config.gitlab.version + ') for gitlab api; it should be \'v3\' or \'v4\'. Defaulting to v4')
config.gitlab.version = 'v4'
}
// If gitlab scope is api, enable snippets Export/import
config.isGitlabSnippetsEnable = (!config.gitlab.scope || config.gitlab.scope === 'api') && config.isGitLabEnable
// Only update i18n files in development setups
config.updateI18nFiles = (env === Environment.development)
// merge legacy values
let keys = Object.keys(config)
const uppercase = /[A-Z]/
for (let i = keys.length; i--;) {
let lowercaseKey = keys[i].toLowerCase()
// if the config contains uppercase letters
// and a lowercase version of this setting exists
// and the config with uppercase is not set
// we set the new config using the old key.
if (uppercase.test(keys[i]) &&
config[lowercaseKey] !== undefined &&
fileConfig[keys[i]] === undefined) {
logger.warn('config.js contains deprecated lowercase setting for ' + keys[i] + '. Please change your config.js file to replace ' + lowercaseKey + ' with ' + keys[i])
config[keys[i]] = config[lowercaseKey]
}
}
// 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/codimd/server#environment-variables-will-overwrite-other-server-configs')
}
// Generate session secret if it stays on default values
if (config.sessionSecret === 'secret') {
logger.warn('Session secret not set. Using random generated one. Please set `sessionSecret` in your config.js file. All users will be logged out.')
config.sessionSecret = crypto.randomBytes(Math.ceil(config.sessionSecretLen / 2)) // generate crypto graphic random number
.toString('hex') // convert to hexadecimal format
.slice(0, config.sessionSecretLen) // return required number of characters
}
// Validate upload upload providers
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'
}
// figure out mime types for image uploads
switch (config.imageUploadType) {
case 'imgur':
config.allowedUploadMimeTypes = [
'image/jpeg',
'image/png',
'image/jpg',
'image/gif'
]
break
default:
config.allowedUploadMimeTypes = [
'image/jpeg',
'image/png',
'image/jpg',
'image/gif',
'image/svg+xml'
]
}
// generate correct path
config.sslCAPath.forEach(function (capath, i, array) {
array[i] = path.resolve(appRootPath, capath)
})
config.sslCertPath = path.resolve(appRootPath, config.sslCertPath)
config.sslKeyPath = path.resolve(appRootPath, config.sslKeyPath)
config.dhParamPath = path.resolve(appRootPath, config.dhParamPath)
config.viewPath = path.resolve(appRootPath, config.viewPath)
config.tmpPath = path.resolve(appRootPath, config.tmpPath)
config.defaultNotePath = path.resolve(appRootPath, config.defaultNotePath)
config.docsPath = path.resolve(appRootPath, config.docsPath)
config.uploadsPath = path.resolve(appRootPath, config.uploadsPath)
// make config readonly
config = deepFreeze(config)
module.exports = config

42
lib/config/oldDefault.js Normal file
View File

@ -0,0 +1,42 @@
'use strict'
module.exports = {
urlpath: undefined,
urladdport: undefined,
alloworigin: undefined,
usessl: undefined,
protocolusessl: undefined,
usecdn: undefined,
allowanonymous: undefined,
allowanonymousedits: undefined,
allowfreeurl: undefined,
defaultpermission: undefined,
dburl: undefined,
// ssl path
sslkeypath: undefined,
sslcertpath: undefined,
sslcapath: undefined,
dhparampath: undefined,
// other path
tmppath: undefined,
defaultnotepath: undefined,
docspath: undefined,
indexpath: undefined,
hackmdpath: undefined,
errorpath: undefined,
prettypath: undefined,
slidepath: undefined,
// session
sessionname: undefined,
sessionsecret: undefined,
sessionlife: undefined,
staticcachetime: undefined,
// socket.io
heartbeatinterval: undefined,
heartbeattimeout: undefined,
// document
documentmaxlength: undefined,
imageuploadtype: undefined,
allowemailregister: undefined,
allowpdfexport: undefined
}

View File

@ -0,0 +1,10 @@
'use strict'
const { toBooleanConfig } = require('./utils')
module.exports = {
debug: toBooleanConfig(process.env.DEBUG),
dburl: process.env.DATABASE_URL,
urlpath: process.env.URL_PATH,
port: process.env.PORT
}

55
lib/config/utils.js Normal file
View File

@ -0,0 +1,55 @@
'use strict'
const fs = require('fs')
const path = require('path')
exports.toBooleanConfig = function toBooleanConfig (configValue) {
if (configValue && typeof configValue === 'string') {
return (configValue === 'true')
}
return configValue
}
exports.toArrayConfig = function toArrayConfig (configValue, separator = ',', fallback) {
if (configValue && typeof configValue === 'string') {
return (configValue.split(separator).map(arrayItem => arrayItem.trim()))
}
return fallback
}
exports.toIntegerConfig = function toIntegerConfig (configValue) {
if (configValue && typeof configValue === 'string') {
return parseInt(configValue)
}
return configValue
}
exports.getGitCommit = function getGitCommit (repodir) {
if (!fs.existsSync(repodir + '/.git/HEAD')) {
return undefined
}
let reference = fs.readFileSync(repodir + '/.git/HEAD', 'utf8')
if (reference.startsWith('ref: ')) {
reference = reference.substr(5).replace('\n', '')
reference = fs.readFileSync(path.resolve(repodir + '/.git', reference), 'utf8')
}
reference = reference.replace('\n', '')
return reference
}
exports.getGitHubURL = function getGitHubURL (repo, reference) {
// if it's not a github reference, we handle handle that anyway
if (!repo.startsWith('https://github.com') && !repo.startsWith('git@github.com')) {
return repo
}
if (repo.startsWith('git@github.com') || repo.startsWith('ssh://git@github.com')) {
repo = repo.replace(/^(ssh:\/\/)?git@github.com:/, 'https://github.com/')
}
if (repo.endsWith('.git')) {
repo = repo.replace(/\.git$/, '/')
} else if (!repo.endsWith('/')) {
repo = repo + '/'
}
return repo + 'tree/' + reference
}

100
lib/csp.js Normal file
View File

@ -0,0 +1,100 @@
var config = require('./config')
var uuid = require('uuid')
var CspStrategy = {}
var defaultDirectives = {
defaultSrc: ['\'self\''],
scriptSrc: ['\'self\'', 'vimeo.com', 'https://gist.github.com', 'www.slideshare.net', 'https://query.yahooapis.com', '\'unsafe-eval\''],
// ^ TODO: Remove unsafe-eval - webpack script-loader issues https://github.com/hackmdio/codimd/issues/594
imgSrc: ['*'],
styleSrc: ['\'self\'', '\'unsafe-inline\'', 'https://github.githubassets.com'], // unsafe-inline is required for some libs, plus used in views
fontSrc: ['\'self\'', 'data:', 'https://public.slidesharecdn.com'],
objectSrc: ['*'], // Chrome PDF viewer treats PDFs as objects :/
mediaSrc: ['*'],
childSrc: ['*'],
connectSrc: ['*']
}
var cdnDirectives = {
scriptSrc: ['https://cdnjs.cloudflare.com', 'https://cdn.mathjax.org'],
styleSrc: ['https://cdnjs.cloudflare.com', 'https://fonts.googleapis.com'],
fontSrc: ['https://cdnjs.cloudflare.com', 'https://fonts.gstatic.com']
}
var disqusDirectives = {
scriptSrc: ['https://disqus.com', 'https://*.disqus.com', 'https://*.disquscdn.com'],
styleSrc: ['https://*.disquscdn.com'],
fontSrc: ['https://*.disquscdn.com']
}
var googleAnalyticsDirectives = {
scriptSrc: ['https://www.google-analytics.com']
}
CspStrategy.computeDirectives = function () {
var directives = {}
mergeDirectives(directives, config.csp.directives)
mergeDirectivesIf(config.csp.addDefaults, directives, defaultDirectives)
mergeDirectivesIf(config.useCDN, directives, cdnDirectives)
mergeDirectivesIf(config.csp.addDisqus, directives, disqusDirectives)
mergeDirectivesIf(config.csp.addGoogleAnalytics, directives, googleAnalyticsDirectives)
if (!areAllInlineScriptsAllowed(directives)) {
addInlineScriptExceptions(directives)
}
addUpgradeUnsafeRequestsOptionTo(directives)
addReportURI(directives)
return directives
}
function mergeDirectives (existingDirectives, newDirectives) {
for (var propertyName in newDirectives) {
var newDirective = newDirectives[propertyName]
if (newDirective) {
var existingDirective = existingDirectives[propertyName] || []
existingDirectives[propertyName] = existingDirective.concat(newDirective)
}
}
}
function mergeDirectivesIf (condition, existingDirectives, newDirectives) {
if (condition) {
mergeDirectives(existingDirectives, newDirectives)
}
}
function areAllInlineScriptsAllowed (directives) {
return directives.scriptSrc.indexOf('\'unsafe-inline\'') !== -1
}
function addInlineScriptExceptions (directives) {
directives.scriptSrc.push(getCspNonce)
// TODO: This is the SHA-256 hash of the inline script in build/reveal.js/plugins/notes/notes.html
// Any more clean solution appreciated.
directives.scriptSrc.push('\'sha256-Lc+VnBdinzYTTAkFrIoUqdoA9EQFeS1AF9ybmF+LLfM=\'')
}
function getCspNonce (req, res) {
return "'nonce-" + res.locals.nonce + "'"
}
function addUpgradeUnsafeRequestsOptionTo (directives) {
if (config.csp.upgradeInsecureRequests === 'auto' && config.useSSL) {
directives.upgradeInsecureRequests = true
} else if (config.csp.upgradeInsecureRequests === true) {
directives.upgradeInsecureRequests = true
}
}
function addReportURI (directives) {
if (config.csp.reportURI) {
directives.reportUri = config.csp.reportURI
}
}
CspStrategy.addNonceToLocals = function (req, res, next) {
res.locals.nonce = uuid.v4()
next()
}
module.exports = CspStrategy

View File

@ -1,172 +1,200 @@
//history
//external modules
var async = require('async');
'use strict'
// history
// external modules
var LZString = require('lz-string')
//core
var config = require("./config.js");
var logger = require("./logger.js");
var response = require("./response.js");
var models = require("./models");
// core
var logger = require('./logger')
var response = require('./response')
var models = require('./models')
//public
// public
var History = {
historyGet: historyGet,
historyPost: historyPost,
historyDelete: historyDelete,
updateHistory: updateHistory
};
function getHistory(userid, callback) {
models.User.findOne({
where: {
id: userid
}
}).then(function (user) {
if (!user)
return callback(null, null);
var history = {};
if (user.history)
history = parseHistoryToObject(JSON.parse(user.history));
if (config.debug)
logger.info('read history success: ' + user.id);
return callback(null, history);
}).catch(function (err) {
logger.error('read history failed: ' + err);
return callback(err, null);
});
historyGet: historyGet,
historyPost: historyPost,
historyDelete: historyDelete,
updateHistory: updateHistory
}
function setHistory(userid, history, callback) {
models.User.update({
history: JSON.stringify(parseHistoryToArray(history))
}, {
where: {
id: userid
}
}).then(function (count) {
return callback(null, count);
}).catch(function (err) {
logger.error('set history failed: ' + err);
return callback(err, null);
});
}
function updateHistory(userid, noteId, document, time) {
if (userid && noteId && typeof document !== 'undefined') {
getHistory(userid, function (err, history) {
if (err || !history) return;
if (!history[noteId]) {
history[noteId] = {};
}
var noteHistory = history[noteId];
var noteInfo = models.Note.parseNoteInfo(document);
noteHistory.id = noteId;
noteHistory.text = noteInfo.title;
noteHistory.time = time || Date.now();
noteHistory.tags = noteInfo.tags;
setHistory(userid, history, function (err, count) {
return;
});
});
function getHistory (userid, callback) {
models.User.findOne({
where: {
id: userid
}
}
function parseHistoryToArray(history) {
var _history = [];
Object.keys(history).forEach(function (key) {
var item = history[key];
_history.push(item);
});
return _history;
}
function parseHistoryToObject(history) {
var _history = {};
for (var i = 0, l = history.length; i < l; i++) {
var item = history[i];
_history[item.id] = item;
}).then(function (user) {
if (!user) {
return callback(null, null)
}
return _history;
var history = {}
if (user.history) {
history = JSON.parse(user.history)
// migrate LZString encoded note id to base64url encoded note id
for (let i = 0, l = history.length; i < l; i++) {
// Calculate minimal string length for an UUID that is encoded
// base64 encoded and optimize comparsion by using -1
// this should make a lot of LZ-String parsing errors obsolete
// as we can assume that a nodeId that is 48 chars or longer is a
// noteID.
const base64UuidLength = ((4 * 36) / 3) - 1
if (!(history[i].id.length > base64UuidLength)) {
continue
}
try {
let id = LZString.decompressFromBase64(history[i].id)
if (id && models.Note.checkNoteIdValid(id)) {
history[i].id = models.Note.encodeNoteId(id)
}
} catch (err) {
// most error here comes from LZString, ignore
if (err.message === 'Cannot read property \'charAt\' of undefined') {
logger.warning('Looks like we can not decode "' + history[i].id + '" with LZString. Can be ignored.')
} else {
logger.error(err)
}
}
}
history = parseHistoryToObject(history)
}
logger.debug(`read history success: ${user.id}`)
return callback(null, history)
}).catch(function (err) {
logger.error('read history failed: ' + err)
return callback(err, null)
})
}
function historyGet(req, res) {
if (req.isAuthenticated()) {
getHistory(req.user.id, function (err, history) {
if (err) return response.errorInternalError(res);
if (!history) return response.errorNotFound(res);
res.send({
history: parseHistoryToArray(history)
});
});
function setHistory (userid, history, callback) {
models.User.update({
history: JSON.stringify(parseHistoryToArray(history))
}, {
where: {
id: userid
}
}).then(function (count) {
return callback(null, count)
}).catch(function (err) {
logger.error('set history failed: ' + err)
return callback(err, null)
})
}
function updateHistory (userid, noteId, document, time) {
if (userid && noteId && typeof document !== 'undefined') {
getHistory(userid, function (err, history) {
if (err || !history) return
if (!history[noteId]) {
history[noteId] = {}
}
var noteHistory = history[noteId]
var noteInfo = models.Note.parseNoteInfo(document)
noteHistory.id = noteId
noteHistory.text = noteInfo.title
noteHistory.time = time || Date.now()
noteHistory.tags = noteInfo.tags
setHistory(userid, history, function (err, count) {
if (err) {
logger.log(err)
}
})
})
}
}
function parseHistoryToArray (history) {
var _history = []
Object.keys(history).forEach(function (key) {
var item = history[key]
_history.push(item)
})
return _history
}
function parseHistoryToObject (history) {
var _history = {}
for (var i = 0, l = history.length; i < l; i++) {
var item = history[i]
_history[item.id] = item
}
return _history
}
function historyGet (req, res) {
if (req.isAuthenticated()) {
getHistory(req.user.id, function (err, history) {
if (err) return response.errorInternalError(res)
if (!history) return response.errorNotFound(res)
res.send({
history: parseHistoryToArray(history)
})
})
} else {
return response.errorForbidden(res)
}
}
function historyPost (req, res) {
if (req.isAuthenticated()) {
var noteId = req.params.noteId
if (!noteId) {
if (typeof req.body['history'] === 'undefined') return response.errorBadRequest(res)
logger.debug(`SERVER received history from [${req.user.id}]: ${req.body.history}`)
try {
var history = JSON.parse(req.body.history)
} catch (err) {
return response.errorBadRequest(res)
}
if (Array.isArray(history)) {
setHistory(req.user.id, history, function (err, count) {
if (err) return response.errorInternalError(res)
res.end()
})
} else {
return response.errorBadRequest(res)
}
} else {
return response.errorForbidden(res);
}
}
function historyPost(req, res) {
if (req.isAuthenticated()) {
var noteId = req.params.noteId;
if (!noteId) {
if (typeof req.body['history'] === 'undefined') return response.errorBadRequest(res);
if (config.debug)
logger.info('SERVER received history from [' + req.user.id + ']: ' + req.body.history);
try {
var history = JSON.parse(req.body.history);
} catch (err) {
return response.errorBadRequest(res);
}
if (Array.isArray(history)) {
setHistory(req.user.id, history, function (err, count) {
if (err) return response.errorInternalError(res);
res.end();
});
} else {
return response.errorBadRequest(res);
}
if (typeof req.body['pinned'] === 'undefined') return response.errorBadRequest(res)
getHistory(req.user.id, function (err, history) {
if (err) return response.errorInternalError(res)
if (!history) return response.errorNotFound(res)
if (!history[noteId]) return response.errorNotFound(res)
if (req.body.pinned === 'true' || req.body.pinned === 'false') {
history[noteId].pinned = (req.body.pinned === 'true')
setHistory(req.user.id, history, function (err, count) {
if (err) return response.errorInternalError(res)
res.end()
})
} else {
if (typeof req.body['pinned'] === 'undefined') return response.errorBadRequest(res);
getHistory(req.user.id, function (err, history) {
if (err) return response.errorInternalError(res);
if (!history) return response.errorNotFound(res);
if (!history[noteId]) return response.errorNotFound(res);
if (req.body.pinned === 'true' || req.body.pinned === 'false') {
history[noteId].pinned = (req.body.pinned === 'true');
setHistory(req.user.id, history, function (err, count) {
if (err) return response.errorInternalError(res);
res.end();
});
} else {
return response.errorBadRequest(res);
}
});
return response.errorBadRequest(res)
}
} else {
return response.errorForbidden(res);
})
}
} else {
return response.errorForbidden(res)
}
}
function historyDelete(req, res) {
if (req.isAuthenticated()) {
var noteId = req.params.noteId;
if (!noteId) {
setHistory(req.user.id, [], function (err, count) {
if (err) return response.errorInternalError(res);
res.end();
});
} else {
getHistory(req.user.id, function (err, history) {
if (err) return response.errorInternalError(res);
if (!history) return response.errorNotFound(res);
delete history[noteId];
setHistory(req.user.id, history, function (err, count) {
if (err) return response.errorInternalError(res);
res.end();
});
});
}
function historyDelete (req, res) {
if (req.isAuthenticated()) {
var noteId = req.params.noteId
if (!noteId) {
setHistory(req.user.id, [], function (err, count) {
if (err) return response.errorInternalError(res)
res.end()
})
} else {
return response.errorForbidden(res);
getHistory(req.user.id, function (err, history) {
if (err) return response.errorInternalError(res)
if (!history) return response.errorNotFound(res)
delete history[noteId]
setHistory(req.user.id, history, function (err, count) {
if (err) return response.errorInternalError(res)
res.end()
})
})
}
} else {
return response.errorForbidden(res)
}
}
module.exports = History;
module.exports = History

View File

@ -1,25 +1,50 @@
"use strict";
'use strict'
// external modules
var randomcolor = require('randomcolor');
const crypto = require('crypto')
const randomcolor = require('randomcolor')
const config = require('./config')
// core
module.exports = function(name) {
var color = randomcolor({
seed: name,
luminosity: 'dark'
});
var letter = name.substring(0, 1).toUpperCase();
exports.generateAvatar = function (name) {
const color = randomcolor({
seed: name,
luminosity: 'dark'
})
const letter = name.substring(0, 1).toUpperCase()
var svg = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>';
svg += '<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="96" width="96" version="1.1" viewBox="0 0 96 96">';
svg += '<g>';
svg += '<rect width="96" height="96" fill="' + color + '" />';
svg += '<text font-size="64px" font-family="sans-serif" text-anchor="middle" fill="#ffffff">';
svg += '<tspan x="48" y="72" stroke-width=".26458px" fill="#ffffff">' + letter + '</tspan>';
svg += '</text>';
svg += '</g>';
svg += '</svg>';
let svg = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>'
svg += '<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="96" width="96" version="1.1" viewBox="0 0 96 96">'
svg += '<g>'
svg += '<rect width="96" height="96" fill="' + color + '" />'
svg += '<text font-size="64px" font-family="sans-serif" text-anchor="middle" fill="#ffffff">'
svg += '<tspan x="48" y="72" stroke-width=".26458px" fill="#ffffff">' + letter + '</tspan>'
svg += '</text>'
svg += '</g>'
svg += '</svg>'
return 'data:image/svg+xml;base64,' + new Buffer(svg).toString('base64');
};
return svg
}
exports.generateAvatarURL = function (name, email = '', big = true) {
let photo
if (typeof email !== 'string') {
email = '' + name + '@example.com'
}
name = encodeURIComponent(name)
let hash = crypto.createHash('md5')
hash.update(email.toLowerCase())
let hexDigest = hash.digest('hex')
if (email !== '' && config.allowGravatar) {
photo = 'https://cdn.libravatar.org/avatar/' + hexDigest
if (big) {
photo += '?s=400'
} else {
photo += '?s=96'
}
} else {
photo = config.serverURL + '/user/' + (name || email.substring(0, email.lastIndexOf('@')) || hexDigest) + '/avatar.svg'
}
return photo
}

View File

@ -1,22 +1,27 @@
var winston = require('winston');
winston.emitErrs = true;
'use strict'
const { createLogger, format, transports } = require('winston')
var logger = new winston.Logger({
transports: [
new winston.transports.Console({
level: 'debug',
handleExceptions: true,
json: false,
colorize: true,
timestamp: true
})
],
exitOnError: false
});
const logger = createLogger({
level: 'debug',
format: format.combine(
format.uncolorize(),
format.timestamp(),
format.align(),
format.splat(),
format.printf(info => `${info.timestamp} ${info.level}: ${info.message}`)
),
transports: [
new transports.Console({
handleExceptions: true
})
],
exitOnError: false
})
module.exports = logger;
module.exports.stream = {
write: function(message, encoding){
logger.info(message);
}
};
logger.stream = {
write: function (message, encoding) {
logger.info(message)
}
}
module.exports = logger

Some files were not shown because too many files have changed in this diff Show More