Compare commits
10 Commits
dddd3a7ed5
...
34f6bb5d0f
| Author | SHA1 | Date | |
|---|---|---|---|
| 34f6bb5d0f | |||
|
|
1e2e22d238 | ||
|
|
734171ded4 | ||
|
|
0482e5b3c0 | ||
|
|
b933504071 | ||
|
|
47a7cdf3f3 | ||
|
|
43f414adc4 | ||
|
|
02c6c08bd3 | ||
|
|
0e24145095 | ||
|
|
486fcfef67 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -16,6 +16,8 @@ backups/
|
||||
*.log
|
||||
*.sqlite
|
||||
|
||||
*~
|
||||
|
||||
# ignore config files
|
||||
config.json
|
||||
.sequelizerc
|
||||
|
||||
2
.mailmap
2
.mailmap
@@ -35,3 +35,5 @@ Yannick Bungers <git@innay.de> Yannick Bungers <github@innay.de>
|
||||
Renovate Bot <bot@renovateapp.com> renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
|
||||
|
||||
Tobias Dillig <tobias.dillig@frachtwerk.de> Tobi <tldev-de@users.noreply.github.com>
|
||||
|
||||
Andreas Boesen <boesen@belwue.de> Andreas Boesen <618847+Happy86@users.noreply.github.com>
|
||||
|
||||
4
AUTHORS
4
AUTHORS
@@ -10,7 +10,8 @@ Alexander Hesse <alexander.hesse@sandstorm-media.de>
|
||||
Alexander Wellbrock <a.wellbrock@mailbox.org>
|
||||
Amolith <amolith@nixnet.xyz>
|
||||
Andre Julius <noromoron@gmail.com>
|
||||
Andreas Boesen <618847+Happy86@users.noreply.github.com>
|
||||
Andreas Boesen <boesen@belwue.de>
|
||||
Andy Piper <andypiper@users.noreply.github.com>
|
||||
Antoine Aflalo <antoine@warrantymaster.com>
|
||||
aptalca <aptalca@users.noreply.github.com>
|
||||
Augustin Trancart <augustin.trancart@oslandia.com>
|
||||
@@ -193,6 +194,7 @@ Tobias Dillig <tobias.dillig@frachtwerk.de>
|
||||
Tobias Kremer <tobias.kremer@gmail.com>
|
||||
Tom Wyckhuys <tomwyckhuys@gmail.com>
|
||||
Toma Tasovac <ttasovac@humanistika.org>
|
||||
Tony Chau <90050474+fo5for@users.noreply.github.com>
|
||||
toshi0123 <7948737+toshi0123@users.noreply.github.com>
|
||||
Turakar <turakar23@gmail.com>
|
||||
VaiTon <eyadlorenzo@gmail.com>
|
||||
|
||||
33
Dockerfile
Normal file
33
Dockerfile
Normal file
@@ -0,0 +1,33 @@
|
||||
############################
|
||||
# 1) Builder: bygg HedgeDoc
|
||||
############################
|
||||
FROM node:18-alpine AS builder
|
||||
|
||||
WORKDIR /build
|
||||
|
||||
# H??mta din branch som tarball (ingen git beh??vs)
|
||||
ADD https://git.sa6anw.se/sa6anw/hedgedoc/archive/refs/heads/hedgeagent/1.10.5.tar.gz /tmp/hedgedoc.tar.gz
|
||||
|
||||
RUN tar -xzf /tmp/hedgedoc.tar.gz --strip-components=1 \
|
||||
&& rm /tmp/hedgedoc.tar.gz
|
||||
|
||||
# Installera deps + bygg frontend/backend
|
||||
RUN corepack enable \
|
||||
&& yarn install --immutable \
|
||||
&& yarn build
|
||||
|
||||
|
||||
########################################
|
||||
# 2) Runtime: officiell HedgeDoc-image
|
||||
########################################
|
||||
FROM quay.io/hedgedoc/hedgedoc:1.10.5
|
||||
|
||||
USER root
|
||||
|
||||
# Ers??tt upstream-koden
|
||||
RUN rm -rf /hedgedoc
|
||||
|
||||
# Kopiera f??rdigbyggd app med r??tt UID/GID
|
||||
COPY --from=builder --chown=10000:10000 /build /hedgedoc
|
||||
|
||||
USER 10000
|
||||
18
README.md
18
README.md
@@ -1,3 +1,21 @@
|
||||
# HedgeDoc-HedgeAgent
|
||||
|
||||
This is a customized version that makes it possible to invite an AI agent to a note via the menu. "Invite Agent" sends the `note_id` to hedgeagent.
|
||||
|
||||
To start an instance for development, the following is required:
|
||||
1. ```cp config.json.example config.json ```
|
||||
2. Update ```"domain": "change this" ```
|
||||
3. ```.yarn/releases/yarn-4.12.0.cjs install```
|
||||
4. ```.yarn/releases/yarn-4.12.0.cjs run build```
|
||||
5. ```.yarn/releases/yarn-4.12.0.cjs start```
|
||||
|
||||
To start for production:
|
||||
1. `docker compose up -d`
|
||||
|
||||
Note: Use UID 10000 for data folders.
|
||||
|
||||
---
|
||||
|
||||

|
||||
|
||||
# HedgeDoc
|
||||
|
||||
2
app.js
2
app.js
@@ -274,7 +274,7 @@ 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/userRouter').default)
|
||||
app.use(require('./lib/web/imageRouter').default)
|
||||
app.use(require('./lib/web/note/router'))
|
||||
|
||||
|
||||
50
docker-compose.yaml
Normal file
50
docker-compose.yaml
Normal file
@@ -0,0 +1,50 @@
|
||||
services:
|
||||
database:
|
||||
image: postgres:13.4-alpine
|
||||
environment:
|
||||
- POSTGRES_USER=hedgedoc
|
||||
- POSTGRES_PASSWORD=password
|
||||
- POSTGRES_DB=hedgedoc
|
||||
volumes:
|
||||
- ./db:/var/lib/postgresql/data
|
||||
restart: always
|
||||
networks:
|
||||
- internal
|
||||
|
||||
app:
|
||||
build: .
|
||||
image: hedgedoc-hedgeagent:1.10.5
|
||||
container_name: hedgedoc
|
||||
environment:
|
||||
CMD_DB_URL: postgres://hedgedoc:password@database:5432/hedgedoc
|
||||
CMD_PORT: "3000"
|
||||
CMD_HOST: "0.0.0.0"
|
||||
CMD_DOMAIN: hedgedoc.sa6anw.se
|
||||
CMD_URL_ADDPORT: "false"
|
||||
CMD_PROTOCOL_USESSL: "true"
|
||||
CMD_EMAIL: "true"
|
||||
CMD_ALLOW_EMAIL_REGISTER: "true"
|
||||
volumes:
|
||||
- ./uploads:/hedgedoc/public/uploads
|
||||
restart: always
|
||||
depends_on:
|
||||
- database
|
||||
# Since I use Caddy I don't need this
|
||||
# ports:
|
||||
# - "3000:3000"
|
||||
|
||||
## If you use Caddy like I do keep below
|
||||
networks:
|
||||
- internal
|
||||
- proxy
|
||||
|
||||
labels:
|
||||
caddy: hedgedoc.sa6anw.se
|
||||
caddy.reverse_proxy: "{{upstreams 3000}}"
|
||||
|
||||
networks:
|
||||
internal:
|
||||
internal: true
|
||||
proxy:
|
||||
external: true
|
||||
## If you don't, you can deleta all of this
|
||||
@@ -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.11.1
|
||||
version: 1.12.0
|
||||
contact:
|
||||
name: HedgeDoc on GitHub
|
||||
url: https://github.com/hedgedoc/hedgedoc
|
||||
|
||||
@@ -19,7 +19,7 @@ The easiest way to get started with HedgeDoc and Docker is to use the following
|
||||
version: '3'
|
||||
services:
|
||||
database:
|
||||
image: postgres:17.7-alpine
|
||||
image: postgres:18.6-alpine
|
||||
environment:
|
||||
- POSTGRES_USER=hedgedoc
|
||||
- POSTGRES_PASSWORD=password
|
||||
@@ -29,7 +29,7 @@ services:
|
||||
restart: always
|
||||
app:
|
||||
# Make sure to use the latest release from https://hedgedoc.org/latest-release
|
||||
image: quay.io/hedgedoc/hedgedoc:1.11.1
|
||||
image: quay.io/hedgedoc/hedgedoc:1.12.0
|
||||
environment:
|
||||
- CMD_DB_URL=postgres://hedgedoc:password@database:5432/hedgedoc
|
||||
- CMD_DOMAIN=localhost
|
||||
|
||||
@@ -19,7 +19,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.11.1 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.12.0 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
|
||||
@@ -61,7 +61,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.11.1`</small>
|
||||
<small>If you use Git, you can check out the new tag with e.g. `git fetch origin && git checkout 1.12.0`</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 --immutable` and `yarn build`. The extra `yarn install --immutable` is necessary as `bin/setup` does not install the build dependencies.
|
||||
|
||||
@@ -7,7 +7,7 @@ const CspStrategy = {}
|
||||
const defaultDirectives = {
|
||||
defaultSrc: ['\'none\''],
|
||||
baseUri: ['\'self\''],
|
||||
connectSrc: ['\'self\'', buildDomainOriginWithProtocol(config, 'ws'), 'https://vimeo.com/api/v2/video/'],
|
||||
connectSrc: ['\'self\'', buildDomainOriginWithProtocol(config, 'ws'), 'https://vimeo.com/api/v2/video/', 'https://hedgeagent.sa6anw.se/add_note'],
|
||||
fontSrc: ['\'self\''],
|
||||
manifestSrc: ['\'self\''],
|
||||
frameSrc: ['\'self\'', 'https://player.vimeo.com', 'https://www.youtube.com', 'https://gist.github.com'],
|
||||
|
||||
@@ -130,9 +130,9 @@ imageRouter.post('/uploadimage', function (req, res) {
|
||||
logger.error(`Image upload error: formidable error: ${err}`)
|
||||
rimraf.sync(tmpDir)
|
||||
return errors.errorForbidden(res)
|
||||
} else if (!files.image || !files.image.length < 1 || !files.image[0].filepath) {
|
||||
} else if (!files.image || files.image.length < 1 || !files.image[0].filepath) {
|
||||
logger.debug(`${JSON.stringify(files)}`)
|
||||
logger.error('Image upload error: Upload didn\'t contain file)')
|
||||
logger.error('Image upload error: Upload didn\'t contain file')
|
||||
rimraf.sync(tmpDir)
|
||||
return errors.errorBadRequest(res)
|
||||
} else if (!(await checkUploadType(files.image[0].filepath))) {
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
'use strict'
|
||||
|
||||
const archiver = require('archiver')
|
||||
import { ZipArchive } from 'archiver'
|
||||
import { createRequire } from 'module'
|
||||
const require = createRequire(import.meta.url)
|
||||
|
||||
const sanitizeFilename = require('sanitize-filename')
|
||||
const async = require('async')
|
||||
const Router = require('express').Router
|
||||
@@ -11,7 +14,8 @@ const models = require('../models')
|
||||
const logger = require('../logger')
|
||||
const { generateAvatar } = require('../letter-avatars')
|
||||
|
||||
const UserRouter = module.exports = Router()
|
||||
const UserRouter = Router()
|
||||
export default UserRouter
|
||||
|
||||
// get me info
|
||||
UserRouter.get('/me', function (req, res) {
|
||||
@@ -71,7 +75,7 @@ UserRouter.get('/me/delete/:token?', function (req, res) {
|
||||
UserRouter.get('/me/export', function (req, res) {
|
||||
if (req.isAuthenticated()) {
|
||||
// let output = fs.createWriteStream(__dirname + '/example.zip');
|
||||
const archive = archiver('zip', {
|
||||
const archive = new ZipArchive({
|
||||
zlib: { level: 3 } // Sets the compression level.
|
||||
})
|
||||
res.setHeader('Content-Type', 'application/zip')
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
"Extra": "Extra",
|
||||
"Revision": "Revision",
|
||||
"Slide Mode": "Slide Mode",
|
||||
"Invite Agent": "Invite Agent",
|
||||
"Export": "Export",
|
||||
"Import": "Import",
|
||||
"Clipboard": "Clipboard",
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
"Extra": "Extra",
|
||||
"Revision": "Revision",
|
||||
"Slide Mode": "Slide Mode",
|
||||
"Invite Agent": "Invite Agent",
|
||||
"Export": "Exportera",
|
||||
"Import": "Importera",
|
||||
"Clipboard": "Urklipp",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "HedgeDoc",
|
||||
"version": "1.11.1",
|
||||
"version": "1.12.0",
|
||||
"description": "The best platform to write and share markdown.",
|
||||
"main": "app.js",
|
||||
"license": "AGPL-3.0",
|
||||
@@ -21,7 +21,7 @@
|
||||
"@node-saml/passport-saml": "5.1.0",
|
||||
"@passport-next/passport-openid": "1.0.0",
|
||||
"Idle.Js": "git+https://github.com/shawnmclean/Idle.js#commit=2b57cc6e49d177b7ddce0cca00ef5cbe07453541",
|
||||
"archiver": "7.0.1",
|
||||
"archiver": "8.0.0",
|
||||
"async": "3.2.6",
|
||||
"aws-sdk": "2.1693.0",
|
||||
"azure-storage": "2.10.7",
|
||||
@@ -55,7 +55,7 @@
|
||||
"lutim": "1.0.3",
|
||||
"lz-string": "git+https://github.com/hackmdio/lz-string.git#commit=6edfccb79cd8c210f03fd3bf18e41ca144fbeefb",
|
||||
"mariadb": "3.5.3",
|
||||
"markdown-it": "14.1.1",
|
||||
"markdown-it": "14.3.0",
|
||||
"markdown-it-abbr": "2.0.0",
|
||||
"markdown-it-container": "4.0.0",
|
||||
"markdown-it-deflist": "4.0.0",
|
||||
@@ -102,7 +102,7 @@
|
||||
"store": "2.0.12",
|
||||
"toobusy-js": "0.5.1",
|
||||
"umzug": "3.8.3",
|
||||
"uuid": "11.1.1",
|
||||
"uuid": "14.0.2",
|
||||
"validator": "13.15.35",
|
||||
"winston": "3.19.0",
|
||||
"xss": "1.0.15"
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
# Release Notes
|
||||
|
||||
## <i class="fa fa-tag"></i> 1.x.x <i class="fa fa-calendar-o"></i> UNRELEASED
|
||||
## <i class="fa fa-tag"></i> 1.12.0 <i class="fa fa-calendar-o"></i> 2026-08-21
|
||||
|
||||
### Important changes
|
||||
|
||||
⚠️ **HedgeDoc 1.12.0 and onwards will require Node 20.17 or later in order to run.**
|
||||
Since Node 18 security support was stopped over one year ago, we don't maintain backwards-compatability for that anymore.
|
||||
|
||||
Some syntax highlighting languages have been removed and/or changed. You can find more information in
|
||||
[the highlight.js docs](https://highlightjs.readthedocs.io/en/latest/upgrade-11.html#built-in-set-of-common-languages).
|
||||
|
||||
### Enhancements
|
||||
|
||||
@@ -8,9 +16,14 @@
|
||||
|
||||
### Bugfixes
|
||||
|
||||
- All links will be opened in new tabs instead of the same tab as the note. This was changed when the external link warning was implemented and now the old behavior is restored.
|
||||
- All links will be opened in new tabs instead of the same tab as the note. This was changed when the external link warning was implemented and now the old behavior is restored
|
||||
- Fixed multiple bugs in the realtime connection handling that could lead to data-loss of users with a flaky connection
|
||||
|
||||
### Contributors
|
||||
|
||||
- [Tony Chau](https://github.com/fo5for)
|
||||
- [Lars Kiesow](https://github.com/lkiesow)
|
||||
|
||||
## <i class="fa fa-tag"></i> 1.11.1 <i class="fa fa-calendar-o"></i> 2026-07-24
|
||||
|
||||
### Security fixes
|
||||
|
||||
@@ -1207,6 +1207,23 @@ ui.toolbar.publish.attr('href', noteurl + '/publish')
|
||||
// extra
|
||||
// slide
|
||||
ui.toolbar.extra.slide.attr('href', noteurl + '/slide')
|
||||
|
||||
// invite agent
|
||||
ui.toolbar.extra.inviteAgent.click(function (e) {
|
||||
e.preventDefault()
|
||||
|
||||
$.ajax({
|
||||
url: 'https://hedgeagent.sa6anw.se/add_note',
|
||||
type: 'POST',
|
||||
contentType: 'application/json',
|
||||
data: JSON.stringify({ note_id: noteid }),
|
||||
error: function (xhr, status, err) {
|
||||
console.error('Invite agent failed:', status, err)
|
||||
alert('Failed to invite agent.')
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
// download
|
||||
// markdown
|
||||
ui.toolbar.download.markdown.click(function (e) {
|
||||
|
||||
@@ -12,7 +12,8 @@ export const getUIElements = () => ({
|
||||
publish: $('.ui-publish'),
|
||||
extra: {
|
||||
revision: $('.ui-extra-revision'),
|
||||
slide: $('.ui-extra-slide')
|
||||
slide: $('.ui-extra-slide'),
|
||||
inviteAgent: $('.ui-invite-agent')
|
||||
},
|
||||
download: {
|
||||
markdown: $('.ui-download-markdown'),
|
||||
|
||||
@@ -34,6 +34,8 @@
|
||||
</li>
|
||||
<li role="presentation"><a role="menuitem" class="ui-extra-slide" tabindex="-1" href="#" target="_blank" rel="noopener"><i class="fa fa-tv fa-fw"></i> <%= __('Slide Mode') %></a>
|
||||
</li>
|
||||
<li role="presentation"><a role="menuitem" class="ui-invite-agent" tabindex="-1" href="#"><i class="fa fa-robot fa-fw"></i> <%= __('Invite Agent') %></a>
|
||||
</li>
|
||||
<% if(enableGitHubGist || enableDropBoxSave || enableGitlabSnippets) { %>
|
||||
<li class="divider"></li>
|
||||
<li class="dropdown-header"><%= __('Export') %></li>
|
||||
@@ -136,6 +138,8 @@
|
||||
</li>
|
||||
<li role="presentation"><a role="menuitem" class="ui-extra-slide" tabindex="-1" href="#" target="_blank" rel="noopener"><i class="fa fa-tv fa-fw"></i> <%= __('Slide Mode') %></a>
|
||||
</li>
|
||||
<li role="presentation"><a role="menuitem" class="ui-invite-agent" tabindex="-1" href="#"><i class="fa fa-robot fa-fw"></i> <%= __('Invite Agent') %></a>
|
||||
</li>
|
||||
<% if(enableGitHubGist || enableDropBoxSave || enableGitlabSnippets) { %>
|
||||
<li class="divider"></li>
|
||||
<li class="dropdown-header"><%= __('Export') %></li>
|
||||
|
||||
Reference in New Issue
Block a user