Commit 9b2d339f authored by gthiem1's avatar gthiem1
Browse files

test 1.9 RC

parent 35b0fbe9
module.exports = {
"root": true,
"extends": "standard",
"env": {
"node": true
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"]
}
};
rules: {}
}
......@@ -11,6 +11,7 @@ This PR fixes/adds/improves/...
- [ ] Added implementation
- [ ] Added / updated tests
- [ ] Added / updated documentation
- [ ] Added changelog snippet
- [ ] I read the [contribution documentation](https://github.com/hedgedoc/hedgedoc/blob/master/CONTRIBUTING.md) and signed-off my commits to accept the DCO.
### Related Issue(s)
......
......@@ -18,20 +18,11 @@ jobs:
- sudo apt install -y jq && yarn run jsonlint
steps:
- uses: actions/checkout@v2
- name: Use Node.js 14
- name: Use Node.js 16
uses: actions/setup-node@v2
with:
node-version: 14
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- uses: actions/cache@v2
id: yarn-cache
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
node-version: 16
cache: yarn
- run: yarn --frozen-lockfile --prefer-offline
- run: ${{matrix.command}}
dynamic-tests:
......@@ -39,23 +30,14 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [12.x, 14.x, 15.x, 16.x]
node-version: [12, 14, 16]
steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- uses: actions/cache@v2
id: yarn-cache
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
cache: yarn
- run: yarn --frozen-lockfile --prefer-offline
- run: yarn run mocha-suite
production-build:
......@@ -63,27 +45,18 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [12.x, 14.x, 15.x, 16.x]
node-version: [12, 14, 16]
steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- uses: actions/cache@v2
id: yarn-cache
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
cache: yarn
- run: yarn --frozen-lockfile --prefer-offline
- run: yarn run build
- uses: actions/upload-artifact@v2
if: github.ref == 'refs/heads/master' && matrix.node-version == '14.x'
if: github.ref == 'refs/heads/master' && matrix.node-version == '16'
with:
name: Prebuild with Node.js ${{ matrix.node-version }}
path: |
......
......@@ -51,6 +51,16 @@ If you set your `user.name` and `user.email` git configs, you can sign your comm
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.
## Changelog snippets
PRs that fix a bug or add a new feature or enhancement should add a corresponding changelog entry.
The changelog can be found at `public/docs/release-notes.md`. If there is no section for the next release yet, just add
one using `## <i class="fa fa-tag"></i> 1.x.x <i class="fa fa-calendar-o"></i> UNRELEASED`. The version and date will
be filled later by the maintainers.
Add a short description for your change in the `Features`, `Enhancements` or `Bugfixes` section, creating the section
if needed. Have a look at previous entries for inspiration.
You are welcome to add a `(by [@your_username](https://github.com/your_username))` note to your entry.
## Submitting a Pull Request
1. Submit an issue describing your proposed change.
......
......@@ -58,9 +58,9 @@ More info about that can be found in the configuration docs above.
To use HedgeDoc, your browser should match or exceed these versions:
- ![Chrome](https://raw.githubusercontent.com/alrra/browser-logos/HEAD/src/chrome/chrome_24x24.png) Chrome >= 47, ![Chrome](https://raw.githubusercontent.com/alrra/browser-logos/HEAD/src/chrome/chrome_24x24.png) Chrome for Android >= 47
- ![Safari](https://raw.githubusercontent.com/alrra/browser-logos/HEAD/src/safari/safari_24x24.png) Safari >= 9, ![iOS Safarai](https://raw.githubusercontent.com/alrra/browser-logos/HEAD/src/safari-ios/safari-ios_24x24.png) iOS Safari >= 8.4
- ![Safari](https://raw.githubusercontent.com/alrra/browser-logos/HEAD/src/safari/safari_24x24.png) Safari >= 10.1, ![iOS Safari](https://raw.githubusercontent.com/alrra/browser-logos/HEAD/src/safari-ios/safari-ios_24x24.png) iOS Safari >= 10.3
- ![Firefox](https://raw.githubusercontent.com/alrra/browser-logos/HEAD/src/firefox/firefox_24x24.png) Firefox >= 44
- ![Edge](https://raw.githubusercontent.com/alrra/browser-logos/HEAD/src/edge/edge_24x24.png) Edge >= 12
- ![Edge](https://raw.githubusercontent.com/alrra/browser-logos/HEAD/src/edge/edge_24x24.png) Edge >= 14
- ![Opera](https://raw.githubusercontent.com/alrra/browser-logos/HEAD/src/opera/opera_24x24.png) Opera >=
34, ![Opera Mini](https://raw.githubusercontent.com/alrra/browser-logos/HEAD/src/opera-mini/opera-mini_24x24.png)
Opera Mini not supported
......
......@@ -27,6 +27,7 @@ const errors = require('./lib/errors')
const models = require('./lib/models')
const csp = require('./lib/csp')
const metrics = require('./lib/prometheus')
const { useUnless } = require('./lib/utils')
const supportedLocalesList = Object.keys(require('./locales/_supported.json'))
......@@ -73,10 +74,6 @@ metrics.setupCustomPrometheusMetrics()
// socket io
const io = require('socket.io')(server, { cookie: false })
io.engine.ws = new (require('ws').Server)({
noServer: true,
perMessageDeflate: false
})
// others
const realtime = require('./lib/realtime.js')
......@@ -147,7 +144,7 @@ app.use('/uploads', express.static(path.resolve(__dirname, config.uploadsPath),
app.use('/default.md', express.static(path.resolve(__dirname, config.defaultNotePath), { maxAge: config.staticCacheTime }))
// session
app.use(session({
app.use(useUnless(['/status', '/metrics'], session({
name: config.sessionName,
secret: config.sessionSecret,
resave: false, // don't save session if unmodified
......@@ -159,7 +156,7 @@ app.use(session({
secure: config.useSSL || config.protocolUseSSL || false
},
store: sessionStore
}))
})))
// session resumption
const tlsSessionStore = {}
......@@ -194,7 +191,6 @@ 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
......@@ -271,21 +267,38 @@ function startListen () {
}
}
// sync db then start listen
models.sequelize.authenticate().then(function () {
models.runMigrations().then(() => {
sessionStore.sync()
// 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()
})
const maxDBTries = 30
let currentDBTry = 1
function syncAndListen () {
// sync db then start listen
models.sequelize.authenticate().then(function () {
models.runMigrations().then(() => {
sessionStore.sync()
// 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 {
logger.error('server still not ready after db synced')
process.exit(1)
}
})
}).catch(() => {
if (currentDBTry < maxDBTries) {
logger.warn(`Database cannot be reached. Try ${currentDBTry} of ${maxDBTries}.`)
currentDBTry++
setTimeout(function () {
syncAndListen()
}, 1000)
} else {
throw new Error('server still not ready after db synced')
logger.error('Cannot reach database! Exiting.')
process.exit(1)
}
})
})
}
syncAndListen()
// log uncaught exception
process.on('uncaughtException', function (err) {
......@@ -295,9 +308,15 @@ process.on('uncaughtException', function (err) {
process.exit(1)
})
let alreadyHandlingTermSignals = false
// install exit handler
function handleTermSignals () {
if (alreadyHandlingTermSignals) {
logger.info('Forcefully exiting.')
process.exit(1)
}
logger.info('HedgeDoc has been killed by signal, try to exit gracefully...')
alreadyHandlingTermSignals = true
realtime.maintenance = true
// disconnect all socket.io clients
Object.keys(io.sockets.sockets).forEach(function (key) {
......@@ -317,17 +336,28 @@ function handleTermSignals () {
}
})
}
const maxCleanTries = 30
let currentCleanTry = 1
const checkCleanTimer = setInterval(function () {
if (realtime.isReady()) {
models.Revision.checkAllNotesRevision(function (err, notes) {
if (err) return logger.error(err)
if (err) {
logger.error('Error while saving note revisions: ' + err)
if (currentCleanTry <= maxCleanTries) {
logger.warn(`Trying again. Try ${currentCleanTry} of ${maxCleanTries}`)
currentCleanTry++
return null
}
logger.error(`Could not save note revisions after ${maxCleanTries} tries! Exiting.`)
process.exit(1)
}
if (!notes || notes.length <= 0) {
clearInterval(checkCleanTimer)
return process.exit(0)
process.exit(0)
}
})
}
}, 100)
}, 200)
}
process.on('SIGINT', handleTermSignals)
process.on('SIGTERM', handleTermSignals)
......
This diff is collapsed.
......@@ -3,7 +3,7 @@ openapi: 3.0.1
info:
title: HedgeDoc
description: HedgeDoc is an open source collaborative note editor. Several tasks of HedgeDoc can be automated through this API.
version: 1.8.2
version: 1.9.0-rc1
contact:
name: HedgeDoc on GitHub
url: https://github.com/hedgedoc/hedgedoc
......@@ -12,7 +12,7 @@ info:
url: https://github.com/hedgedoc/hedgedoc/blob/master/LICENSE
externalDocs:
url: https://github.com/hedgedoc/hedgedoc/blob/master/docs/dev/api.md
url: https://docs.hedgedoc.org/dev/api/
paths:
......
# FAQ
This page collects Frequently Asked Questions of the community.
If you have any questions that aren't answered here, feel free to ask us on [Matrix][matrix.org-url] or stop by our [community forums][hedgedoc-community].
[matrix.org-url]: https://chat.hedgedoc.org
[hedgedoc-community]: https://community.hedgedoc.org
## Why is CodiMD now called HedgeDoc?
The short version: There were two CodiMD-projects on GitHub, the community-driven fork and the original project maintained by the HackMD-team.
To solve this naming conflict, our community-driven version was renamed to HedgeDoc.
For a full writeup, check out the [history overview](https://hedgedoc.org/history/).
## Can I run multiple instances on the same database?
No. The HedgeDoc server process is not entirely stateless and therefore running more than one instance will result in missing/broken content for users.
In order to solve issues like HA-capabilities, please use a high level orchestrator that makes sure that always 1 instance is running on your infrastructure and that the database is available.
The server process usually starts within seconds and therefore the possible downtime should be minimal.
## Why was the PDF Export feature removed?
We used a headless Chromium instance to generate the PDFs, but that led to some security vulnerabilities and was therefore deactivated.
There are currently plans to re-add this feature in a safe way, but this will most likely take some time and can be expected at the earliest with HedgeDoc 2.1 (but could also take longer).
In the meantime you can use your browsers print to PDF Feature.
This [page](https://www.digitaltrends.com/computing/how-to-save-a-webpage-as-a-pdf/) explains how to do that for multiple browsers.
## Why can't I embed some PDFs?
Many servers don't allow the embedding of their content on arbitrary sites.
For a more technical explanation:
The `X-Frame-Options` header can be used to specify if a given webpage can be embedded.
For security reasons this header is often set to `SAMEORIGIN`, which disallows embedding on other origins.
To be able to embed a PDF inside a HedgeDoc note, the server that hosts the PDF must either send no `X-Frame-Options`
header (which might be insecure) or include the URI of your HedgeDoc instance in an `ALLOW-FROM` statement.
See [Mozillas docs](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options) for more details.
Also note that the `X-Frame-Options` header [is being obsoleted](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/frame-ancestors)
by the `frame-ancestors` statement in the `Content-Security-Policy` header.
## Why can't I embed a HedgeDoc note in other pages using iframes?
Allowing your HedgeDoc instance to be embedded in other pages increases the risk of [clickjacking](https://en.wikipedia.org/wiki/Clickjacking),
[XSS](https://en.wikipedia.org/wiki/Cross-site_scripting) and other attacks.
Therefore, **we recommend to not enable** this option.
If you still want to allow embedding via iframe, ensure that:
- Your HedgeDoc instance is served via HTTPS
- `cookiePolicy` / `CMD_COOKIE_POLICY` is set to `none` (Otherwise you will get a `AUTH failed: No cookie transmitted` error.)
- `csp.allowFraming` / `CMD_CSP_ALLOW_FRAMING` is set to `true`
See also the [configuration docs](/configuration/#web-security-aspects) for more information about these options.
## I can't upload images or the upload gets stuck
This problem is typically accompanied by the error `Invalid URL: /uploads/` in the log and is often caused by a missing
`domain` / `CMD_DOMAIN` config option or an incorrect reverse proxy config.
Have a look at our [reverse proxy documentation](https://docs.hedgedoc.org/guides/reverse-proxy/)
and make sure that `protocolUseSSL` / `CMD_PROTOCOL_USESSL` is set to `true` if you serve HedgeDoc via HTTPS.
## HedgeDoc fails executing migrations and does not start
Unfortunately, older versions of HedgeDoc had some bugs regarding migrations and didn't always record that a migration was executed.
Have a look at the *[Troubleshooting Migrations](/guides/migration-troubleshooting/)* guide for more information.
......@@ -5,6 +5,11 @@ configs that you'll have to do.
This documentation will cover HTTPS setup, with comments for HTTP setup.
## Cloudflare
!!! warning
If you use Cloudflare as reverse proxy then you **MUST** disable the minify features for HTML, CSS and JS, or your HedgeDoc instance may be broken.
For more information please read the [Cloudflare documentation](https://support.cloudflare.com/hc/en-us/articles/200168196-How-do-I-minify-HTML-CSS-and-JavaScript-to-optimize-my-site-).
## HedgeDoc config
[Full explanation of the configuration options](../configuration.md)
......@@ -92,4 +97,3 @@ Here is an example config snippet:
Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
```
......@@ -8,13 +8,13 @@ it by visiting our [HedgeDoc demo server][hedgedoc-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](history.md) or [you can have a look at an explanitory graph over at our website][hedgedoc-history].
into its own organization. [A longer write-up can be read in the history doc](history.md) or [you can have a look at an explanatory graph over at our website][hedgedoc-history].
If you have any questions that aren't answered here, feel free to ask us on [Matrix][matrix.org-url], stop by our [community forums][hedgedoc-community] or have a look at our [FAQ][hedgedoc-faq].
[hedgedoc-demo]: https://demo.hedgedoc.org
[hedgedoc-history]: https://hedgedoc.org/history
[hedgedoc-faq]: https://hedgedoc.org/faq
[hedgedoc-faq]: /faq
[matrix.org-url]: https://chat.hedgedoc.org
[hedgedoc-community]: https://community.hedgedoc.org
......@@ -18,7 +18,7 @@ The easiest way to get started with HedgeDoc and Docker is to use the following
version: '3'
services:
database:
image: postgres:9.6-alpine
image: postgres:13.4-alpine
environment:
- POSTGRES_USER=hedgedoc
- POSTGRES_PASSWORD=password
......
......@@ -2,7 +2,7 @@
!!! info "Requirements on your server"
- Node.js 12 or higher
- Database (PostgreSQL, MySQL, MariaDB, SQLite, MSSQL)
- Database (PostgreSQL, MySQL, MariaDB, SQLite)
The database must use charset `utf8`. This is typically the default in PostgreSQL and SQLite.
In MySQL and MariaDB UTF-8 might need to be set with `alter database <DBNAME> character set utf8 collate utf8_bin;`
Be aware of older MySQL and MariaDB versions which sometimes use shorter representations of UTF-8 than 4 bytes.
......
......@@ -30,6 +30,7 @@ nav:
- GitHub: guides/auth/github.md
- GitLab: guides/auth/gitlab-self-hosted.md
- Keycloak: guides/auth/keycloak.md
- Mattermost: guides/auth/mattermost-self-hosted.md
- Nextcloud: guides/auth/nextcloud.md
- Twitter: guides/auth/twitter.md
- Media Backend:
......@@ -47,7 +48,7 @@ nav:
- 'Operational Transformation': dev/ot.md
- Webpack: dev/webpack.md
- 'Documentation': dev/documentation.md
- FAQ: https://hedgedoc.org/faq
- FAQ: faq.md
markdown_extensions:
- toc:
permalink: true
......
mkdocs==1.1.2
mkdocs-material==7.1.4
mkdocs==1.2.2
mkdocs-material==7.2.5
pymdown-extensions==8.2
mdx_truly_sane_lists==1.2
......@@ -22,14 +22,15 @@ module.exports = {
directives: {
},
addDefaults: true,
addDisqus: true,
addGoogleAnalytics: true,
addDisqus: false,
addGoogleAnalytics: false,
upgradeInsecureRequests: 'auto',
reportURI: undefined
reportURI: undefined,
allowFraming: true,
allowPDFEmbed: true
},
cookiePolicy: 'lax',
protocolUseSSL: false,
useCDN: false,
allowAnonymous: true,
allowAnonymousEdits: false,
allowFreeURL: false,
......
......@@ -20,12 +20,15 @@ module.exports = {
},
csp: {
enable: toBooleanConfig(process.env.CMD_CSP_ENABLE),
reportURI: process.env.CMD_CSP_REPORTURI
reportURI: process.env.CMD_CSP_REPORTURI,
addDisqus: toBooleanConfig(process.env.CMD_CSP_ADD_DISQUS),
addGoogleAnalytics: toBooleanConfig(process.env.CMD_CSP_ADD_GOOGLE_ANALYTICS),
allowFraming: toBooleanConfig(process.env.CMD_CSP_ALLOW_FRAMING),
allowPDFEmbed: toBooleanConfig(process.env.CMD_CSP_ALLOW_PDF_EMBED)
},
cookiePolicy: process.env.CMD_COOKIE_POLICY,
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),
......@@ -33,6 +36,14 @@ module.exports = {
forbiddenNoteIDs: toArrayConfig(process.env.CMD_FORBIDDEN_NOTE_IDS),
defaultPermission: process.env.CMD_DEFAULT_PERMISSION,
dbURL: process.env.CMD_DB_URL,
db: {
username: process.env.CMD_DB_USERNAME,
password: process.env.CMD_DB_PASSWORD,
host: process.env.CMD_DB_HOST,
port: process.env.CMD_DB_PORT,
database: process.env.CMD_DB_DATABASE,
dialect: process.env.CMD_DB_DIALECT
},
sessionSecret: process.env.CMD_SESSION_SECRET,
sessionLife: toIntegerConfig(process.env.CMD_SESSION_LIFE),
tooBusyLag: toIntegerConfig(process.env.CMD_TOOBUSY_LAG),
......
......@@ -20,7 +20,6 @@ module.exports = {
},
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),
......
......@@ -6,7 +6,6 @@ module.exports = {
alloworigin: undefined,
usessl: undefined,
protocolusessl: undefined,
usecdn: undefined,
allowanonymous: undefined,
allowanonymousedits: undefined,
allowfreeurl: undefined,
......
......@@ -25,16 +25,29 @@ exports.toIntegerConfig = function toIntegerConfig (configValue) {
}
exports.getGitCommit = function getGitCommit (repodir) {
if (!fs.existsSync(repodir + '/.git/HEAD')) {
return undefined
try {
// prefer using git to get the current ref, as poking in .git is very fragile
return require('child_process').execSync('git rev-parse HEAD').replace('\n', '')
} catch (e) {
// there was an error running git, try to parse refs ourselves
if (!fs.existsSync(repodir + '/.git/HEAD')) {
// there is no HEAD information
return undefined
}
let reference = fs.readFileSync(repodir + '/.git/HEAD', 'utf8')
if (reference.startsWith('ref: ')) {
// HEAD references another ref, try to get the commit SHA from .git/ref/heads
reference = reference.substr(5).replace('\n', '')
const refPath = path.resolve(repodir + '/.git', reference)
if (!fs.existsSync(refPath)) {
// ref does not exist in .git/ref/heads
return undefined
}
reference = fs.readFileSync(refPath, 'utf8')
}
reference = reference.replace('\n', '')
return reference
}
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) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment