Unverified Commit 16b9409e authored by Yukai Huang's avatar Yukai Huang Committed by GitHub
Browse files

Merge pull request #1439 from hackmdio/release/2.0.0

Release 2.0.0
parents a5bb0d69 fc662661
node_modules node_modules
package-lock.json
composer.phar composer.phar
composer.lock composer.lock
.env.*.php .env.*.php
......
...@@ -7,7 +7,7 @@ node_js: ...@@ -7,7 +7,7 @@ node_js:
- "12" - "12"
dist: xenial dist: xenial
cache: yarn cache: npm
matrix: matrix:
fast_finish: true fast_finish: true
...@@ -19,8 +19,8 @@ matrix: ...@@ -19,8 +19,8 @@ matrix:
- node_js: "12" - node_js: "12"
script: script:
- yarn test:ci - npm run test:ci
- yarn build - npm run build
jobs: jobs:
include: include:
......
web: ./bin/heroku_start.sh
...@@ -44,7 +44,7 @@ HackMD team is committed to keep CodiMD open source. All contributions are welco ...@@ -44,7 +44,7 @@ HackMD team is committed to keep CodiMD open source. All contributions are welco
You would find all documentation here: [CodiMD Documentation](https://hackmd.io/c/codimd-documentation) You would find all documentation here: [CodiMD Documentation](https://hackmd.io/c/codimd-documentation)
### Deployment ### Deployment
If you want to spin up an instance and start using immediately, see [Docker deployment](https://hackmd.io/c/codimd-documentation/%2Fs%2Fcodimd-documentation#Deployment). If you want to spin up an instance and start using immediately, see [Docker deployment](https://hackmd.io/c/codimd-documentation/%2Fs%2Fcodimd-docker-deployment).
If you want to contribute to the project, start with [manual deployment](https://hackmd.io/c/codimd-documentation/%2Fs%2Fcodimd-manual-deployment). If you want to contribute to the project, start with [manual deployment](https://hackmd.io/c/codimd-documentation/%2Fs%2Fcodimd-manual-deployment).
### Configuration ### Configuration
......
...@@ -24,6 +24,9 @@ var logger = require('./lib/logger') ...@@ -24,6 +24,9 @@ var logger = require('./lib/logger')
var response = require('./lib/response') var response = require('./lib/response')
var models = require('./lib/models') var models = require('./lib/models')
var csp = require('./lib/csp') var csp = require('./lib/csp')
const { Environment } = require('./lib/config/enum')
const { versionCheckMiddleware, checkVersion } = require('./lib/web/middleware/checkVersion')
function createHttpServer () { function createHttpServer () {
if (config.useSSL) { if (config.useSSL) {
...@@ -66,7 +69,7 @@ io.engine.ws = new (require('ws').Server)({ ...@@ -66,7 +69,7 @@ io.engine.ws = new (require('ws').Server)({
}) })
// others // others
var realtime = require('./lib/realtime.js') var realtime = require('./lib/realtime/realtime.js')
// assign socket io to realtime // assign socket io to realtime
realtime.io = io realtime.io = io
...@@ -153,7 +156,7 @@ server.on('resumeSession', function (id, cb) { ...@@ -153,7 +156,7 @@ server.on('resumeSession', function (id, cb) {
}) })
// middleware which blocks requests when we're too busy // middleware which blocks requests when we're too busy
app.use(require('./lib/web/middleware/tooBusy')) app.use(require('./lib/middleware/tooBusy'))
app.use(flash()) app.use(flash())
...@@ -162,10 +165,15 @@ app.use(passport.initialize()) ...@@ -162,10 +165,15 @@ app.use(passport.initialize())
app.use(passport.session()) app.use(passport.session())
// check uri is valid before going further // check uri is valid before going further
app.use(require('./lib/web/middleware/checkURIValid')) app.use(require('./lib/middleware/checkURIValid'))
// redirect url without trailing slashes // redirect url without trailing slashes
app.use(require('./lib/web/middleware/redirectWithoutTrailingSlashes')) app.use(require('./lib/middleware/redirectWithoutTrailingSlashes'))
app.use(require('./lib/web/middleware/codiMDVersion')) app.use(require('./lib/middleware/codiMDVersion'))
if (config.autoVersionCheck && process.env.NODE_ENV === Environment.production) {
checkVersion(app)
app.use(versionCheckMiddleware)
}
// routes need sessions // routes need sessions
// template files // template files
...@@ -186,6 +194,7 @@ app.locals.authProviders = { ...@@ -186,6 +194,7 @@ app.locals.authProviders = {
facebook: config.isFacebookEnable, facebook: config.isFacebookEnable,
twitter: config.isTwitterEnable, twitter: config.isTwitterEnable,
github: config.isGitHubEnable, github: config.isGitHubEnable,
bitbucket: config.isBitbucketEnable,
gitlab: config.isGitLabEnable, gitlab: config.isGitLabEnable,
mattermost: config.isMattermostEnable, mattermost: config.isMattermostEnable,
dropbox: config.isDropboxEnable, dropbox: config.isDropboxEnable,
...@@ -199,23 +208,21 @@ app.locals.authProviders = { ...@@ -199,23 +208,21 @@ app.locals.authProviders = {
email: config.isEmailEnable, email: config.isEmailEnable,
allowEmailRegister: config.allowEmailRegister allowEmailRegister: config.allowEmailRegister
} }
app.locals.versionInfo = {
latest: true,
versionItem: null
}
// Export/Import menu items // Export/Import menu items
app.locals.enableDropBoxSave = config.isDropboxEnable app.locals.enableDropBoxSave = config.isDropboxEnable
app.locals.enableGitHubGist = config.isGitHubEnable app.locals.enableGitHubGist = config.isGitHubEnable
app.locals.enableGitlabSnippets = config.isGitlabSnippetsEnable app.locals.enableGitlabSnippets = config.isGitlabSnippetsEnable
app.use(require('./lib/web/baseRouter')) app.use(require('./lib/routes').router)
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'))
// response not found if no any route matxches // response not found if no any route matxches
app.get('*', function (req, res) { app.get('*', function (req, res) {
response.errorNotFound(res) response.errorNotFound(req, res)
}) })
// socket.io secure // socket.io secure
......
...@@ -15,124 +15,132 @@ ...@@ -15,124 +15,132 @@
"description": "Let npm also install development build tool", "description": "Let npm also install development build tool",
"value": "false" "value": "false"
}, },
"HMD_SESSION_SECRET": { "CMD_SESSION_SECRET": {
"description": "Secret used to secure session cookies.", "description": "Secret used to secure session cookies.",
"required": false "required": false
}, },
"HMD_HSTS_ENABLE": { "CMD_HSTS_ENABLE": {
"description": "whether to also use HSTS if HTTPS is enabled", "description": "whether to also use HSTS if HTTPS is enabled",
"required": false "required": false
}, },
"HMD_HSTS_MAX_AGE": { "CMD_HSTS_MAX_AGE": {
"description": "max duration, in seconds, to tell clients to keep HSTS status", "description": "max duration, in seconds, to tell clients to keep HSTS status",
"required": false "required": false
}, },
"HMD_HSTS_INCLUDE_SUBDOMAINS": { "CMD_HSTS_INCLUDE_SUBDOMAINS": {
"description": "whether to tell clients to also regard subdomains as HSTS hosts", "description": "whether to tell clients to also regard subdomains as HSTS hosts",
"required": false "required": false
}, },
"HMD_HSTS_PRELOAD": { "CMD_HSTS_PRELOAD": {
"description": "whether to allow at all adding of the site to HSTS preloads (e.g. in browsers)", "description": "whether to allow at all adding of the site to HSTS preloads (e.g. in browsers)",
"required": false "required": false
}, },
"HMD_DOMAIN": { "CMD_DOMAIN": {
"description": "domain name", "description": "domain name",
"required": false "required": false
}, },
"HMD_URL_PATH": { "CMD_URL_PATH": {
"description": "sub url path, like `www.example.com/<URL_PATH>`", "description": "sub url path, like `www.example.com/<URL_PATH>`",
"required": false "required": false
}, },
"HMD_ALLOW_ORIGIN": { "CMD_ALLOW_ORIGIN": {
"description": "domain name whitelist (use comma to separate)", "description": "domain name whitelist (use comma to separate)",
"required": false, "required": false,
"value": "localhost" "value": "localhost"
}, },
"HMD_PROTOCOL_USESSL": { "CMD_PROTOCOL_USESSL": {
"description": "set to use ssl protocol for resources path (only applied when domain is set)", "description": "set to use ssl protocol for resources path (only applied when domain is set)",
"required": false "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)", "description": "set to add port on callback url (port 80 or 443 won't applied) (only applied when domain is set)",
"required": false "required": false
}, },
"HMD_FACEBOOK_CLIENTID": { "CMD_FACEBOOK_CLIENTID": {
"description": "Facebook API client id", "description": "Facebook API client id",
"required": false "required": false
}, },
"HMD_FACEBOOK_CLIENTSECRET": { "CMD_FACEBOOK_CLIENTSECRET": {
"description": "Facebook API client secret", "description": "Facebook API client secret",
"required": false "required": false
}, },
"HMD_TWITTER_CONSUMERKEY": { "CMD_TWITTER_CONSUMERKEY": {
"description": "Twitter API consumer key", "description": "Twitter API consumer key",
"required": false "required": false
}, },
"HMD_TWITTER_CONSUMERSECRET": { "CMD_TWITTER_CONSUMERSECRET": {
"description": "Twitter API consumer secret", "description": "Twitter API consumer secret",
"required": false "required": false
}, },
"HMD_GITHUB_CLIENTID": { "CMD_GITHUB_CLIENTID": {
"description": "GitHub API client id", "description": "GitHub API client id",
"required": false "required": false
}, },
"HMD_GITHUB_CLIENTSECRET": { "CMD_GITHUB_CLIENTSECRET": {
"description": "GitHub API client secret", "description": "GitHub API client secret",
"required": false "required": false
}, },
"HMD_GITLAB_BASEURL": { "CMD_BITBUCKET_CLIENTID": {
"description": "Bitbucket API client id",
"required": false
},
"CMD_BITBUCKET_CLIENTSECRET": {
"description": "Bitbucket API client secret",
"required": false
},
"CMD_GITLAB_BASEURL": {
"description": "GitLab authentication endpoint, set to use other endpoint than GitLab.com (optional)", "description": "GitLab authentication endpoint, set to use other endpoint than GitLab.com (optional)",
"required": false "required": false
}, },
"HMD_GITLAB_CLIENTID": { "CMD_GITLAB_CLIENTID": {
"description": "GitLab API client id", "description": "GitLab API client id",
"required": false "required": false
}, },
"HMD_GITLAB_CLIENTSECRET": { "CMD_GITLAB_CLIENTSECRET": {
"description": "GitLab API client secret", "description": "GitLab API client secret",
"required": false "required": false
}, },
"HMD_GITLAB_SCOPE": { "CMD_GITLAB_SCOPE": {
"description": "GitLab API client scope (optional)", "description": "GitLab API client scope (optional)",
"required": false "required": false
}, },
"HMD_MATTERMOST_BASEURL": { "CMD_MATTERMOST_BASEURL": {
"description": "Mattermost authentication endpoint", "description": "Mattermost authentication endpoint",
"required": false "required": false
}, },
"HMD_MATTERMOST_CLIENTID": { "CMD_MATTERMOST_CLIENTID": {
"description": "Mattermost API client id", "description": "Mattermost API client id",
"required": false "required": false
}, },
"HMD_MATTERMOST_CLIENTSECRET": { "CMD_MATTERMOST_CLIENTSECRET": {
"description": "Mattermost API client secret", "description": "Mattermost API client secret",
"required": false "required": false
}, },
"HMD_DROPBOX_CLIENTID": { "CMD_DROPBOX_CLIENTID": {
"description": "Dropbox API client id", "description": "Dropbox API client id",
"required": false "required": false
}, },
"HMD_DROPBOX_CLIENTSECRET": { "CMD_DROPBOX_CLIENTSECRET": {
"description": "Dropbox API client secret", "description": "Dropbox API client secret",
"required": false "required": false
}, },
"HMD_DROPBOX_APP_KEY": { "CMD_DROPBOX_APP_KEY": {
"description": "Dropbox app key (for import/export)", "description": "Dropbox app key (for import/export)",
"required": false "required": false
}, },
"HMD_GOOGLE_CLIENTID": { "CMD_GOOGLE_CLIENTID": {
"description": "Google API client id", "description": "Google API client id",
"required": false "required": false
}, },
"HMD_GOOGLE_CLIENTSECRET": { "CMD_GOOGLE_CLIENTSECRET": {
"description": "Google API client secret", "description": "Google API client secret",
"required": false "required": false
}, },
"HMD_IMGUR_CLIENTID": { "CMD_IMGUR_CLIENTID": {
"description": "Imgur API client id", "description": "Imgur API client id",
"required": false "required": false
}, },
"HMD_ALLOW_PDF_EXPORT": { "CMD_ALLOW_PDF_EXPORT": {
"description": "Enable or disable PDF exports", "description": "Enable or disable PDF exports",
"required": false "required": false
} }
......
...@@ -4,17 +4,7 @@ set -e ...@@ -4,17 +4,7 @@ set -e
if [ ! -z "$DYNO" ]; then if [ ! -z "$DYNO" ]; then
# setup config files # setup config files
cat << EOF > .sequelizerc cp .sequelizerc.example .sequelizerc
var path = require('path');
module.exports = {
'config': path.resolve('config.json'),
'migrations-path': path.resolve('lib', 'migrations'),
'models-path': path.resolve('lib', 'models'),
'url': process.env.DATABASE_URL
}
EOF
cat << EOF > config.json cat << EOF > config.json
......
#!/bin/bash
set -euo pipefail
CMD_DB_URL="$DATABASE_URL" CMD_PORT="$PORT" npm run start
...@@ -8,12 +8,11 @@ if [ -d .git ]; then ...@@ -8,12 +8,11 @@ if [ -d .git ]; then
cd "$(git rev-parse --show-toplevel)" cd "$(git rev-parse --show-toplevel)"
fi fi
if ! type yarn > /dev/null if ! type npm > /dev/null
then then
cat << EOF cat << EOF
yarn is not installed, please install Node.js, npm and yarn. npm is not installed, please install Node.js and npm.
Read more on Node.js official website: https://nodejs.org 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 Setup will not be run
EOF EOF
exit 0 exit 0
...@@ -29,14 +28,13 @@ if [ ! -f .sequelizerc ]; then ...@@ -29,14 +28,13 @@ if [ ! -f .sequelizerc ]; then
fi fi
echo "install packages" echo "install packages"
yarn install --pure-lockfile npm install
yarn install --production=false --pure-lockfile
cat << EOF cat << EOF
Edit the following config file to setup CodiMD server and client. Edit the following config file to setup CodiMD server and client.
Read more info at https://github.com/hackmdio/codimd#configuration-files Read more info at https://hackmd.io/c/codimd-documentation/%2Fs%2Fcodimd-configuration
* config.json -- CodiMD config * config.json -- CodiMD config
* .sequelizerc -- db config * .sequelizerc -- db config
......
...@@ -5,14 +5,13 @@ COPY --chown=hackmd:hackmd . . ...@@ -5,14 +5,13 @@ COPY --chown=hackmd:hackmd . .
RUN set -xe && \ RUN set -xe && \
git reset --hard && \ git reset --hard && \
git clean -fx && \ git clean -fx && \
yarn install && \ npm install && \
yarn build && \ npm run build && \
yarn install --production=true && \
cp ./deployments/docker-entrypoint.sh ./ && \ cp ./deployments/docker-entrypoint.sh ./ && \
cp .sequelizerc.example .sequelizerc && \ cp .sequelizerc.example .sequelizerc && \
rm -rf .git .gitignore .travis.yml .dockerignore .editorconfig .babelrc .mailmap .sequelizerc.example \ rm -rf .git .gitignore .travis.yml .dockerignore .editorconfig .babelrc .mailmap .sequelizerc.example \
test docs contribute \ test docs contribute \
yarn.lock webpack.prod.js webpack.htmlexport.js webpack.dev.js webpack.common.js \ package-lock.json webpack.prod.js webpack.htmlexport.js webpack.dev.js webpack.common.js \
config.json.example README.md CONTRIBUTING.md AUTHORS config.json.example README.md CONTRIBUTING.md AUTHORS
FROM hackmdio/runtime:1.0.6 FROM hackmdio/runtime:1.0.6
......
version: "3" version: "3"
services: services:
database: database:
image: postgres:11.5 image: postgres:11.6-alpine
environment: environment:
- POSTGRES_USER=codimd - POSTGRES_USER=codimd
- POSTGRES_PASSWORD=change_password - POSTGRES_PASSWORD=change_password
...@@ -11,10 +11,10 @@ services: ...@@ -11,10 +11,10 @@ services:
restart: always restart: always
codimd: codimd:
# you can use image or custom build below # you can use image or custom build below
# image: nabo.codimd.dev/hackmdio/hackmd:1.4.0 image: nabo.codimd.dev/hackmdio/hackmd:2.0.0
build: # build:
context: .. # context: ..
dockerfile: ./deployments/Dockerfile # dockerfile: ./deployments/Dockerfile
environment: environment:
- CMD_DB_URL=postgres://codimd:change_password@database/codimd - CMD_DB_URL=postgres://codimd:change_password@database/codimd
- CMD_USECDN=false - CMD_USECDN=false
......
# Webpack Docs
## `webpack.common.js`
This file contains all common definition for chunks and plugins, that are needed by the whole app.
**TODO:** Document which entry points are used for what.
## `webpack.htmlexport.js`
Separate config for the "save as html" feature.
Packs all CSS from `public/js/htmlExport.js` to `build/html.min.css`.
This file is then downloaded by client-side JS and used to create the HTML.
See `exportToHTML()` in `public/js/extra.js`.
## `webpack.dev.js`
The development config uses both common configs, enables development mode and enables "cheap" source maps (lines only).
If you need more detailed source maps while developing, you might want to use the `source-maps` option.
See https://webpack.js.org/configuration/devtool/ for details.
## `webpack.prod.js`
The production config uses both common configs and enables production mode.
This automatically enables various optimizations (e.g. UglifyJS). See https://webpack.js.org/concepts/mode/ for details.
For the global app config, the name of the emitted chunks is changed to include the content hash.
See https://webpack.js.org/guides/caching/ on why this is a good idea.
For the HTML export config, CSS minification is enabled.
Authentication guide - GitHub
===
***Note:** This guide was written before the renaming. Just replace `HackMD` with `CodiMD` in your mind :smile: thanks!*
1. Sign-in or sign-up for a GitHub account
2. Navigate to developer settings in your GitHub account [here](https://github.com/settings/developers) and select the "OAuth Apps" tab
3. Click on the **New OAuth App** button, to create a new OAuth App:
![create-oauth-app](../images/auth/create-oauth-app.png)
4. Fill out the new OAuth application registration form, and click **Register Application**
![register-oauth-application-form](../images/auth/register-oauth-application-form.png)
*Note: The callback URL is <your-hackmd-url>/auth/github/callback*
5. After successfully registering the application, you'll receive the Client ID and Client Secret for the application
![application-page](../images/auth/application-page.png)
6. Add the Client ID and Client Secret to your config.json file or pass them as environment variables
* config.json:
````javascript
{
"production": {
"github": {
"clientID": "3747d30eaccXXXXXXXXX",
"clientSecret": "2a8e682948eee0c580XXXXXXXXXXXXXXXXXXXXXX"
}
}
}
````
* environment variables:
````
HMD_GITHUB_CLIENTID=3747d30eaccXXXXXXXXX
HMD_GITHUB_CLIENTSECRET=2a8e682948eee0c580XXXXXXXXXXXXXXXXXXXXXX
````
# 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**