Gitlab Community Edition Instance

Commit 75d84e9a authored by Gregor Thiem's avatar Gregor Thiem
Browse files

update to 1.9.2

parent 3401a06d
......@@ -175,7 +175,7 @@ app.use(flash())
// passport
app.use(passport.initialize())
app.use(passport.session())
app.use(useUnless(['/status', '/metrics'], passport.session()))
// check uri is valid before going further
app.use(require('./lib/web/middleware/checkURIValid'))
......
......@@ -6,7 +6,7 @@ Environment variables take precedence over configurations from the config files.
- Environment variables are processed in [`lib/config/environment.js`](https://github.com/hedgedoc/hedgedoc/tree/master/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`](https://github.com/hedgedoc/hedgedoc/tree/master/lib/config/default.js), in case you wonder if you even need to override it.
- The config file is processed in [`lib/config/index.js`](https://github.com/hedgedoc/hedgedoc/tree/master/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`](https://github.com/hedgedoc/hedgedoc/tree/master/lib/config/default.js), in case you wonder if you even need to override it. To get started, it is a good idea to take the `config.json.example` and copy it
- The config file is processed in [`lib/config/index.js`](https://github.com/hedgedoc/hedgedoc/tree/master/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`](https://github.com/hedgedoc/hedgedoc/tree/master/lib/config/default.js), in case you wonder if you even need to override it. To get started, it is a good idea to take the [`config.json.example`](https://github.com/hedgedoc/hedgedoc/tree/master/config.json.example) and copy it
to `config.json` before filling in your own details.
**Note:** *Due to the rename process we renamed all `HMD_`-prefix variables to be `CMD_`-prefixed. The old ones continue to work.*
......
......@@ -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.9.0
version: 1.9.2
contact:
name: HedgeDoc on GitHub
url: https://github.com/hedgedoc/hedgedoc
......
......@@ -58,3 +58,22 @@ and make sure that `protocolUseSSL` / `CMD_PROTOCOL_USESSL` is set to `true` if
## 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.
## Why does my interface look weird?
If your interface looks like this
![Broken HedgeDoc interface](./faq/interface_broken.png)
instead of this
![Not broken HedgeDoc interface](./faq/interface_okay.png)
then HedgeDoc can't find the asset files like images, stylesheets, fonts, etc.
You should check the following settings (or their corresponding environment variables if you e.g. use docker.):
- `domain` (env: `CMD_DOMAIN`)
- `protocolUseSSL` (env: `CMD_PROTOCOL_USESSL`)
- `urlAddPort` (env: `CMD_URL_ADDPORT`)
Check [the reverse proxy guide](../guides/reverse-proxy/#configure-asset-link-generation) for an explanation.
......@@ -12,7 +12,7 @@ This documentation will cover HTTPS setup, with comments for HTTP setup.
## HedgeDoc config
[Full explanation of the configuration options](../configuration.md)
### Useful configuration options
| `config.json` parameter | Environment variable | Value | Example |
|-------------------------|----------------------|-------|---------|
......@@ -25,6 +25,23 @@ This documentation will cover HTTPS setup, with comments for HTTP setup.
| `urlAddPort` | `CMD_URL_ADDPORT` | `false`, HedgeDoc should not append its port to the URLs it links | `false` |
| `hsts.enable` | `CMD_HSTS_ENABLE` | `true` if you host over SSL, `false` otherwise | `true` |
[Full explanation of the configuration options](../configuration.md)
### Configure asset link generation
HedgeDoc generates links to other pages and to assets (like images, stylesheets, fonts, etc) using the following settings. You must configure them according to the URL that you use to access your instance.
- `domain` (env: `CMD_DOMAIN`)
- `protocolUseSSL` (env: `CMD_PROTOCOL_USESSL`)
- `urlAddPort` (env: `CMD_URL_ADDPORT`)
!!! example
You access your HedgeDoc instance using a reverse proxy via `https://markdown.example`. You must set:
- `domain` to `markdown.example`.
- `protocolUseSSL` to `true` because you access your instance via HTTPS.
- `urlAddPort` to `false` because you access the instance using the default HTTPS port.
## Reverse Proxy config
......
......@@ -28,7 +28,7 @@ services:
restart: always
app:
# Make sure to use the latest release from https://hedgedoc.org/latest-release
image: quay.io/hedgedoc/hedgedoc:1.9.0
image: quay.io/hedgedoc/hedgedoc:1.9.2
environment:
- CMD_DB_URL=postgres://hedgedoc:password@database:5432/hedgedoc
- CMD_DOMAIN=localhost
......@@ -48,6 +48,17 @@ After executing `docker-compose up`, HedgeDoc should be available at [http://127
You can now continue to configure your container with environment variables.
Check out [the configuration docs](/configuration) for more details.
## File Permissions
By default, HedgeDoc will change the permissions of the uploads directory to
`0700` on every start of the Docker container. This is OK if you keep the files
in a named volume, but if you want to serve the files from a webserver on your
host (e.g. an Nginx reverse proxy) the webserver may not have the permission to
read the files.
To fix this, you can set the `UPLOADS_MODE` env variable to something other
than `0700`.
## Upgrading
!!! warning
......
# Manual Installation
!!! info "Requirements on your server"
- Node.js 12 or higher
- Node.js `>= 12.20.0`, `>= 14.13.1` or `>= 16`. We recommend you run HedgeDoc with the latest release of Node 16.
- 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;`
......@@ -16,7 +16,7 @@
1. Check if you meet the [requirements at the top of this document](#manual-installation).
2. Download the [latest release](https://hedgedoc.org/latest-release/) and extract it.
<small>Alternatively, you can use Git to clone the repository and checkout a release, e.g. with `git clone -b 1.9.0 https://github.com/hedgedoc/hedgedoc.git`.</small>
<small>Alternatively, you can use Git to clone the repository and checkout a release, e.g. with `git clone -b 1.9.2 https://github.com/hedgedoc/hedgedoc.git`.</small>
3. Enter the directory and execute `bin/setup`, which will install the dependencies and create example configs.
4. Configure HedgeDoc: To get started, you can use this minimal `config.json`:
```json
......@@ -58,7 +58,7 @@ If you want to upgrade HedgeDoc from an older version, follow these steps:
and the latest release.
2. Fully stop your old HedgeDoc server.
3. [Download](https://hedgedoc.org/latest-release/) the new release and extract it over the old directory.
<small>If you use Git, you can check out the new tag with e.g. `git fetch origin && git checkout 1.9.0`</small>
<small>If you use Git, you can check out the new tag with e.g. `git fetch origin && git checkout 1.9.2`</small>
5. Run `bin/setup`. This will take care of installing dependencies. It is safe to run on an existing installation.
6. *:octicons-light-bulb-16: If you used the release tarball for 1.7.0 or newer, this step can be skipped.*
Build the frontend bundle by running `yarn install` and `yarn build`. The extra `yarn install` is necessary as `bin/setup` does not install the build dependencies.
......
mkdocs==1.2.2
mkdocs-material==7.2.6
pymdown-extensions==8.2
mkdocs==1.2.3
mkdocs-material==7.3.6
pymdown-extensions==9.1
mdx_truly_sane_lists==1.2
module.exports = {
buildDomainOriginWithProtocol: function (config, baseProtocol) {
const isStandardHTTPsPort = config.protocolUseSSL && config.port === 443
const isStandardHTTPPort = !config.protocolUseSSL && config.port === 80
if (!config.domain) {
return ''
}
let origin = ''
const protocol = baseProtocol + (config.protocolUseSSL ? 's' : '') + '://'
origin = protocol + config.domain
if (config.urlAddPort) {
if (!isStandardHTTPPort || !isStandardHTTPsPort) {
origin += ':' + config.port
}
}
return origin
}
}
......@@ -8,6 +8,7 @@ const deepFreeze = require('deep-freeze')
const { Environment, Permission } = require('./enum')
const logger = require('../logger')
const { getGitCommit, getGitHubURL } = require('./utils')
const { buildDomainOriginWithProtocol } = require('./buildDomainOriginWithProtocol')
const appRootPath = path.resolve(__dirname, '../../')
const env = process.env.NODE_ENV || Environment.development
......@@ -79,14 +80,6 @@ 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
})()
// Use HTTPS protocol if the internal TLS server is enabled
if (config.useSSL === true) {
if (config.protocolUseSSL === false) {
......@@ -96,17 +89,8 @@ if (config.useSSL === true) {
}
// cache serverURL
config.serverURL = (function getserverurl () {
let url = ''
if (config.domain) {
const protocol = config.protocolUseSSL ? 'https://' : 'http://'
url = protocol + config.domain
if (config.urlAddPort) {
if (!config.isStandardHTTPPort || !config.isStandardHTTPsPort) {
url += ':' + config.port
}
}
}
config.serverURL = (function () {
let url = buildDomainOriginWithProtocol(config, 'http')
if (config.urlPath) {
url += '/' + config.urlPath
}
......
const config = require('./config')
const { v4: uuidv4 } = require('uuid')
const { buildDomainOriginWithProtocol } = require('./config/buildDomainOriginWithProtocol')
const CspStrategy = {}
const defaultDirectives = {
defaultSrc: ['\'none\''],
baseUri: ['\'self\''],
connectSrc: ['\'self\''],
connectSrc: ['\'self\'', buildDomainOriginWithProtocol(config, 'ws')],
fontSrc: ['\'self\''],
manifestSrc: ['\'self\''],
frameSrc: ['\'self\'', 'https://player.vimeo.com', 'https://www.slideshare.net/slideshow/embed_code/key/', 'https://www.youtube.com'],
......
......@@ -153,7 +153,9 @@ function gitlabActionProjects (req, res, note) {
id: req.user.id
}
}).then(function (user) {
if (!user) { return errors.errorNotFound(res) }
if (!user) {
return errors.errorNotFound(res)
}
const ret = { baseURL: config.gitlab.baseURL, version: config.gitlab.version }
ret.accesstoken = user.accessToken
ret.profileid = user.profileid
......@@ -161,12 +163,14 @@ function gitlabActionProjects (req, res, note) {
fetch(apiUrl).then(resp => {
if (!resp.ok) {
res.send(ret)
throw new Error('HTTP request returned not okay-ish status')
return Promise.reject(new Error('HTTP request returned not okay-ish status'))
}
return resp.json()
}).then(body => {
ret.projects = body
return res.send(ret)
}).catch(err => {
logger.error('gitlab action projects failed: ', err)
})
}).catch(function (err) {
logger.error('gitlab action projects failed: ' + err)
......
......@@ -3,7 +3,6 @@
const Router = require('express').Router
const formidable = require('formidable')
const path = require('path')
const FileType = require('file-type')
const fs = require('fs')
const os = require('os')
const rimraf = require('rimraf')
......@@ -17,7 +16,8 @@ const imageRouter = (module.exports = Router())
async function checkUploadType (filePath) {
const extension = path.extname(filePath).toLowerCase()
let typeFromMagic = await FileType.fromFile(filePath)
const FileType = await import('file-type')
let typeFromMagic = await FileType.fileTypeFromFile(filePath)
if (extension === '.svg' && (typeFromMagic === undefined || typeFromMagic.mime === 'application/xml')) {
const fileContent = fs.readFileSync(filePath)
if (isSvg(fileContent)) {
......@@ -67,21 +67,22 @@ imageRouter.post('/uploadimage', function (req, res) {
return errors.errorForbidden(res)
}
const form = new formidable.IncomingForm()
form.keepExtensions = true
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'hedgedoc-'))
form.uploadDir = tmpDir
const form = formidable({
keepExtensions: true,
uploadDir: tmpDir
})
form.parse(req, async function (err, fields, files) {
if (err) {
logger.error(`Image upload error: formidable error: ${err}`)
rimraf(tmpDir)
return errors.errorForbidden(res)
} else if (!files.image || !files.image.path) {
} else if (!files.image || !files.image.filepath) {
logger.error("Image upload error: Upload didn't contain file)")
rimraf.sync(tmpDir)
return errors.errorBadRequest(res)
} else if (!(await checkUploadType(files.image.path))) {
} else if (!(await checkUploadType(files.image.filepath))) {
rimraf.sync(tmpDir)
return errors.errorBadRequest(res)
} else {
......@@ -91,9 +92,9 @@ imageRouter.post('/uploadimage', function (req, res) {
const uploadProvider = require('./' + config.imageUploadType)
logger.debug(
`imageRouter: Uploading ${files.image.path} using ${config.imageUploadType}`
`imageRouter: Uploading ${files.image.filepath} using ${config.imageUploadType}`
)
uploadProvider.uploadImage(files.image.path, function (err, url) {
uploadProvider.uploadImage(files.image.filepath, function (err, url) {
rimraf.sync(tmpDir)
if (err !== null) {
logger.error(err)
......
......@@ -37,5 +37,6 @@
"pt-br": "Português do Brasil",
"lt": "Lietuvių kalba",
"ro": "Română",
"sl": "Slovenski jezik"
"sl": "Slovenski jezik",
"eu": "Euskara"
}
\ No newline at end of file
......@@ -15,8 +15,8 @@
"or": "أو",
"Sign Out": "سجل الخروج",
"Explore all features": "استكشف جميع الميزات",
"Select tags...": "اختر كلمات مفتاحية...",
"Search keyword...": "البحث عن كلمة مفتاحية...",
"Select tags...": "اختر كلمات مفتاحية",
"Search keyword...": "البحث عن كلمة مفتاحية",
"Sort by title": "الترتيب حسب العنوان",
"Title": "العنوان",
"Sort by time": "فرز حسب الوقت",
......@@ -97,7 +97,7 @@
"Sorry, you've reached the max length this note can be.": "عذرًا، لقد بلغت الحد الأقصى لطول هذه الملاحظة.",
"Please reduce the content or divide it to more notes, thank you!": "يرجى جعل هذه الملاحظة قصيرة.",
"Import from Gist": "استيراد من Gist",
"Paste your gist url here...": "الصق عنوان url الخاص بك هنا...",
"Paste your gist url here...": "الصق عنوان url الخاص بك هنا",
"Import from Snippet": "استرداد من Snippet",
"Select From Available Projects": "اختر من بين المشاريع المتاحة",
"Select From Available Snippets": "اختر من بين المقتطفات المتاحة",
......
......@@ -15,8 +15,8 @@
"or": "или",
"Sign Out": "Изход",
"Explore all features": "Разучете всички функционалности",
"Select tags...": "Избор на тагове...",
"Search keyword...": "Търсене по ключова дума...",
"Select tags...": "Избор на тагове",
"Search keyword...": "Търсене по ключова дума",
"Sort by title": "Сортиране по заглавие",
"Title": "Заглавие",
"Sort by time": "Сортиране по време",
......@@ -32,7 +32,7 @@
"Do you really want to delete this note?": "Наистина ли искате да изтриете тази бележка?",
"All users will lose their connection.": "Всички потребители ще загубят тяхната връзка.",
"Cancel": "Отказ",
"Yes, do it!": "Да",
"Yes, do it!": "Да!",
"Choose method": "Изберете метод",
"Sign in via %s": "Вход чрез %s",
"New": "Нов",
......@@ -53,7 +53,7 @@
"Menu": "Меню",
"This page need refresh": "Тази страница трябва да бъде презаредена",
"You have an incompatible client version.": "Несъвместима клиентска версия.",
"Refresh to update.": "Презареждане за обновяване",
"Refresh to update.": "Презареждане за обновяване.",
"New version available!": "Нова версия е налична!",
"See releases notes here": "See releases notes here",
"Refresh to enjoy new features.": "Презаредете за да се възползвате от новите функционалности.",
......@@ -88,7 +88,7 @@
"This is a alert area.": "This is an alert area.",
"Revert": "Връщане",
"Import from clipboard": "Импорт от клипборд",
"Paste your markdown or webpage here...": "Поставете вашите markdown или web страница тук...",
"Paste your markdown or webpage here...": "Поставете вашите markdown или web страница тук",
"Clear": "Изчисти",
"This note is locked": "Тази бележка е заключена",
"Sorry, only owner can edit this note.": "Съжаляваме, само собственикът може да редактира тази бележка.",
......@@ -97,7 +97,7 @@
"Sorry, you've reached the max length this note can be.": "Съжаляваме, вие сте достигнали максималната дължина на бележката.",
"Please reduce the content or divide it to more notes, thank you!": "Моля съкратете бележката.",
"Import from Gist": "Импорт от Gist",
"Paste your gist url here...": "Поставете вашата Gist връзка тук...",
"Paste your gist url here...": "Поставете вашата Gist връзка тук",
"Import from Snippet": "Импорт от Snippet",
"Select From Available Projects": "Изберете от налични проекти",
"Select From Available Snippets": "Изберете от налични проекти",
......@@ -112,7 +112,7 @@
"This will delete your account, all notes that are owned by you and remove all references to your account from other notes.": "Това ще изтрие вашият акаунт, всички бележки които са притежавани от вас и всички препратки към него от други бележки.",
"Delete user": "Изтрии на потребител",
"Export user data": "Експорт на данни",
"Help us translating on %s": "Помогнете ни за превода в %s.",
"Help us translating on %s": "Помогнете ни за превода в %s",
"Source Code": "Source Code",
"Register": "Регистрация",
"Powered by %s": "Powered by %s",
......
......@@ -15,8 +15,8 @@
"or": "o",
"Sign Out": "Sortir",
"Explore all features": "Explorar totes les funcions",
"Select tags...": "Seleccionar etiquetes...",
"Search keyword...": "Buscar paraules clau...",
"Select tags...": "Seleccionar etiquetes",
"Search keyword...": "Buscar paraules clau",
"Sort by title": "Ordenar per títol",
"Title": "Títol",
"Sort by time": "Ordenar per hora",
......@@ -53,7 +53,7 @@
"Menu": "Menú",
"This page need refresh": "Aquesta pàgina necessita ser refrescada",
"You have an incompatible client version.": "Tens una versió del client incompatible.",
"Refresh to update.": "Refrescar per actualitzar",
"Refresh to update.": "Refrescar per actualitzar.",
"New version available!": "Nova versió disponible!",
"See releases notes here": "Veure les notes de publicació aquí",
"Refresh to enjoy new features.": "Actualitzar per fer servir les noves funcions.",
......@@ -88,16 +88,16 @@
"This is a alert area.": "Això és una àrea d'alerta.",
"Revert": "Revertir",
"Import from clipboard": "Importar del portapapers",
"Paste your markdown or webpage here...": "Enganxa la teva markdown o pàgina web aquí...",
"Paste your markdown or webpage here...": "Enganxa la teva markdown o pàgina web aquí",
"Clear": "Netejar",
"This note is locked": "Aquesta nota està bloquejada",
"Sorry, only owner can edit this note.": "Perdona, només l'amo pot editar aquesta nota.",
"OK": "OK",
"Reach the limit": "Ha arribat al límit",
"Sorry, you've reached the max length this note can be.": "Perdona, ha arribat a la longitut màxima que pot tenir aquesta nota.",
"Please reduce the content or divide it to more notes, thank you!": "Siusplau, redueix el contingut o divideix-la en més notes, gràcies!",
"Please reduce the content or divide it to more notes, thank you!": "Siusplau, redueix el contingut o divideix-la en més notes, gràcies.",
"Import from Gist": "Importar d'un Gist",
"Paste your gist url here...": "Enganxa l'URL del teu Gist aquí...",
"Paste your gist url here...": "Enganxa l'URL del teu Gist aquí",
"Import from Snippet": "Importar d'Snippet",
"Select From Available Projects": "Triar d'un projecte disponsible",
"Select From Available Snippets": "Triar d'un Snippet disponible",
......@@ -105,7 +105,7 @@
"Export to Snippet": "Exportar a Snippet",
"Select Visibility Level": "Triar el nivell de visibilitat",
"Night Theme": "Tema Fosc",
"Follow us on %s and %s.": "Segueix-nos a %s i %s",
"Follow us on %s and %s.": "Segueix-nos a %s i %s.",
"Privacy": "Privacitat",
"Terms of Use": "Condicions d'ús",
"Do you really want to delete your user account?": "Estàs segur que vols eliminar el teu compte?",
......
......@@ -13,10 +13,10 @@
"Welcome!": "Velkommen!",
"New note": "Ny note",
"or": "eller",
"Sign Out": " Log Ud",
"Sign Out": "Log Ud",
"Explore all features": "Udforsk alle features",
"Select tags...": "Vælg tags...",
"Search keyword...": "Søg nøgleord...",
"Select tags...": "Vælg tags",
"Search keyword...": "Søg nøgleord",
"Sort by title": "Sortér titler",
"Title": "Titel",
"Sort by time": "Sortér kronologisk",
......@@ -88,16 +88,16 @@
"This is a alert area.": "Dette er et alarmområde.",
"Revert": "Fortryd ændringer",
"Import from clipboard": "Importér fra udklipsholder",
"Paste your markdown or webpage here...": "Indsæt din markdown eller hjemmeside her...",
"Paste your markdown or webpage here...": "Indsæt din markdown eller hjemmeside her",
"Clear": "Ryd",
"This note is locked": "Denne note er låst",
"Sorry, only owner can edit this note.": "Beklager, men kun ejeren kan redigere denne note.",
"OK": "Okay",
"Reach the limit": "Nå grænsen",
"Sorry, you've reached the max length this note can be.": "Beklager, du har nået grænsen for den maksimale længde denne note må være.",
"Please reduce the content or divide it to more notes, thank you!": "Vær venlig at begrænse indholdets mængde eller opdel det i flere noter, tak!",
"Please reduce the content or divide it to more notes, thank you!": "Vær venlig at begrænse indholdets mængde eller opdel det i flere noter, tak.",
"Import from Gist": "Importér fra Gist",
"Paste your gist url here...": "Indsæt din gist-url her...",
"Paste your gist url here...": "Indsæt din gist-url her",
"Import from Snippet": "Importér fra Snippet",
"Select From Available Projects": "Vælg fra tilgængelige projekter",
"Select From Available Snippets": "Vælg fra tilgængelige Snippets",
......
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