mirror of
https://github.com/logseq/logseq.git
synced 2026-05-16 17:02:34 +00:00
chore: tech stack upgrade (#12448)
* fix(lint): make worker/frontend separation lint work on Windows * chore: update cljs:electron-watch script to include test flag * chore: remove dead root dependencies * chore(deps): converge better-sqlite3 to 12.6.2 across deps packages * chore(deps): converge fs-extra to ^11.3.0 across package roots * fix(test): correct parameters for create-if-not-exists function * chore(deps): converge cljs-bean to 1.9.0 across deps roots * fix(tests): escape regex in cljs:run-test script * chore: pin root packageManager to yarn 1.22.22 * chore(build): replace del with fs.rmSync in gulp clean * chore(build): replace npm-run-all with npm-run-all2 * chore(security): upgrade dompurify and unify sanitizer path * chore(observability): upgrade web sentry to 8.x * chore: remove unused react-draggable dependencies * chore(ci): fix windows release artifact collection * fix(build): create static dir before gulp clean scans it * fix: update nbb-logseq dependency to version feat-db-v33 * fix(test): move start-time initialization after clone repo * fix(deps): update nbb dependencies and adjust test script paths to compatible with windows path delimiter * chore(deps): remove dead meander dependency --------- Co-authored-by: Tienson Qin <tiensonqin@gmail.com>
This commit is contained in:
10
.github/workflows/build-desktop-release.yml
vendored
10
.github/workflows/build-desktop-release.yml
vendored
@@ -302,7 +302,8 @@ jobs:
|
||||
run: |
|
||||
mkdir builds
|
||||
mv static\out\make\squirrel.windows\x64\*.nupkg builds\Logseq-win-x64-${{ steps.ref.outputs.version }}-full.nupkg
|
||||
mv static\out\make\zip\win32\x64\*.exe builds\Logseq-win-x64-${{ steps.ref.outputs.version }}.exe
|
||||
mv static\out\make\squirrel.windows\x64\*.exe builds\Logseq-win-x64-${{ steps.ref.outputs.version }}.exe
|
||||
mv static\out\make\zip\win32\x64\*.zip builds\Logseq-win-x64-${{ steps.ref.outputs.version }}.zip
|
||||
mv static\out\make\wix\x64\Logseq.msi builds\Logseq-win-x64-${{ steps.ref.outputs.version }}.msi
|
||||
mv static\out\make\squirrel.windows\x64\RELEASES builds\RELEASES
|
||||
|
||||
@@ -324,7 +325,7 @@ jobs:
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: logseq-win64-builds
|
||||
name: logseq-win-x64-builds
|
||||
path: builds
|
||||
|
||||
build-windows-arm64:
|
||||
@@ -367,7 +368,8 @@ jobs:
|
||||
run: |
|
||||
mkdir builds
|
||||
mv static\out\make\squirrel.windows\arm64\*.nupkg builds\Logseq-win-arm64-${{ steps.ref.outputs.version }}-full.nupkg
|
||||
mv static\out\make\zip\win32\arm64\*.exe builds\Logseq-win-arm64-${{ steps.ref.outputs.version }}.exe
|
||||
mv static\out\make\squirrel.windows\arm64\*.exe builds\Logseq-win-arm64-${{ steps.ref.outputs.version }}.exe
|
||||
mv static\out\make\zip\win32\arm64\*.zip builds\Logseq-win-arm64-${{ steps.ref.outputs.version }}.zip
|
||||
mv static\out\make\wix\arm64\Logseq.msi builds\Logseq-win-arm64-${{ steps.ref.outputs.version }}.msi
|
||||
mv static\out\make\squirrel.windows\arm64\RELEASES builds\RELEASES
|
||||
|
||||
@@ -590,7 +592,7 @@ jobs:
|
||||
- name: Download The Windows Artifact x64
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: logseq-win64-builds
|
||||
name: logseq-win-x64-builds
|
||||
path: ./
|
||||
|
||||
- name: Download The Windows Artifact arm64
|
||||
|
||||
3
deps.edn
3
deps.edn
@@ -13,7 +13,7 @@
|
||||
funcool/promesa {:mvn/version "11.0.678"}
|
||||
medley/medley {:mvn/version "1.4.0"}
|
||||
metosin/reitit-frontend {:mvn/version "0.3.10"}
|
||||
cljs-bean/cljs-bean {:mvn/version "1.5.0"}
|
||||
cljs-bean/cljs-bean {:mvn/version "1.9.0"}
|
||||
prismatic/dommy {:mvn/version "1.1.0"}
|
||||
org.clojure/core.match {:mvn/version "1.0.0"}
|
||||
com.andrewmcveigh/cljs-time {:git/url "https://github.com/logseq/cljs-time" ;; fork
|
||||
@@ -44,7 +44,6 @@
|
||||
metosin/malli {:mvn/version "0.16.1"}
|
||||
com.cognitect/transit-cljs {:mvn/version "0.8.280"}
|
||||
missionary/missionary {:mvn/version "b.46"}
|
||||
meander/epsilon {:mvn/version "0.0.650"}
|
||||
|
||||
io.github.open-spaced-repetition/cljc-fsrs {:git/sha "eeef3520df664e51c3d0ba2031ec2ba071635442"
|
||||
:git/url "https://github.com/open-spaced-repetition/cljc-fsrs"}
|
||||
|
||||
2
deps/cli/package.json
vendored
2
deps/cli/package.json
vendored
@@ -12,7 +12,7 @@
|
||||
"dependencies": {
|
||||
"@logseq/nbb-logseq": "github:logseq/nbb-logseq#feat-db-v33",
|
||||
"@modelcontextprotocol/sdk": "^1.17.5",
|
||||
"better-sqlite3": "~11.10.0",
|
||||
"better-sqlite3": "^12.6.2",
|
||||
"fastify": "5.3.2",
|
||||
"fs-extra": "^11.3.0",
|
||||
"jszip": "3.8.0",
|
||||
|
||||
8
deps/cli/yarn.lock
vendored
8
deps/cli/yarn.lock
vendored
@@ -135,10 +135,10 @@ base64-js@^1.3.1:
|
||||
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
|
||||
integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
|
||||
|
||||
better-sqlite3@~11.10.0:
|
||||
version "11.10.0"
|
||||
resolved "https://registry.yarnpkg.com/better-sqlite3/-/better-sqlite3-11.10.0.tgz#2b1b14c5acd75a43fd84d12cc291ea98cef57d98"
|
||||
integrity sha512-EwhOpyXiOEL/lKzHz9AW1msWFNzGc/z+LzeB3/jnFJpxu+th2yqvzsSWas1v9jgs9+xiXJcD5A8CJxAG2TaghQ==
|
||||
better-sqlite3@^12.6.2:
|
||||
version "12.6.2"
|
||||
resolved "https://registry.yarnpkg.com/better-sqlite3/-/better-sqlite3-12.6.2.tgz#770649f28a62e543a360f3dfa1afe4cc944b1937"
|
||||
integrity sha512-8VYKM3MjCa9WcaSAI3hzwhmyHVlH8tiGFwf0RlTsZPWJ1I5MkzjiudCo4KC4DxOaL/53A5B1sI/IbldNFDbsKA==
|
||||
dependencies:
|
||||
bindings "^1.5.0"
|
||||
prebuild-install "^7.1.1"
|
||||
|
||||
2
deps/db/deps.edn
vendored
2
deps/db/deps.edn
vendored
@@ -5,7 +5,7 @@
|
||||
;; datascript/datascript {:local/root "../../../../datascript"}
|
||||
datascript-transit/datascript-transit {:mvn/version "0.3.0"
|
||||
:exclusions [datascript/datascript]}
|
||||
cljs-bean/cljs-bean {:mvn/version "1.5.0"}
|
||||
cljs-bean/cljs-bean {:mvn/version "1.9.0"}
|
||||
com.cognitect/transit-cljs {:mvn/version "0.8.280"}
|
||||
org.flatland/ordered {:mvn/version "1.15.11"}
|
||||
|
||||
|
||||
2
deps/db/package.json
vendored
2
deps/db/package.json
vendored
@@ -7,7 +7,7 @@
|
||||
"fs-extra": "^11.3.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"better-sqlite3": "11.10.0"
|
||||
"better-sqlite3": "^12.6.2"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "yarn nbb-logseq -cp test -m nextjournal.test-runner",
|
||||
|
||||
8
deps/db/yarn.lock
vendored
8
deps/db/yarn.lock
vendored
@@ -13,10 +13,10 @@ base64-js@^1.3.1:
|
||||
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
|
||||
integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
|
||||
|
||||
better-sqlite3@11.10.0:
|
||||
version "11.10.0"
|
||||
resolved "https://registry.yarnpkg.com/better-sqlite3/-/better-sqlite3-11.10.0.tgz#2b1b14c5acd75a43fd84d12cc291ea98cef57d98"
|
||||
integrity sha512-EwhOpyXiOEL/lKzHz9AW1msWFNzGc/z+LzeB3/jnFJpxu+th2yqvzsSWas1v9jgs9+xiXJcD5A8CJxAG2TaghQ==
|
||||
better-sqlite3@^12.6.2:
|
||||
version "12.6.2"
|
||||
resolved "https://registry.yarnpkg.com/better-sqlite3/-/better-sqlite3-12.6.2.tgz#770649f28a62e543a360f3dfa1afe4cc944b1937"
|
||||
integrity sha512-8VYKM3MjCa9WcaSAI3hzwhmyHVlH8tiGFwf0RlTsZPWJ1I5MkzjiudCo4KC4DxOaL/53A5B1sI/IbldNFDbsKA==
|
||||
dependencies:
|
||||
bindings "^1.5.0"
|
||||
prebuild-install "^7.1.1"
|
||||
|
||||
2
deps/graph-parser/deps.edn
vendored
2
deps/graph-parser/deps.edn
vendored
@@ -4,7 +4,7 @@
|
||||
{com.andrewmcveigh/cljs-time {:git/url "https://github.com/logseq/cljs-time" ;; fork
|
||||
:sha "5704fbf48d3478eedcf24d458c8964b3c2fd59a9"}
|
||||
funcool/promesa {:mvn/version "11.0.678"}
|
||||
cljs-bean/cljs-bean {:mvn/version "1.5.0"}
|
||||
cljs-bean/cljs-bean {:mvn/version "1.9.0"}
|
||||
|
||||
;; Any other deps should be added here and to nbb.edn
|
||||
borkdude/rewrite-edn {:mvn/version "0.4.9"}
|
||||
|
||||
2
deps/graph-parser/nbb.edn
vendored
2
deps/graph-parser/nbb.edn
vendored
@@ -4,6 +4,8 @@
|
||||
{:local/root "../common"}
|
||||
logseq/db
|
||||
{:local/root "../db"}
|
||||
logseq/outliner
|
||||
{:local/root "../outliner"}
|
||||
io.github.nextjournal/nbb-test-runner
|
||||
{:git/sha "b379325cfa5a3306180649da5de3bf5166414e71"}
|
||||
borkdude/rewrite-edn {:mvn/version "0.4.9"}
|
||||
|
||||
6
deps/graph-parser/package.json
vendored
6
deps/graph-parser/package.json
vendored
@@ -4,14 +4,14 @@
|
||||
"private": true,
|
||||
"devDependencies": {
|
||||
"@logseq/nbb-logseq": "github:logseq/nbb-logseq#feat-db-v33",
|
||||
"better-sqlite3": "11.10.0"
|
||||
"better-sqlite3": "^12.6.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"mldoc": "^1.5.9",
|
||||
"sanitize-filename": "1.6.3"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "nbb-logseq -cp test:../outliner/src -m nextjournal.test-runner",
|
||||
"test-v": "nbb-logseq -cp test:../outliner/src -m logseq.graph-parser.test-runner"
|
||||
"test": "nbb-logseq -cp test -m nextjournal.test-runner",
|
||||
"test-v": "nbb-logseq -cp test -m logseq.graph-parser.test-runner"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -285,8 +285,8 @@
|
||||
|
||||
(deftest-async ^:integration export-docs-graph-with-convert-all-tags
|
||||
(p/let [file-graph-dir "test/resources/docs-0.10.12"
|
||||
start-time (cljs.core/system-time)
|
||||
_ (docs-graph-helper/clone-docs-repo-if-not-exists file-graph-dir "v0.10.12")
|
||||
start-time (cljs.core/system-time)
|
||||
conn (db-test/create-conn)
|
||||
_ (db-pipeline/add-listener conn)
|
||||
{:keys [import-state]}
|
||||
|
||||
8
deps/graph-parser/yarn.lock
vendored
8
deps/graph-parser/yarn.lock
vendored
@@ -23,10 +23,10 @@ base64-js@^1.3.1:
|
||||
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
|
||||
integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
|
||||
|
||||
better-sqlite3@11.10.0:
|
||||
version "11.10.0"
|
||||
resolved "https://registry.yarnpkg.com/better-sqlite3/-/better-sqlite3-11.10.0.tgz#2b1b14c5acd75a43fd84d12cc291ea98cef57d98"
|
||||
integrity sha512-EwhOpyXiOEL/lKzHz9AW1msWFNzGc/z+LzeB3/jnFJpxu+th2yqvzsSWas1v9jgs9+xiXJcD5A8CJxAG2TaghQ==
|
||||
better-sqlite3@^12.6.2:
|
||||
version "12.6.2"
|
||||
resolved "https://registry.yarnpkg.com/better-sqlite3/-/better-sqlite3-12.6.2.tgz#770649f28a62e543a360f3dfa1afe4cc944b1937"
|
||||
integrity sha512-8VYKM3MjCa9WcaSAI3hzwhmyHVlH8tiGFwf0RlTsZPWJ1I5MkzjiudCo4KC4DxOaL/53A5B1sI/IbldNFDbsKA==
|
||||
dependencies:
|
||||
bindings "^1.5.0"
|
||||
prebuild-install "^7.1.1"
|
||||
|
||||
2
deps/outliner/package.json
vendored
2
deps/outliner/package.json
vendored
@@ -6,7 +6,7 @@
|
||||
"@logseq/nbb-logseq": "github:logseq/nbb-logseq#feat-db-v33"
|
||||
},
|
||||
"dependencies": {
|
||||
"better-sqlite3": "11.10.0",
|
||||
"better-sqlite3": "^12.6.2",
|
||||
"mldoc": "^1.5.9"
|
||||
},
|
||||
"scripts": {
|
||||
|
||||
8
deps/outliner/yarn.lock
vendored
8
deps/outliner/yarn.lock
vendored
@@ -23,10 +23,10 @@ base64-js@^1.3.1:
|
||||
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
|
||||
integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
|
||||
|
||||
better-sqlite3@11.10.0:
|
||||
version "11.10.0"
|
||||
resolved "https://registry.yarnpkg.com/better-sqlite3/-/better-sqlite3-11.10.0.tgz#2b1b14c5acd75a43fd84d12cc291ea98cef57d98"
|
||||
integrity sha512-EwhOpyXiOEL/lKzHz9AW1msWFNzGc/z+LzeB3/jnFJpxu+th2yqvzsSWas1v9jgs9+xiXJcD5A8CJxAG2TaghQ==
|
||||
better-sqlite3@^12.6.2:
|
||||
version "12.6.2"
|
||||
resolved "https://registry.yarnpkg.com/better-sqlite3/-/better-sqlite3-12.6.2.tgz#770649f28a62e543a360f3dfa1afe4cc944b1937"
|
||||
integrity sha512-8VYKM3MjCa9WcaSAI3hzwhmyHVlH8tiGFwf0RlTsZPWJ1I5MkzjiudCo4KC4DxOaL/53A5B1sI/IbldNFDbsKA==
|
||||
dependencies:
|
||||
bindings "^1.5.0"
|
||||
prebuild-install "^7.1.1"
|
||||
|
||||
4
deps/publishing/package.json
vendored
4
deps/publishing/package.json
vendored
@@ -7,8 +7,8 @@
|
||||
"mldoc": "^1.5.9"
|
||||
},
|
||||
"dependencies": {
|
||||
"better-sqlite3": "11.10.0",
|
||||
"fs-extra": "9.1.0"
|
||||
"better-sqlite3": "^12.6.2",
|
||||
"fs-extra": "^11.3.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "yarn nbb-logseq -cp test -m nextjournal.test-runner"
|
||||
|
||||
22
deps/publishing/yarn.lock
vendored
22
deps/publishing/yarn.lock
vendored
@@ -18,20 +18,15 @@ ansi-regex@^3.0.0:
|
||||
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.1.tgz#123d6479e92ad45ad897d4054e3c7ca7db4944e1"
|
||||
integrity sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==
|
||||
|
||||
at-least-node@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2"
|
||||
integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==
|
||||
|
||||
base64-js@^1.3.1:
|
||||
version "1.5.1"
|
||||
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
|
||||
integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
|
||||
|
||||
better-sqlite3@11.10.0:
|
||||
version "11.10.0"
|
||||
resolved "https://registry.yarnpkg.com/better-sqlite3/-/better-sqlite3-11.10.0.tgz#2b1b14c5acd75a43fd84d12cc291ea98cef57d98"
|
||||
integrity sha512-EwhOpyXiOEL/lKzHz9AW1msWFNzGc/z+LzeB3/jnFJpxu+th2yqvzsSWas1v9jgs9+xiXJcD5A8CJxAG2TaghQ==
|
||||
better-sqlite3@^12.6.2:
|
||||
version "12.6.2"
|
||||
resolved "https://registry.yarnpkg.com/better-sqlite3/-/better-sqlite3-12.6.2.tgz#770649f28a62e543a360f3dfa1afe4cc944b1937"
|
||||
integrity sha512-8VYKM3MjCa9WcaSAI3hzwhmyHVlH8tiGFwf0RlTsZPWJ1I5MkzjiudCo4KC4DxOaL/53A5B1sI/IbldNFDbsKA==
|
||||
dependencies:
|
||||
bindings "^1.5.0"
|
||||
prebuild-install "^7.1.1"
|
||||
@@ -159,12 +154,11 @@ fs-constants@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad"
|
||||
integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==
|
||||
|
||||
fs-extra@9.1.0:
|
||||
version "9.1.0"
|
||||
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d"
|
||||
integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==
|
||||
fs-extra@^11.3.0:
|
||||
version "11.3.4"
|
||||
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.3.4.tgz#ab6934eca8bcf6f7f6b82742e33591f86301d6fc"
|
||||
integrity sha512-CTXd6rk/M3/ULNQj8FBqBWHYBVYybQ3VPBw0xGKFe3tuH7ytT6ACnvzpIQ3UZtB8yvUKC2cXn1a+x+5EVQLovA==
|
||||
dependencies:
|
||||
at-least-node "^1.0.0"
|
||||
graceful-fs "^4.2.0"
|
||||
jsonfile "^6.0.1"
|
||||
universalify "^2.0.0"
|
||||
|
||||
2
deps/shui/deps.edn
vendored
2
deps/shui/deps.edn
vendored
@@ -7,4 +7,4 @@
|
||||
:sha "5d672bf84ed944414b9f61eeb83808ead7be9127"}
|
||||
|
||||
medley/medley {:mvn/version "1.4.0"}
|
||||
cljs-bean/cljs-bean {:mvn/version "1.5.0"}}}
|
||||
cljs-bean/cljs-bean {:mvn/version "1.9.0"}}}
|
||||
|
||||
25
gulpfile.js
25
gulpfile.js
@@ -4,8 +4,6 @@ const cp = require('child_process')
|
||||
const exec = utils.promisify(cp.exec)
|
||||
const path = require('path')
|
||||
const gulp = require('gulp')
|
||||
const del = require('del')
|
||||
const ip = require('ip')
|
||||
const replace = require('gulp-replace')
|
||||
|
||||
const outputPath = path.join(__dirname, 'static')
|
||||
@@ -17,6 +15,13 @@ const mobileJsPath = path.join(mobilePath, 'js')
|
||||
const sourcePath = path.join(__dirname, 'src/main/frontend')
|
||||
const resourceFilePath = path.join(resourcesPath, '**')
|
||||
const outputFilePath = path.join(outputPath, '**')
|
||||
const staticCleanKeep = new Set([
|
||||
'entitlements.plist',
|
||||
'forge.config.js',
|
||||
'node_modules',
|
||||
'package.json',
|
||||
'yarn.lock',
|
||||
])
|
||||
|
||||
const css = {
|
||||
watchCSS () {
|
||||
@@ -54,8 +59,20 @@ const css = {
|
||||
|
||||
const common = {
|
||||
clean () {
|
||||
return del(
|
||||
['./static/**/*', '!./static/node_modules'])
|
||||
if (!fs.existsSync(outputPath)) {
|
||||
fs.mkdirSync(outputPath, { recursive: true })
|
||||
}
|
||||
|
||||
for (const entry of fs.readdirSync(outputPath)) {
|
||||
if (staticCleanKeep.has(entry)) continue
|
||||
fs.rmSync(path.join(outputPath, entry), {
|
||||
recursive: true,
|
||||
force: true,
|
||||
maxRetries: 10,
|
||||
retryDelay: 100,
|
||||
})
|
||||
}
|
||||
return Promise.resolve()
|
||||
},
|
||||
|
||||
syncResourceFile () {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{:paths ["src" "test"]
|
||||
:deps {org.clojure/clojurescript {:mvn/version "1.12.42"}
|
||||
cljs-bean/cljs-bean {:mvn/version "1.5.0"}}
|
||||
cljs-bean/cljs-bean {:mvn/version "1.9.0"}}
|
||||
|
||||
:npm-deps {"@logseq/libs" "0.2.3"}
|
||||
|
||||
|
||||
22
package.json
22
package.json
@@ -2,6 +2,7 @@
|
||||
"name": "logseq",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"packageManager": "yarn@1.22.22",
|
||||
"main": "static/electron.js",
|
||||
"engines": {
|
||||
"node": ">=22.20.0"
|
||||
@@ -20,16 +21,11 @@
|
||||
"better-sqlite3": "^12.6.2",
|
||||
"cross-env": "^7.0.3",
|
||||
"cssnano": "^5.1.13",
|
||||
"del": "^6.0.0",
|
||||
"glob": "9.0.0",
|
||||
"gulp": "^4.0.2",
|
||||
"gulp-postcss": "^10.0.0",
|
||||
"gulp-replace": "^1.1.4",
|
||||
"ip": "1.1.9",
|
||||
"karma": "^6.4.4",
|
||||
"karma-chrome-launcher": "^3.2.0",
|
||||
"karma-cljs-test": "^0.1.0",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"npm-run-all2": "^8.0.4",
|
||||
"playwright": "=1.51.0",
|
||||
"postcss": "^8.4.47",
|
||||
"postcss-cli": "10.0.0",
|
||||
@@ -38,7 +34,6 @@
|
||||
"postcss-import-ext-glob": "2.0.1",
|
||||
"postcss-nested": "6.0.0",
|
||||
"process": "^0.11.10",
|
||||
"purgecss": "4.0.2",
|
||||
"semver": "7.5.2",
|
||||
"shadow-cljs": "2.28.23",
|
||||
"source-map-loader": "^5.0.0",
|
||||
@@ -89,13 +84,13 @@
|
||||
"cljs:release-mobile": "clojure -M:cljs release mobile db-worker --config-merge \"{:output-dir \\\"./static/mobile/js\\\" :asset-path \\\"/static/mobile/js\\\" :release {:asset-path \\\"http://localhost\\\"}}\"",
|
||||
"cljs:dev-watch": "clojure -M:cljs watch app db-worker inference-worker electron mobile",
|
||||
"cljs:app-watch": "clojure -M:cljs watch app db-worker inference-worker",
|
||||
"cljs:electron-watch": "clojure -M:cljs watch app db-worker inference-worker electron --config-merge \"{:asset-path \\\"./js\\\"}\"",
|
||||
"cljs:electron-watch": "clojure -M:cljs watch app db-worker inference-worker electron test --config-merge \"{:asset-path \\\"./js\\\"}\"",
|
||||
"cljs:release": "clojure -M:cljs release app db-worker inference-worker publishing electron",
|
||||
"cljs:release-electron": "clojure -M:cljs release app db-worker inference-worker electron --debug && clojure -M:cljs release publishing",
|
||||
"cljs:release-app": "clojure -M:cljs release app db-worker inference-worker",
|
||||
"cljs:release-publishing": "clojure -M:cljs release app publishing",
|
||||
"cljs:test": "clojure -M:test compile test",
|
||||
"cljs:run-test": "node static/tests.js -r '^(?!logseq.db-sync.).*' -e fix-me",
|
||||
"cljs:run-test": "node static/tests.js -r \"^(?!logseq.db-sync.).*\" -e fix-me",
|
||||
"cljs:test-no-worker": "clojure -M:test compile test-no-worker",
|
||||
"cljs:run-test-no-worker": "node static/tests-no-worker.js",
|
||||
"cljs:dev-release-app": "clojure -M:cljs release app db-worker inference-worker --config-merge \"{:closure-defines {frontend.config/DEV-RELEASE true}}\"",
|
||||
@@ -144,8 +139,7 @@
|
||||
"@logseq/react-tweet-embed": "1.3.1-1",
|
||||
"@logseq/simple-wave-record": "^0.0.3",
|
||||
"@radix-ui/colors": "^0.1.8",
|
||||
"@sentry/react": "^6.18.2",
|
||||
"@sentry/tracing": "^6.18.2",
|
||||
"@sentry/react": "^8.53.0",
|
||||
"@sqlite.org/sqlite-wasm": "^3.50.3-build1",
|
||||
"@tabler/icons-react": "^2.47.0",
|
||||
"@tabler/icons-webfont": "^2.47.0",
|
||||
@@ -156,10 +150,10 @@
|
||||
"codemirror": "5.65.18",
|
||||
"comlink": "^4.4.1",
|
||||
"d3-force": "3.0.0",
|
||||
"dompurify": "2.4.0",
|
||||
"dompurify": "^3.3.3",
|
||||
"emoji-mart": "^5.5.2",
|
||||
"fs": "0.0.1-security",
|
||||
"fs-extra": "9.1.0",
|
||||
"fs-extra": "^11.3.0",
|
||||
"fuse.js": "6.4.6",
|
||||
"grapheme-splitter": "1.0.4",
|
||||
"graphology": "0.20.0",
|
||||
@@ -182,7 +176,6 @@
|
||||
"prop-types": "^15.7.2",
|
||||
"react": "18.3.1",
|
||||
"react-dom": "18.3.1",
|
||||
"react-grid-layout": "0.16.6",
|
||||
"react-intersection-observer": "^9.3.5",
|
||||
"react-textarea-autosize": "8.3.3",
|
||||
"react-transition-group": "4.3.0",
|
||||
@@ -192,7 +185,6 @@
|
||||
"send-intent": "^7.0.0",
|
||||
"shepherd.js": "^9.1.0",
|
||||
"tailwind-capitalize-first-letter": "^1.0.4",
|
||||
"threads": "1.6.5",
|
||||
"url": "^0.11.0",
|
||||
"util": "^0.12.5",
|
||||
"yargs-parser": "20.2.4"
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
"electron-window-state": "5.0.3",
|
||||
"extract-zip": "2.0.1",
|
||||
"fastify": "5.3.2",
|
||||
"fs-extra": "9.1.0",
|
||||
"fs-extra": "^11.3.0",
|
||||
"https-proxy-agent": "7.0.2",
|
||||
"node-fetch": "2.6.7",
|
||||
"open": "7.3.1",
|
||||
|
||||
@@ -61,12 +61,20 @@
|
||||
(defn- validate-workers-not-in-frontend
|
||||
[]
|
||||
(let [res (shell {:out :string :continue true}
|
||||
"grep -r --exclude-dir=worker --exclude-dir=inference_worker" "\\[frontend.worker.*:" "src/main/frontend")
|
||||
"git grep --untracked --exclude-standard"
|
||||
"\\[frontend.worker.*:" "--" "src/main/frontend")
|
||||
;; allow reset-file b/c it's only affects tests
|
||||
allowed-exceptions #{"src/main/frontend/handler/file_based/file.cljs: [frontend.worker.file.reset :as file-reset]"}
|
||||
excluded-path-prefixes ["src/main/frontend/worker/"
|
||||
"src/main/frontend/inference_worker/"]
|
||||
invalid-lines (when (= 0 (:exit res))
|
||||
(remove #(some->> % (contains? allowed-exceptions))
|
||||
(string/split-lines (:out res))))
|
||||
(->> (:out res)
|
||||
string/split-lines
|
||||
(remove (fn [line]
|
||||
(let [path (first (string/split line #":" 2))]
|
||||
(or (contains? allowed-exceptions line)
|
||||
(some #(string/starts-with? path %)
|
||||
excluded-path-prefixes)))))))
|
||||
_ (when (> (:exit res) 1) (System/exit 1))]
|
||||
(if (and (= 0 (:exit res)) (seq invalid-lines))
|
||||
(do (println "The following worker requires should not be in frontend namespaces:")
|
||||
|
||||
@@ -38,7 +38,6 @@
|
||||
[logseq.shui.ui :as shui]
|
||||
[medley.core :as medley]
|
||||
[promesa.core :as p]
|
||||
[react-draggable]
|
||||
[reitit.frontend.easy :as rfe]
|
||||
[rum.core :as rum]))
|
||||
|
||||
|
||||
@@ -33,7 +33,6 @@
|
||||
[logseq.shui.hooks :as hooks]
|
||||
[logseq.shui.ui :as shui]
|
||||
[promesa.core :as p]
|
||||
[react-draggable]
|
||||
[rum.core :as rum]))
|
||||
|
||||
(defonce no-matched-commands [["No matched commands" [[:editor/move-cursor-to-end]]]])
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
[logseq.db :as ldb]
|
||||
[logseq.shui.hooks :as hooks]
|
||||
[logseq.shui.ui :as shui]
|
||||
[react-draggable]
|
||||
[reitit.frontend.easy :as rfe]
|
||||
[rum.core :as rum]))
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
[frontend.components.lazy-editor :as lazy-editor]
|
||||
[frontend.handler.notification :as notification]
|
||||
[frontend.handler.plugin :as plugin-handler]
|
||||
[frontend.security :as security]
|
||||
[frontend.ui :as ui]
|
||||
[frontend.util :as util]
|
||||
[goog.functions :refer [debounce]]
|
||||
@@ -10,17 +11,10 @@
|
||||
[logseq.shui.ui :as shui]
|
||||
[rum.core :as rum]))
|
||||
|
||||
(defn- dom-purify
|
||||
[html opts]
|
||||
(try
|
||||
(js-invoke js/DOMPurify "sanitize" html (bean/->js opts))
|
||||
(catch js/Error e
|
||||
(js/console.warn e) html)))
|
||||
|
||||
(rum/defc html-content
|
||||
[html]
|
||||
[:div.html-content.pl-1.flex-1.text-sm
|
||||
{:dangerouslySetInnerHTML {:__html (dom-purify html nil)}}])
|
||||
{:dangerouslySetInnerHTML {:__html (security/sanitize-html html)}}])
|
||||
|
||||
(rum/defc edit-settings-file
|
||||
[pid {:keys [class edit-mode set-edit-mode!]}]
|
||||
|
||||
@@ -66,5 +66,4 @@
|
||||
|
||||
(defn set-user!
|
||||
[id]
|
||||
(Sentry/configureScope (fn [scope]
|
||||
(.setUser scope #js {:id id}))))
|
||||
(.setUser (Sentry/getCurrentScope) #js {:id id}))
|
||||
|
||||
@@ -1,6 +1,36 @@
|
||||
(ns frontend.security
|
||||
"Provide security focused fns like preventing XSS attacks"
|
||||
(:require ["dompurify" :as DOMPurify]))
|
||||
(:require ["dompurify" :as dompurify]))
|
||||
|
||||
(defn- sanitizer-instance?
|
||||
[value]
|
||||
(fn? (some-> value (aget "sanitize"))))
|
||||
|
||||
(defn- resolve-dompurify
|
||||
[module]
|
||||
(let [purify (or (.-default module) module)]
|
||||
(cond
|
||||
(sanitizer-instance? purify)
|
||||
purify
|
||||
|
||||
(fn? purify)
|
||||
(let [instance (purify js/window)]
|
||||
(if (sanitizer-instance? instance)
|
||||
instance
|
||||
(throw (js/Error. "DOMPurify factory did not return a sanitizer instance"))))
|
||||
|
||||
:else
|
||||
(throw (js/Error. "Unsupported DOMPurify module shape")))))
|
||||
|
||||
(defonce ^:private dompurify-instance (volatile! nil))
|
||||
|
||||
(defn- get-dompurify
|
||||
([] (get-dompurify dompurify dompurify-instance))
|
||||
([module cache]
|
||||
(or @cache
|
||||
(let [instance (resolve-dompurify module)]
|
||||
(vreset! cache instance)
|
||||
instance))))
|
||||
|
||||
(def sanitization-options (clj->js {:ADD_TAGS ["iframe"]
|
||||
:ADD_ATTR ["is"]
|
||||
@@ -8,4 +38,4 @@
|
||||
|
||||
(defn sanitize-html
|
||||
[html]
|
||||
(.sanitize DOMPurify html sanitization-options))
|
||||
(js-invoke (get-dompurify) "sanitize" html sanitization-options))
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
(->
|
||||
(p/do!
|
||||
(fs/create-if-not-exists nil dir some-file "NEW")
|
||||
(fs/create-if-not-exists nil nil some-file "NEW")
|
||||
(is (fs-node/existsSync some-file)
|
||||
"something.txt created correctly")
|
||||
(is (= "NEW"
|
||||
@@ -36,7 +36,7 @@
|
||||
|
||||
(->
|
||||
(p/do!
|
||||
(fs/create-if-not-exists nil dir some-file "NEW")
|
||||
(fs/create-if-not-exists nil nil some-file "NEW")
|
||||
(is (= "OLD" (str (fs-node/readFileSync some-file)))
|
||||
"something.txt has not been touched and old content still exists"))
|
||||
|
||||
|
||||
47
src/test/frontend/security_test.cljs
Normal file
47
src/test/frontend/security_test.cljs
Normal file
@@ -0,0 +1,47 @@
|
||||
(ns frontend.security-test
|
||||
(:require [cljs.test :refer [deftest is testing]]
|
||||
[frontend.security :as security]))
|
||||
|
||||
(deftest sanitize-html-uses-logseq-sanitization-policy
|
||||
(testing "sanitize-html delegates to DOMPurify with the repository's supported plugin policy"
|
||||
(let [called (atom nil)
|
||||
html "<p onclick=\"alert('x')\">safe</p><iframe src=\"logseq://plugin/frame\" is=\"plugin-frame\"></iframe><script>alert('x')</script>"
|
||||
fake-purify #js {:sanitize (fn [input opts]
|
||||
(reset! called {:input input
|
||||
:opts (js->clj opts)})
|
||||
"<p>safe</p><iframe src=\"logseq://plugin/frame\" is=\"plugin-frame\"></iframe>")}]
|
||||
(with-redefs [security/get-dompurify (fn [] fake-purify)]
|
||||
(is (= "<p>safe</p><iframe src=\"logseq://plugin/frame\" is=\"plugin-frame\"></iframe>"
|
||||
(security/sanitize-html html)))
|
||||
(is (= html (:input @called)))
|
||||
(is (= ["iframe"] (get-in @called [:opts "ADD_TAGS"])))
|
||||
(is (= ["is"] (get-in @called [:opts "ADD_ATTR"])))
|
||||
(is (= true (get-in @called [:opts "ALLOW_UNKNOWN_PROTOCOLS"])))))))
|
||||
|
||||
(deftest resolve-dompurify-fails-fast-on-unsupported-shapes
|
||||
(testing "unsupported module shapes fail explicitly instead of falling through to a later sanitize call"
|
||||
(let [bad-module-error (try
|
||||
(#'security/resolve-dompurify #js {})
|
||||
nil
|
||||
(catch js/Error error
|
||||
error))
|
||||
bad-factory-error (try
|
||||
(#'security/resolve-dompurify (fn [_] #js {}))
|
||||
nil
|
||||
(catch js/Error error
|
||||
error))]
|
||||
(is (= "Unsupported DOMPurify module shape" (.-message bad-module-error)))
|
||||
(is (= "DOMPurify factory did not return a sanitizer instance"
|
||||
(.-message bad-factory-error))))))
|
||||
|
||||
(deftest get-dompurify-caches-the-resolved-instance
|
||||
(testing "the DOMPurify instance is resolved once and then reused"
|
||||
(let [calls (atom 0)
|
||||
cache (volatile! nil)
|
||||
fake-instance #js {:sanitize (fn [_ _] "<p>safe</p>")}]
|
||||
(with-redefs [security/resolve-dompurify (fn [_]
|
||||
(swap! calls inc)
|
||||
fake-instance)]
|
||||
(is (identical? fake-instance (#'security/get-dompurify #js {} cache)))
|
||||
(is (identical? fake-instance (#'security/get-dompurify #js {} cache)))
|
||||
(is (= 1 @calls))))))
|
||||
Reference in New Issue
Block a user