Compare commits

..

10 Commits

Author SHA1 Message Date
Maksim Eltyshev
2685e5d5fc chore: Update version 2026-03-01 16:53:11 +01:00
Maksim Eltyshev
5ebe320396 chore: Update dependencies 2026-03-01 16:42:19 +01:00
Maksim Eltyshev
66ff3b65c6 fix(proxy): Prevent external access to outgoing proxy in host-network mode 2026-03-01 15:57:12 +01:00
Maksim Eltyshev
d5d3f1de44 chore: Update version 2026-02-23 18:44:06 +01:00
Maksim Eltyshev
4e9e842e3d chore: Update server dependencies 2026-02-23 18:12:14 +01:00
Fabian Reinold
605dcace54 fix(gravatar): Update hash algorithm to SHA-256 for improved security (#1550) 2026-02-23 16:59:55 +01:00
SnoozeFreddo
61753f08eb fix(helm): Add writable temp directory mounts when readOnlyRootFilesystem is enabled (#1542) 2026-02-20 16:18:30 +01:00
Maksim Eltyshev
52c96c6c8f fix(platform): Make app compatible with Windows 2026-02-19 20:15:28 +01:00
Maksim Eltyshev
2a1760393f fix(dropzone): Prevent dropzone from overflowing content 2026-02-19 17:09:21 +01:00
seals187
7758312e05 fix(backup): Improve backup/restore scripts, allow specifying backup directory (#1541) 2026-02-19 13:13:12 +01:00
24 changed files with 1811 additions and 1795 deletions

View File

@@ -15,13 +15,13 @@ type: application
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 2.0.1
version: 2.0.3
# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
# It is recommended to use it with quotes.
appVersion: "2.0.1"
appVersion: "2.0.3"
dependencies:
- alias: postgresql

View File

@@ -70,6 +70,12 @@ spec:
- mountPath: /app/logs
subPath: app-logs
name: emptydir
- mountPath: /app/.tmp
subPath: app-tmp
name: emptydir
- mountPath: /tmp
subPath: tmp
name: emptydir
{{- end }}
{{- /* Extra volume mounts */}}
{{- range .Values.extraMounts }}

1446
client/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -89,12 +89,12 @@
"dependencies": {
"@ballerina/highlightjs-ballerina": "^1.0.1",
"@diplodoc/cut-extension": "^1.1.1",
"@diplodoc/transform": "^4.64.1",
"@diplodoc/transform": "^4.70.0",
"@gravity-ui/components": "^4.18.0",
"@gravity-ui/markdown-editor": "^15.31.0",
"@gravity-ui/uikit": "^7.31.1",
"@gravity-ui/markdown-editor": "^15.34.4",
"@gravity-ui/uikit": "^7.32.0",
"@juggle/resize-observer": "^3.4.0",
"@vitejs/plugin-react": "^5.1.3",
"@vitejs/plugin-react": "^5.1.4",
"browserslist-to-esbuild": "^2.1.1",
"classnames": "^2.5.1",
"date-fns": "^4.1.0",
@@ -123,10 +123,10 @@
"highlightjs-zenscript": "^2.0.0",
"hightlightjs-papyrus": "^0.0.4",
"history": "^5.3.0",
"i18next": "^25.8.1",
"i18next-browser-languagedetector": "^8.2.0",
"i18next": "^25.8.13",
"i18next-browser-languagedetector": "^8.2.1",
"initials": "^3.1.2",
"javascript-time-ago": "^2.6.2",
"javascript-time-ago": "^2.6.4",
"js-cookie": "^3.0.5",
"jwt-decode": "^4.0.0",
"linkify-react": "^4.3.2",
@@ -143,18 +143,18 @@
"react-beautiful-dnd": "^13.1.1",
"react-datepicker": "^9.1.0",
"react-dom": "18.2.0",
"react-dropzone": "^14.4.0",
"react-dropzone": "^15.0.0",
"react-frame-component": "^5.2.7",
"react-hot-toast": "^2.6.0",
"react-i18next": "^16.5.4",
"react-input-mask": "^2.0.4",
"react-intersection-observer": "^10.0.2",
"react-intersection-observer": "^10.0.3",
"react-mentions": "^4.4.10",
"react-photoswipe-gallery": "^4.0.0",
"react-redux": "^9.2.0",
"react-router": "^7.13.0",
"react-router": "^7.13.1",
"react-textarea-autosize": "^8.5.9",
"react-time-ago": "^7.4.1",
"react-time-ago": "^7.4.4",
"redux": "^5.0.1",
"redux-logger": "^3.0.6",
"redux-orm": "^0.16.2",
@@ -174,9 +174,9 @@
"devDependencies": {
"@babel/eslint-parser": "^7.28.6",
"@babel/preset-env": "^7.29.0",
"@cucumber/cucumber": "^12.6.0",
"@cucumber/pretty-formatter": "^3.0.0",
"@playwright/test": "^1.58.1",
"@cucumber/cucumber": "^12.7.0",
"@cucumber/pretty-formatter": "^3.2.0",
"@playwright/test": "^1.58.2",
"babel-jest": "^30.2.0",
"babel-preset-airbnb": "^5.0.0",
"eslint": "^8.57.1",
@@ -188,7 +188,7 @@
"eslint-plugin-react": "^7.37.5",
"eslint-plugin-react-hooks": "^4.6.2",
"jest": "^30.2.0",
"playwright": "^1.58.0",
"playwright": "^1.58.2",
"prettier": "3.8.1"
}
}

View File

@@ -1,8 +1,8 @@
diff --git a/node_modules/@diplodoc/transform/lib/md.js b/node_modules/@diplodoc/transform/lib/md.js
index a2d222e..8d1377e 100644
index c9faa96..e4bef9b 100644
--- a/node_modules/@diplodoc/transform/lib/md.js
+++ b/node_modules/@diplodoc/transform/lib/md.js
@@ -101,8 +101,12 @@ function initPlugins(md, options, pluginOptions) {
@@ -107,8 +107,12 @@ function initPlugins(md, options, pluginOptions) {
}
md.use(ol_attr_conversion_1.olAttrConversion);
plugins.forEach((plugin) => md.use(plugin, pluginOptions));

View File

@@ -1,8 +1,8 @@
diff --git a/node_modules/@gravity-ui/markdown-editor/build/esm/bundle/wysiwyg-preset.js b/node_modules/@gravity-ui/markdown-editor/build/esm/bundle/wysiwyg-preset.js
index dec01f0..a80b857 100644
index c0d13c3..4c6e4e9 100644
--- a/node_modules/@gravity-ui/markdown-editor/build/esm/bundle/wysiwyg-preset.js
+++ b/node_modules/@gravity-ui/markdown-editor/build/esm/bundle/wysiwyg-preset.js
@@ -102,7 +102,6 @@ export const BundlePreset = (builder, opts) => {
@@ -107,7 +107,6 @@ export const BundlePreset = (builder, opts) => {
enableNewImageSizeCalculation: opts.enableNewImageSizeCalculation,
...opts.imgSize,
},
@@ -10,7 +10,7 @@ index dec01f0..a80b857 100644
deflist: {
deflistTermPlaceholder: () => i18nPlaceholder('deflist_term'),
deflistDescPlaceholder: () => i18nPlaceholder('deflist_desc'),
@@ -123,11 +122,6 @@ export const BundlePreset = (builder, opts) => {
@@ -128,11 +127,6 @@ export const BundlePreset = (builder, opts) => {
...opts.yfmTable,
controls: opts.mobile ? false : opts.yfmTable?.controls,
},
@@ -36,6 +36,23 @@ index 8aefe20..99e59e3 100644
}
if (options.pmTransformers) {
this.#pmTransformers = options.pmTransformers;
diff --git a/node_modules/@gravity-ui/markdown-editor/build/esm/extensions/markdown/CodeBlock/CodeBlockHighlight/TooltipPlugin/index.js b/node_modules/@gravity-ui/markdown-editor/build/esm/extensions/markdown/CodeBlock/CodeBlockHighlight/TooltipPlugin/index.js
index 5eec9bb..3abd31a 100644
--- a/node_modules/@gravity-ui/markdown-editor/build/esm/extensions/markdown/CodeBlock/CodeBlockHighlight/TooltipPlugin/index.js
+++ b/node_modules/@gravity-ui/markdown-editor/build/esm/extensions/markdown/CodeBlock/CodeBlockHighlight/TooltipPlugin/index.js
@@ -75,12 +75,6 @@ export const codeLangSelectTooltipViewCreator = (view, langItems, mapping = {},
dispatch: view.dispatch,
}),
},
- {
- id: 'code-block-copy',
- type: ToolbarDataType.ReactNodeFn,
- width: 28,
- content: () => _jsx(ClipboardButton, { text: node.textContent }),
- },
].filter(isTruthy),
[
{
diff --git a/node_modules/@gravity-ui/markdown-editor/build/esm/extensions/yfm/YfmNote/YfmNoteSpecs/index.js b/node_modules/@gravity-ui/markdown-editor/build/esm/extensions/yfm/YfmNote/YfmNoteSpecs/index.js
index 212c583..b709383 100644
--- a/node_modules/@gravity-ui/markdown-editor/build/esm/extensions/yfm/YfmNote/YfmNoteSpecs/index.js

View File

@@ -1,4 +1,19 @@
# [2.0.1] - 2026-02-17
# [2.0.3] - 2026-03-01
### Fixed
* Improve security by ensuring the outgoing proxy is not accessible from outside
## [2.0.2] - 2026-02-23
### Fixed
* Prevent dropzone from overflowing content
* Update Gravatar hash algorithm
* Improve backup and restore scripts
* Improve installation on Windows and containerized environments
## [2.0.1] - 2026-02-17
### Fixed

View File

@@ -132,7 +132,11 @@ const AddAttachmentZone = React.memo(({ children }) => {
<>
{/* eslint-disable-next-line react/jsx-props-no-spreading */}
<div {...getRootProps()}>
{isDragActive && <div className={styles.dropzone}>{t('common.dropFileToUpload')}</div>}
{isDragActive && (
<div className={styles.dropzone}>
<div className={styles.dropzoneText}>{t('common.dropFileToUpload')}</div>
</div>
)}
{children}
{/* eslint-disable-next-line react/jsx-props-no-spreading */}
<input {...getInputProps()} />

View File

@@ -8,13 +8,18 @@
background: white;
font-size: 20px;
font-weight: bold;
height: 100%;
inset: 0;
line-height: 30px;
opacity: 0.7;
padding: 200px 50px;
position: absolute;
text-align: center;
width: 100%;
z-index: 2001;
}
.dropzoneText {
left: 50%;
position: absolute;
top: min(200px, 50%);
transform: translateX(-50%) translateY(-50%);
}
}

View File

@@ -68,7 +68,11 @@ const AddImageZone = React.memo(({ children, onCreate }) => {
return (
/* eslint-disable-next-line react/jsx-props-no-spreading */
<div {...getRootProps()}>
{isDragActive && <div className={styles.dropzone}>{t('common.dropFileToUpload')}</div>}
{isDragActive && (
<div className={styles.dropzone}>
<div className={styles.dropzoneText}>{t('common.dropFileToUpload')}</div>
</div>
)}
{children}
{/* eslint-disable-next-line react/jsx-props-no-spreading */}
<input {...getInputProps()} />

View File

@@ -8,13 +8,18 @@
background: white;
font-size: 20px;
font-weight: bold;
height: 100%;
inset: 0;
line-height: 30px;
opacity: 0.7;
padding-top: 200px;
position: absolute;
text-align: center;
width: 100%;
z-index: 2001;
}
.dropzoneText {
left: 50%;
position: absolute;
top: min(200px, 50%);
transform: translateX(-50%) translateY(-50%);
}
}

View File

@@ -1 +1 @@
export default '2.0.1';
export default '2.0.3';

View File

@@ -1,13 +1,22 @@
#!/bin/bash
# Stop on Error
# Stop on error
set -e
# Configure those to match your PLANKA Docker container names
PLANKA_DOCKER_CONTAINER_POSTGRES="planka-postgres-1"
PLANKA_DOCKER_CONTAINER_PLANKA="planka-planka-1"
# Configure those to match your Docker container names
DOCKER_CONTAINER_POSTGRES="planka-postgres-1"
DOCKER_CONTAINER_PLANKA="planka-planka-1"
# Use provided directory or default to current directory
BACKUP_DIR="${1:-$(pwd)}"
if [ -z "$1" ]; then
echo "No backup directory specified, backing up to current directory: $BACKUP_DIR"
else
echo "Backing up to: $BACKUP_DIR"
fi
echo
# Create Temporary folder
if date --version >/dev/null 2>&1; then
# GNU date (Linux)
BACKUP_DATETIME=$(date --utc +%FT%H-%M-%SZ)
@@ -15,28 +24,30 @@ else
# BSD date (macOS)
BACKUP_DATETIME=$(date -u +%FT%H-%M-%SZ)
fi
mkdir -p "$BACKUP_DATETIME-backup"
# Dump DB into SQL File
BACKUP_TEMP="$BACKUP_DIR/$BACKUP_DATETIME-backup"
# Create temporary directory
mkdir -p "$BACKUP_TEMP"
echo -n "Exporting postgres database ... "
docker exec -t "$PLANKA_DOCKER_CONTAINER_POSTGRES" pg_dumpall -c -U postgres > "$BACKUP_DATETIME-backup/postgres.sql"
docker exec -t "$DOCKER_CONTAINER_POSTGRES" pg_dumpall -c -U postgres > "$BACKUP_TEMP/postgres.sql"
echo "Success!"
echo
# Export Docker Volume
echo -n "Exporting data volume ... "
docker run --rm --volumes-from "$PLANKA_DOCKER_CONTAINER_PLANKA" -v "$(pwd)/$BACKUP_DATETIME-backup:/backup" ubuntu cp -r /app/data /backup/data
docker run --rm --volumes-from "$DOCKER_CONTAINER_PLANKA" -v "$BACKUP_TEMP:/backup" node:22-alpine cp -r /app/data /backup/data
echo "Success!"
echo
# Create tgz
echo -n "Creating final tarball $BACKUP_DATETIME-backup.tgz ... "
tar -czf "$BACKUP_DATETIME-backup.tgz" \
"$BACKUP_DATETIME-backup/postgres.sql" \
"$BACKUP_DATETIME-backup/data"
tar -C "$BACKUP_DIR" -czf "$BACKUP_TEMP.tgz" "$BACKUP_DATETIME-backup"
echo "Success!"
echo
# Remove source files
echo -n "Cleaning up temporary files and folders ... "
rm -rf "$BACKUP_DATETIME-backup"
echo -n "Cleaning up temporary files and directories ... "
rm -rf "$BACKUP_TEMP"
echo "Success!"
echo
echo "Backup Complete!"

View File

@@ -1,31 +1,41 @@
#!/bin/bash
# Stop on Error
# Stop on error
set -e
# Configure those to match your PLANKA Docker container names
PLANKA_DOCKER_CONTAINER_POSTGRES="planka-postgres-1"
PLANKA_DOCKER_CONTAINER_PLANKA="planka-planka-1"
# Configure those to match your Docker container names
DOCKER_CONTAINER_POSTGRES="planka-postgres-1"
DOCKER_CONTAINER_PLANKA="planka-planka-1"
# Extract tgz archive
PLANKA_BACKUP_ARCHIVE_TGZ=$1
PLANKA_BACKUP_ARCHIVE=$(basename "$PLANKA_BACKUP_ARCHIVE_TGZ" .tgz)
echo -n "Extracting tarball $PLANKA_BACKUP_ARCHIVE_TGZ ... "
tar -xzf "$PLANKA_BACKUP_ARCHIVE_TGZ"
# Use provided archive
BACKUP_ARCHIVE="$1"
if [ -z "$BACKUP_ARCHIVE" ]; then
echo "Usage: $0 <backup-archive.tgz>"
exit 1
fi
BACKUP_DIR=$(dirname "$BACKUP_ARCHIVE")
BACKUP_TEMP="$BACKUP_DIR/$(basename "$BACKUP_ARCHIVE" .tgz)"
echo -n "Extracting tarball $BACKUP_ARCHIVE ... "
tar -C "$BACKUP_DIR" -xzf "$BACKUP_ARCHIVE"
echo "Success!"
echo
# Import Database
echo -n "Importing postgres database ... "
cat "$PLANKA_BACKUP_ARCHIVE/postgres.sql" | docker exec -i "$PLANKA_DOCKER_CONTAINER_POSTGRES" psql -U postgres
cat "$BACKUP_TEMP/postgres.sql" | docker exec -i "$DOCKER_CONTAINER_POSTGRES" psql -U postgres
echo "Success!"
echo
# Restore Docker Volume
echo -n "Importing data volume ... "
docker run --rm --volumes-from "$PLANKA_DOCKER_CONTAINER_PLANKA" -v "$(pwd)/$PLANKA_BACKUP_ARCHIVE:/backup" ubuntu cp -rf /backup/data/. /app/data
docker run --rm --user root --volumes-from "$DOCKER_CONTAINER_PLANKA" -v "$BACKUP_TEMP:/backup" node:22-alpine sh -c "cp -rf /backup/data/. /app/data && chown -R node:node /app/data/*"
echo "Success!"
echo
echo -n "Cleaning up temporary files and folders ... "
rm -r "$PLANKA_BACKUP_ARCHIVE"
echo -n "Cleaning up temporary files and directories ... "
rm -r "$BACKUP_TEMP"
echo "Success!"
echo
echo "Restore complete!"

144
package-lock.json generated
View File

@@ -1,24 +1,24 @@
{
"name": "planka",
"version": "2.0.1",
"version": "2.0.3",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "planka",
"version": "2.0.1",
"version": "2.0.3",
"hasInstallScript": true,
"dependencies": {
"concurrently": "^9.2.1",
"genversion": "^3.2.0",
"husky": "^9.1.7",
"lint-staged": "^16.2.7"
"lint-staged": "^16.3.1"
}
},
"node_modules/ansi-escapes": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.2.0.tgz",
"integrity": "sha512-g6LhBsl+GBPRWGWsBtutpzBYuIIdBkLEvad5C/va/74Db018+5TZiyA26cZJAr3Rft5lprVqOIPxf5Vid6tqAw==",
"version": "7.3.0",
"resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.3.0.tgz",
"integrity": "sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg==",
"license": "MIT",
"dependencies": {
"environment": "^1.0.0"
@@ -134,13 +134,13 @@
}
},
"node_modules/cli-truncate": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-5.1.1.tgz",
"integrity": "sha512-SroPvNHxUnk+vIW/dOSfNqdy1sPEFkrTk6TUtqLCnBlo3N7TNYYkzzN7uSD6+jVjrdO4+p8nH7JzH6cIvUem6A==",
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-5.2.0.tgz",
"integrity": "sha512-xRwvIOMGrfOAnM1JYtqQImuaNtDEv9v6oIYAs4LIHwTiKee8uwvIi363igssOC0O5U04i4AlENs79LQLu9tEMw==",
"license": "MIT",
"dependencies": {
"slice-ansi": "^7.1.0",
"string-width": "^8.0.0"
"slice-ansi": "^8.0.0",
"string-width": "^8.2.0"
},
"engines": {
"node": ">=20"
@@ -330,9 +330,9 @@
"license": "MIT"
},
"node_modules/filelist": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz",
"integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==",
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.6.tgz",
"integrity": "sha512-5giy2PkLYY1cP39p17Ech+2xlpTRL9HLspOfEgm0L6CwBXBTgsK5ou0JtzYuepxkaQ/tvhCFIJ5uXo0OrM2DxA==",
"license": "Apache-2.0",
"dependencies": {
"minimatch": "^5.0.1"
@@ -386,9 +386,9 @@
}
},
"node_modules/get-east-asian-width": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.4.0.tgz",
"integrity": "sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==",
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.5.0.tgz",
"integrity": "sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA==",
"license": "MIT",
"engines": {
"node": ">=18"
@@ -463,18 +463,17 @@
}
},
"node_modules/lint-staged": {
"version": "16.2.7",
"resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-16.2.7.tgz",
"integrity": "sha512-lDIj4RnYmK7/kXMya+qJsmkRFkGolciXjrsZ6PC25GdTfWOAWetR0ZbsNXRAj1EHHImRSalc+whZFg56F5DVow==",
"version": "16.3.1",
"resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-16.3.1.tgz",
"integrity": "sha512-bqvvquXzFBAlSbluugR4KXAe4XnO/QZcKVszpkBtqLWa2KEiVy8n6Xp38OeUbv/gOJOX4Vo9u5pFt/ADvbm42Q==",
"license": "MIT",
"dependencies": {
"commander": "^14.0.2",
"commander": "^14.0.3",
"listr2": "^9.0.5",
"micromatch": "^4.0.8",
"nano-spawn": "^2.0.0",
"pidtree": "^0.6.0",
"string-argv": "^0.3.2",
"yaml": "^2.8.1"
"tinyexec": "^1.0.2",
"yaml": "^2.8.2"
},
"bin": {
"lint-staged": "bin/lint-staged.js"
@@ -531,6 +530,34 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/log-update/node_modules/ansi-styles": {
"version": "6.2.3",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz",
"integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==",
"license": "MIT",
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
"node_modules/log-update/node_modules/slice-ansi": {
"version": "7.1.2",
"resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.2.tgz",
"integrity": "sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==",
"license": "MIT",
"dependencies": {
"ansi-styles": "^6.2.1",
"is-fullwidth-code-point": "^5.0.0"
},
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/chalk/slice-ansi?sponsor=1"
}
},
"node_modules/micromatch": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
@@ -557,9 +584,9 @@
}
},
"node_modules/minimatch": {
"version": "5.1.6",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
"integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
"version": "5.1.9",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.9.tgz",
"integrity": "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==",
"license": "ISC",
"dependencies": {
"brace-expansion": "^2.0.1"
@@ -568,18 +595,6 @@
"node": ">=10"
}
},
"node_modules/nano-spawn": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/nano-spawn/-/nano-spawn-2.0.0.tgz",
"integrity": "sha512-tacvGzUY5o2D8CBh2rrwxyNojUsZNU2zjNTzKQrkgGJQTbGAfArVWXSKMBokBeeg6C7OLRGUEyoFlYbfeWQIqw==",
"license": "MIT",
"engines": {
"node": ">=20.17"
},
"funding": {
"url": "https://github.com/sindresorhus/nano-spawn?sponsor=1"
}
},
"node_modules/onetime": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz",
@@ -631,18 +646,6 @@
"url": "https://github.com/sponsors/jonschlinkert"
}
},
"node_modules/pidtree": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.6.0.tgz",
"integrity": "sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==",
"license": "MIT",
"bin": {
"pidtree": "bin/pidtree.js"
},
"engines": {
"node": ">=0.10"
}
},
"node_modules/require-directory": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
@@ -708,16 +711,16 @@
}
},
"node_modules/slice-ansi": {
"version": "7.1.2",
"resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.2.tgz",
"integrity": "sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==",
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-8.0.0.tgz",
"integrity": "sha512-stxByr12oeeOyY2BlviTNQlYV5xOj47GirPr4yA1hE9JCtxfQN0+tVbkxwCtYDQWhEKWFHsEK48ORg5jrouCAg==",
"license": "MIT",
"dependencies": {
"ansi-styles": "^6.2.1",
"is-fullwidth-code-point": "^5.0.0"
"ansi-styles": "^6.2.3",
"is-fullwidth-code-point": "^5.1.0"
},
"engines": {
"node": ">=18"
"node": ">=20"
},
"funding": {
"url": "https://github.com/chalk/slice-ansi?sponsor=1"
@@ -745,13 +748,13 @@
}
},
"node_modules/string-width": {
"version": "8.1.1",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-8.1.1.tgz",
"integrity": "sha512-KpqHIdDL9KwYk22wEOg/VIqYbrnLeSApsKT/bSj6Ez7pn3CftUiLAv2Lccpq1ALcpLV9UX1Ppn92npZWu2w/aw==",
"version": "8.2.0",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-8.2.0.tgz",
"integrity": "sha512-6hJPQ8N0V0P3SNmP6h2J99RLuzrWz2gvT7VnK5tKvrNqJoyS9W4/Fb8mo31UiPvy00z7DQXkP2hnKBVav76thw==",
"license": "MIT",
"dependencies": {
"get-east-asian-width": "^1.3.0",
"strip-ansi": "^7.1.0"
"get-east-asian-width": "^1.5.0",
"strip-ansi": "^7.1.2"
},
"engines": {
"node": ">=20"
@@ -761,12 +764,12 @@
}
},
"node_modules/strip-ansi": {
"version": "7.1.2",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz",
"integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==",
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz",
"integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==",
"license": "MIT",
"dependencies": {
"ansi-regex": "^6.0.1"
"ansi-regex": "^6.2.2"
},
"engines": {
"node": ">=12"
@@ -790,6 +793,15 @@
"url": "https://github.com/chalk/supports-color?sponsor=1"
}
},
"node_modules/tinyexec": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.2.tgz",
"integrity": "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==",
"license": "MIT",
"engines": {
"node": ">=18"
}
},
"node_modules/to-regex-range": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",

View File

@@ -1,6 +1,6 @@
{
"name": "planka",
"version": "2.0.1",
"version": "2.0.3",
"private": true,
"scripts": {
"client:build": "npm run build --prefix client",
@@ -39,6 +39,6 @@
"concurrently": "^9.2.1",
"genversion": "^3.2.0",
"husky": "^9.1.7",
"lint-staged": "^16.2.7"
"lint-staged": "^16.3.1"
}
}

View File

@@ -20,7 +20,7 @@ module.exports = {
return null;
}
const hash = crypto.createHash('md5').update(inputs.record.email).digest('hex');
const hash = crypto.createHash('sha256').update(inputs.record.email).digest('hex');
return `${sails.config.custom.gravatarBaseUrl}${hash}?s=180&d=initials`;
},
};

View File

@@ -4,8 +4,14 @@
*/
const { execFile } = require('child_process');
const path = require('path');
const util = require('util');
const PYTHON_PATH =
process.platform === 'win32'
? path.join(sails.config.appPath, '.venv', 'Scripts', 'python.exe')
: path.join(sails.config.appPath, '.venv', 'bin', 'python');
const promisifyExecFile = util.promisify(execFile);
module.exports = {
@@ -27,9 +33,9 @@ module.exports = {
async fn(inputs) {
try {
await promisifyExecFile(
`${sails.config.appPath}/.venv/bin/python3`,
PYTHON_PATH,
[
`${sails.config.appPath}/utils/send_notifications.py`,
path.join(sails.config.appPath, 'utils', 'send_notifications.py'),
JSON.stringify(inputs.services),
inputs.title,
JSON.stringify(inputs.bodyByFormat),

1732
server/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -12,7 +12,7 @@
"db:upgrade": "node db/upgrade.js",
"postinstall": "patch-package && npm run setup-python",
"lint": "eslint . --max-warnings=0 --report-unused-disable-directives && echo '✔ Your .js files look good.'",
"setup-python": "python3 -m venv .venv && .venv/bin/pip3 install -r requirements.txt",
"setup-python": "node setup-python.js",
"start": "nodemon",
"start:prod": "cross-env NODE_ENV=production node app.js --prod",
"swagger:generate": "node generate-swagger.js",
@@ -44,20 +44,17 @@
}
},
"overrides": {
"body-parser": {
"qs": "^6.14.1"
},
"waterline-utils": {
"qs": "^6.14.1"
"qs": "^6.15.0"
}
},
"dependencies": {
"@aws-sdk/client-s3": "^3.982.0",
"@aws-sdk/lib-storage": "^3.982.0",
"@aws-sdk/client-s3": "^3.1000.0",
"@aws-sdk/lib-storage": "^3.1000.0",
"bcrypt": "^6.0.0",
"bytes": "^3.1.2",
"cross-env": "^10.1.0",
"dotenv": "^17.2.3",
"dotenv": "^17.3.1",
"dotenv-cli": "^11.0.0",
"escape-html": "^1.0.3",
"escape-markdown": "^1.0.4",
@@ -74,16 +71,16 @@
"nodemailer": "^7.0.13",
"openid-client": "^5.7.1",
"patch-package": "^8.0.1",
"pg": "^8.18.0",
"pg": "^8.19.0",
"read": "^5.0.1",
"rimraf": "^6.1.2",
"sails": "^1.5.16",
"rimraf": "^6.1.3",
"sails": "^1.5.17",
"sails-hook-orm": "^4.0.3",
"sails-hook-sockets": "^3.0.2",
"sails-postgresql": "^5.0.1",
"serve-static": "^2.2.1",
"sharp": "^0.34.5",
"undici": "^7.21.0",
"undici": "^7.22.0",
"uuid": "^11.1.0",
"validator": "^13.15.26",
"winston": "^3.19.0",
@@ -98,7 +95,7 @@
"eslint-plugin-prettier": "^5.5.5",
"ignore": "^7.0.5",
"mocha": "^11.7.5",
"nodemon": "^3.1.11",
"nodemon": "^3.1.14",
"prettier": "3.8.1",
"supertest": "^7.2.2",
"swagger-jsdoc": "^6.2.8"

28
server/setup-python.js Normal file
View File

@@ -0,0 +1,28 @@
const { spawnSync } = require('child_process');
const path = require('path');
const VENV_PATH = path.join(__dirname, '.venv');
const REQUIREMENTS_PATH = path.join(__dirname, 'requirements.txt');
const PYTHON_PATH =
process.platform === 'win32'
? path.join(VENV_PATH, 'Scripts', 'python.exe')
: path.join(VENV_PATH, 'bin', 'python');
const getSystemPythonCommand = () => {
let result = spawnSync('python3', ['--version'], { stdio: 'ignore' });
if (result.status === 0) return 'python3';
result = spawnSync('python', ['--version'], { stdio: 'ignore' });
if (result.status === 0) return 'python';
throw new Error('Python is not installed or not in PATH');
};
const run = (command, args) => {
const result = spawnSync(command, args, { stdio: 'inherit' });
if (result.status !== 0) process.exit(result.status);
};
run(getSystemPythonCommand(), ['-m', 'venv', VENV_PATH]);
run(PYTHON_PATH, ['-m', 'pip', 'install', '-r', REQUIREMENTS_PATH]);

View File

@@ -41,7 +41,7 @@ start_outgoing_proxy_if_needed() {
# Basic settings
echo "pid_filename $SQUID_PID" >> "$SQUID_CONF"
echo "http_port 3128" >> "$SQUID_CONF"
echo "http_port 127.0.0.1:3128" >> "$SQUID_CONF"
echo "acl all src all" >> "$SQUID_CONF"
# Disable caching
@@ -52,11 +52,11 @@ start_outgoing_proxy_if_needed() {
echo "cache_swap_high 0" >> "$SQUID_CONF"
# Disable logs
echo "access_log /tmp/test.log" >> "$SQUID_CONF"
echo "access_log none" >> "$SQUID_CONF"
echo "cache_store_log none" >> "$SQUID_CONF"
echo "cache_log /dev/null" >> "$SQUID_CONF"
echo "logfile_rotate 0" >> "$SQUID_CONF"
echo "debug_options ALL,1" >> "$SQUID_CONF"
echo "debug_options ALL,0" >> "$SQUID_CONF"
# Make it pass-through like
echo "forwarded_for delete" >> "$SQUID_CONF"
@@ -65,6 +65,10 @@ start_outgoing_proxy_if_needed() {
echo "request_header_access Via deny all" >> "$SQUID_CONF"
echo "request_header_access Cache-Control deny all" >> "$SQUID_CONF"
# Allow only local sources
echo "acl localhost_src src 127.0.0.1" >> "$SQUID_CONF"
echo "http_access deny !localhost_src" >> "$SQUID_CONF"
# Blocked IPs
if [[ -n "${OUTGOING_BLOCKED_IPS:-}" ]]; then
IFS=',' read -ra BLOCKED_IPS <<< "$OUTGOING_BLOCKED_IPS"

View File

@@ -1 +1 @@
module.exports = '2.0.1';
module.exports = '2.0.3';