Gitlab Community Edition Instance

Commit 9b2d339f authored by Gregor Thiem's avatar Gregor Thiem
Browse files

test 1.9 RC

parent 35b0fbe9
module.exports = { module.exports = {
"root": true, root: true,
"extends": "standard", extends: ['standard'],
"env": { env: {
"node": true node: true
}, },
"rules": { 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"]
}
};
...@@ -11,6 +11,7 @@ This PR fixes/adds/improves/... ...@@ -11,6 +11,7 @@ This PR fixes/adds/improves/...
- [ ] Added implementation - [ ] Added implementation
- [ ] Added / updated tests - [ ] Added / updated tests
- [ ] Added / updated documentation - [ ] 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. - [ ] 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) ### Related Issue(s)
......
...@@ -18,20 +18,11 @@ jobs: ...@@ -18,20 +18,11 @@ jobs:
- sudo apt install -y jq && yarn run jsonlint - sudo apt install -y jq && yarn run jsonlint
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: Use Node.js 14 - name: Use Node.js 16
uses: actions/setup-node@v2 uses: actions/setup-node@v2
with: with:
node-version: 14 node-version: 16
- name: Get yarn cache directory path cache: yarn
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-
- run: yarn --frozen-lockfile --prefer-offline - run: yarn --frozen-lockfile --prefer-offline
- run: ${{matrix.command}} - run: ${{matrix.command}}
dynamic-tests: dynamic-tests:
...@@ -39,23 +30,14 @@ jobs: ...@@ -39,23 +30,14 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy: strategy:
matrix: matrix:
node-version: [12.x, 14.x, 15.x, 16.x] node-version: [12, 14, 16]
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }} - name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v2 uses: actions/setup-node@v2
with: with:
node-version: ${{ matrix.node-version }} node-version: ${{ matrix.node-version }}
- name: Get yarn cache directory path cache: yarn
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-
- run: yarn --frozen-lockfile --prefer-offline - run: yarn --frozen-lockfile --prefer-offline
- run: yarn run mocha-suite - run: yarn run mocha-suite
production-build: production-build:
...@@ -63,27 +45,18 @@ jobs: ...@@ -63,27 +45,18 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy: strategy:
matrix: matrix:
node-version: [12.x, 14.x, 15.x, 16.x] node-version: [12, 14, 16]
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }} - name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v2 uses: actions/setup-node@v2
with: with:
node-version: ${{ matrix.node-version }} node-version: ${{ matrix.node-version }}
- name: Get yarn cache directory path cache: yarn
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-
- run: yarn --frozen-lockfile --prefer-offline - run: yarn --frozen-lockfile --prefer-offline
- run: yarn run build - run: yarn run build
- uses: actions/upload-artifact@v2 - 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: with:
name: Prebuild with Node.js ${{ matrix.node-version }} name: Prebuild with Node.js ${{ matrix.node-version }}
path: | path: |
......
...@@ -51,6 +51,16 @@ If you set your `user.name` and `user.email` git configs, you can sign your comm ...@@ -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'`. 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. 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 ## Submitting a Pull Request
1. Submit an issue describing your proposed change. 1. Submit an issue describing your proposed change.
......
...@@ -58,9 +58,9 @@ More info about that can be found in the configuration docs above. ...@@ -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: 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 - ![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 - ![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 >= - ![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) 34, ![Opera Mini](https://raw.githubusercontent.com/alrra/browser-logos/HEAD/src/opera-mini/opera-mini_24x24.png)
Opera Mini not supported Opera Mini not supported
......
...@@ -27,6 +27,7 @@ const errors = require('./lib/errors') ...@@ -27,6 +27,7 @@ const errors = require('./lib/errors')
const models = require('./lib/models') const models = require('./lib/models')
const csp = require('./lib/csp') const csp = require('./lib/csp')
const metrics = require('./lib/prometheus') const metrics = require('./lib/prometheus')
const { useUnless } = require('./lib/utils')
const supportedLocalesList = Object.keys(require('./locales/_supported.json')) const supportedLocalesList = Object.keys(require('./locales/_supported.json'))
...@@ -73,10 +74,6 @@ metrics.setupCustomPrometheusMetrics() ...@@ -73,10 +74,6 @@ metrics.setupCustomPrometheusMetrics()
// socket io // socket io
const io = require('socket.io')(server, { cookie: false }) const io = require('socket.io')(server, { cookie: false })
io.engine.ws = new (require('ws').Server)({
noServer: true,
perMessageDeflate: false
})
// others // others
const realtime = require('./lib/realtime.js') const realtime = require('./lib/realtime.js')
...@@ -147,7 +144,7 @@ app.use('/uploads', express.static(path.resolve(__dirname, config.uploadsPath), ...@@ -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 })) app.use('/default.md', express.static(path.resolve(__dirname, config.defaultNotePath), { maxAge: config.staticCacheTime }))
// session // session
app.use(session({ app.use(useUnless(['/status', '/metrics'], session({
name: config.sessionName, name: config.sessionName,
secret: config.sessionSecret, secret: config.sessionSecret,
resave: false, // don't save session if unmodified resave: false, // don't save session if unmodified
...@@ -159,7 +156,7 @@ app.use(session({ ...@@ -159,7 +156,7 @@ app.use(session({
secure: config.useSSL || config.protocolUseSSL || false secure: config.useSSL || config.protocolUseSSL || false
}, },
store: sessionStore store: sessionStore
})) })))
// session resumption // session resumption
const tlsSessionStore = {} const tlsSessionStore = {}
...@@ -194,7 +191,6 @@ app.engine('ejs', ejs.renderFile) ...@@ -194,7 +191,6 @@ app.engine('ejs', ejs.renderFile)
// set view engine // set view engine
app.set('view engine', 'ejs') app.set('view engine', 'ejs')
// set generally available variables for all views // set generally available variables for all views
app.locals.useCDN = config.useCDN
app.locals.serverURL = config.serverURL app.locals.serverURL = config.serverURL
app.locals.sourceURL = config.sourceURL app.locals.sourceURL = config.sourceURL
app.locals.allowAnonymous = config.allowAnonymous app.locals.allowAnonymous = config.allowAnonymous
...@@ -271,21 +267,38 @@ function startListen () { ...@@ -271,21 +267,38 @@ function startListen () {
} }
} }
// sync db then start listen const maxDBTries = 30
models.sequelize.authenticate().then(function () { let currentDBTry = 1
models.runMigrations().then(() => { function syncAndListen () {
sessionStore.sync() // sync db then start listen
// check if realtime is ready models.sequelize.authenticate().then(function () {
if (realtime.isReady()) { models.runMigrations().then(() => {
models.Revision.checkAllNotesRevision(function (err, notes) { sessionStore.sync()
if (err) throw new Error(err) // check if realtime is ready
if (!notes || notes.length <= 0) return startListen() 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 { } else {
throw new Error('server still not ready after db synced') logger.error('Cannot reach database! Exiting.')
process.exit(1)
} }
}) })
}) }
syncAndListen()
// log uncaught exception // log uncaught exception
process.on('uncaughtException', function (err) { process.on('uncaughtException', function (err) {
...@@ -295,9 +308,15 @@ process.on('uncaughtException', function (err) { ...@@ -295,9 +308,15 @@ process.on('uncaughtException', function (err) {
process.exit(1) process.exit(1)
}) })
let alreadyHandlingTermSignals = false
// install exit handler // install exit handler
function handleTermSignals () { function handleTermSignals () {
if (alreadyHandlingTermSignals) {
logger.info('Forcefully exiting.')
process.exit(1)
}
logger.info('HedgeDoc has been killed by signal, try to exit gracefully...') logger.info('HedgeDoc has been killed by signal, try to exit gracefully...')
alreadyHandlingTermSignals = true
realtime.maintenance = true realtime.maintenance = true
// disconnect all socket.io clients // disconnect all socket.io clients
Object.keys(io.sockets.sockets).forEach(function (key) { Object.keys(io.sockets.sockets).forEach(function (key) {
...@@ -317,17 +336,28 @@ function handleTermSignals () { ...@@ -317,17 +336,28 @@ function handleTermSignals () {
} }
}) })
} }
const maxCleanTries = 30
let currentCleanTry = 1
const checkCleanTimer = setInterval(function () { const checkCleanTimer = setInterval(function () {
if (realtime.isReady()) { if (realtime.isReady()) {
models.Revision.checkAllNotesRevision(function (err, notes) { 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) { if (!notes || notes.length <= 0) {
clearInterval(checkCleanTimer) clearInterval(checkCleanTimer)
return process.exit(0) process.exit(0)
} }
}) })
} }
}, 100) }, 200)
} }
process.on('SIGINT', handleTermSignals) process.on('SIGINT', handleTermSignals)
process.on('SIGTERM', handleTermSignals) process.on('SIGTERM', handleTermSignals)
......
This diff is collapsed.
...@@ -3,7 +3,7 @@ openapi: 3.0.1 ...@@ -3,7 +3,7 @@ openapi: 3.0.1
info: info:
title: HedgeDoc title: HedgeDoc
description: HedgeDoc is an open source collaborative note editor. Several tasks of HedgeDoc can be automated through this API. 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: contact:
name: HedgeDoc on GitHub name: HedgeDoc on GitHub
url: https://github.com/hedgedoc/hedgedoc url: https://github.com/hedgedoc/hedgedoc
...@@ -12,7 +12,7 @@ info: ...@@ -12,7 +12,7 @@ info:
url: https://github.com/hedgedoc/hedgedoc/blob/master/LICENSE url: https://github.com/hedgedoc/hedgedoc/blob/master/LICENSE
externalDocs: externalDocs:
url: https://github.com/hedgedoc/hedgedoc/blob/master/docs/dev/api.md url: https://docs.hedgedoc.org/dev/api/
paths: 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. ...@@ -5,6 +5,11 @@ configs that you'll have to do.
This documentation will cover HTTPS setup, with comments for HTTP setup. 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 ## HedgeDoc config
[Full explanation of the configuration options](../configuration.md) [Full explanation of the configuration options](../configuration.md)
...@@ -92,4 +97,3 @@ Here is an example config snippet: ...@@ -92,4 +97,3 @@ Here is an example config snippet:
Include /etc/letsencrypt/options-ssl-apache.conf Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost> </VirtualHost>
``` ```
...@@ -8,13 +8,13 @@ it by visiting our [HedgeDoc demo server][hedgedoc-demo]. ...@@ -8,13 +8,13 @@ it by visiting our [HedgeDoc demo server][hedgedoc-demo].
It is inspired by Hackpad, Etherpad and similar collaborative editors. This It is inspired by Hackpad, Etherpad and similar collaborative editors. This
project originated with the team at [HackMD](https://hackmd.io) and now forked 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]. 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-demo]: https://demo.hedgedoc.org
[hedgedoc-history]: https://hedgedoc.org/history [hedgedoc-history]: https://hedgedoc.org/history
[hedgedoc-faq]: https://hedgedoc.org/faq [hedgedoc-faq]: /faq
[matrix.org-url]: https://chat.hedgedoc.org [matrix.org-url]: https://chat.hedgedoc.org
[hedgedoc-community]: https://community.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 ...@@ -18,7 +18,7 @@ The easiest way to get started with HedgeDoc and Docker is to use the following
version: '3' version: '3'
services: services:
database: database:
image: postgres:9.6-alpine image: postgres:13.4-alpine
environment: environment:
- POSTGRES_USER=hedgedoc - POSTGRES_USER=hedgedoc
- POSTGRES_PASSWORD=password - POSTGRES_PASSWORD=password
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
!!! info "Requirements on your server" !!! info "Requirements on your server"
- Node.js 12 or higher - 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. 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;` 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. Be aware of older MySQL and MariaDB versions which sometimes use shorter representations of UTF-8 than 4 bytes.
......
...@@ -30,6 +30,7 @@ nav: ...@@ -30,6 +30,7 @@ nav:
- GitHub: guides/auth/github.md - GitHub: guides/auth/github.md
- GitLab: guides/auth/gitlab-self-hosted.md - GitLab: guides/auth/gitlab-self-hosted.md
- Keycloak: guides/auth/keycloak.md - Keycloak: guides/auth/keycloak.md
- Mattermost: guides/auth/mattermost-self-hosted.md
- Nextcloud: guides/auth/nextcloud.md - Nextcloud: guides/auth/nextcloud.md
- Twitter: guides/auth/twitter.md - Twitter: guides/auth/twitter.md
- Media Backend: - Media Backend:
...@@ -47,7 +48,7 @@ nav: ...@@ -47,7 +48,7 @@ nav:
- 'Operational Transformation': dev/ot.md - 'Operational Transformation': dev/ot.md
- Webpack: dev/webpack.md - Webpack: dev/webpack.md
- 'Documentation': dev/documentation.md - 'Documentation': dev/documentation.md
- FAQ: https://hedgedoc.org/faq - FAQ: faq.md
markdown_extensions: markdown_extensions:
- toc: - toc:
permalink: true permalink: true
......
mkdocs==1.1.2 mkdocs==1.2.2
mkdocs-material==7.1.4 mkdocs-material==7.2.5
pymdown-extensions==8.2 pymdown-extensions==8.2
mdx_truly_sane_lists==1.2 mdx_truly_sane_lists==1.2
...@@ -22,14 +22,15 @@ module.exports = { ...@@ -22,14 +22,15 @@ module.exports = {
directives: { directives: {
}, },
addDefaults: true, addDefaults: true,
addDisqus: true, addDisqus: false,
addGoogleAnalytics: true, addGoogleAnalytics: false,
upgradeInsecureRequests: 'auto', upgradeInsecureRequests: 'auto',
reportURI: undefined reportURI: undefined,
allowFraming: true,
allowPDFEmbed: true
}, },
cookiePolicy: 'lax', cookiePolicy: 'lax',
protocolUseSSL: false, protocolUseSSL: false,
useCDN: false,
allowAnonymous: true, allowAnonymous: true,
allowAnonymousEdits: false, allowAnonymousEdits: false,
allowFreeURL: false, allowFreeURL: false,
......
...@@ -20,12 +20,15 @@ module.exports = { ...@@ -20,12 +20,15 @@ module.exports = {
}, },
csp: { csp: {
enable: toBooleanConfig(process.env.CMD_CSP_ENABLE),