mirror of
				https://github.com/TriliumNext/Notes.git
				synced 2025-11-04 07:01:31 +08:00 
			
		
		
		
	Merge branch 'develop' into feat_add-link-to-swagger-ui
This commit is contained in:
		
						commit
						4df76fafe1
					
				
							
								
								
									
										8
									
								
								.github/actions/build-electron/action.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								.github/actions/build-electron/action.yml
									
									
									
									
										vendored
									
									
								
							@ -18,7 +18,7 @@ runs:
 | 
				
			|||||||
    # Certificate setup
 | 
					    # Certificate setup
 | 
				
			||||||
    - name: Import Apple certificates
 | 
					    - name: Import Apple certificates
 | 
				
			||||||
      if: inputs.os == 'macos'
 | 
					      if: inputs.os == 'macos'
 | 
				
			||||||
      uses: apple-actions/import-codesign-certs@v2
 | 
					      uses: apple-actions/import-codesign-certs@v3
 | 
				
			||||||
      with:
 | 
					      with:
 | 
				
			||||||
        p12-file-base64: ${{ env.APPLE_APP_CERTIFICATE_BASE64 }}
 | 
					        p12-file-base64: ${{ env.APPLE_APP_CERTIFICATE_BASE64 }}
 | 
				
			||||||
        p12-password: ${{ env.APPLE_APP_CERTIFICATE_PASSWORD }}
 | 
					        p12-password: ${{ env.APPLE_APP_CERTIFICATE_PASSWORD }}
 | 
				
			||||||
@ -27,7 +27,7 @@ runs:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    - name: Install Installer certificate
 | 
					    - name: Install Installer certificate
 | 
				
			||||||
      if: inputs.os == 'macos'
 | 
					      if: inputs.os == 'macos'
 | 
				
			||||||
      uses: apple-actions/import-codesign-certs@v2
 | 
					      uses: apple-actions/import-codesign-certs@v3
 | 
				
			||||||
      with:
 | 
					      with:
 | 
				
			||||||
        p12-file-base64: ${{ env.APPLE_INSTALLER_CERTIFICATE_BASE64 }}
 | 
					        p12-file-base64: ${{ env.APPLE_INSTALLER_CERTIFICATE_BASE64 }}
 | 
				
			||||||
        p12-password: ${{ env.APPLE_INSTALLER_CERTIFICATE_PASSWORD }}
 | 
					        p12-password: ${{ env.APPLE_INSTALLER_CERTIFICATE_PASSWORD }}
 | 
				
			||||||
@ -180,7 +180,7 @@ runs:
 | 
				
			|||||||
          dmg_file=$(find out -name "*.dmg" -print -quit)
 | 
					          dmg_file=$(find out -name "*.dmg" -print -quit)
 | 
				
			||||||
          if [ -n "$dmg_file" ]; then
 | 
					          if [ -n "$dmg_file" ]; then
 | 
				
			||||||
            echo "Found DMG: $dmg_file"
 | 
					            echo "Found DMG: $dmg_file"
 | 
				
			||||||
            cp "$dmg_file" "upload/TriliumNextNotes-${{ github.ref_name }}-darwin-${{ inputs.arch }}.dmg"
 | 
					            cp "$dmg_file" "upload/TriliumNextNotes-${{ github.ref_name }}-macos-${{ inputs.arch }}.dmg"
 | 
				
			||||||
          else
 | 
					          else
 | 
				
			||||||
            echo "Warning: No DMG file found"
 | 
					            echo "Warning: No DMG file found"
 | 
				
			||||||
          fi
 | 
					          fi
 | 
				
			||||||
@ -190,7 +190,7 @@ runs:
 | 
				
			|||||||
          zip_file=$(find out -name "*.zip" -print -quit)
 | 
					          zip_file=$(find out -name "*.zip" -print -quit)
 | 
				
			||||||
          if [ -n "$zip_file" ]; then
 | 
					          if [ -n "$zip_file" ]; then
 | 
				
			||||||
            echo "Found ZIP: $zip_file"
 | 
					            echo "Found ZIP: $zip_file"
 | 
				
			||||||
            cp "$zip_file" "upload/TriliumNextNotes-${{ github.ref_name }}-darwin-${{ inputs.arch }}.zip"
 | 
					            cp "$zip_file" "upload/TriliumNextNotes-${{ github.ref_name }}-macos-${{ inputs.arch }}.zip"
 | 
				
			||||||
          else
 | 
					          else
 | 
				
			||||||
            echo "Warning: No ZIP file found"
 | 
					            echo "Warning: No ZIP file found"
 | 
				
			||||||
          fi
 | 
					          fi
 | 
				
			||||||
 | 
				
			|||||||
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										155
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										155
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							@ -154,6 +154,7 @@
 | 
				
			|||||||
        "@types/session-file-store": "1.2.5",
 | 
					        "@types/session-file-store": "1.2.5",
 | 
				
			||||||
        "@types/source-map-support": "0.5.10",
 | 
					        "@types/source-map-support": "0.5.10",
 | 
				
			||||||
        "@types/stream-throttle": "0.1.4",
 | 
					        "@types/stream-throttle": "0.1.4",
 | 
				
			||||||
 | 
					        "@types/supertest": "6.0.2",
 | 
				
			||||||
        "@types/swagger-ui-express": "4.1.8",
 | 
					        "@types/swagger-ui-express": "4.1.8",
 | 
				
			||||||
        "@types/tmp": "0.2.6",
 | 
					        "@types/tmp": "0.2.6",
 | 
				
			||||||
        "@types/turndown": "5.0.5",
 | 
					        "@types/turndown": "5.0.5",
 | 
				
			||||||
@ -177,6 +178,7 @@
 | 
				
			|||||||
        "rimraf": "6.0.1",
 | 
					        "rimraf": "6.0.1",
 | 
				
			||||||
        "sass": "1.85.1",
 | 
					        "sass": "1.85.1",
 | 
				
			||||||
        "sass-loader": "16.0.5",
 | 
					        "sass-loader": "16.0.5",
 | 
				
			||||||
 | 
					        "supertest": "7.0.0",
 | 
				
			||||||
        "swagger-jsdoc": "6.2.8",
 | 
					        "swagger-jsdoc": "6.2.8",
 | 
				
			||||||
        "tslib": "2.8.1",
 | 
					        "tslib": "2.8.1",
 | 
				
			||||||
        "tsx": "4.19.3",
 | 
					        "tsx": "4.19.3",
 | 
				
			||||||
@ -4089,6 +4091,13 @@
 | 
				
			|||||||
        "@types/express": "*"
 | 
					        "@types/express": "*"
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/@types/cookiejar": {
 | 
				
			||||||
 | 
					      "version": "2.1.5",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/@types/cookiejar/-/cookiejar-2.1.5.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-he+DHOWReW0nghN24E1WUqM0efK4kI9oTqDm6XmK8ZPe2djZ90BSNdGnIyCLzCPw7/pogPlGbzI2wHGGmi4O/Q==",
 | 
				
			||||||
 | 
					      "dev": true,
 | 
				
			||||||
 | 
					      "license": "MIT"
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    "node_modules/@types/d3": {
 | 
					    "node_modules/@types/d3": {
 | 
				
			||||||
      "version": "7.4.3",
 | 
					      "version": "7.4.3",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/@types/d3/-/d3-7.4.3.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/@types/d3/-/d3-7.4.3.tgz",
 | 
				
			||||||
@ -4597,6 +4606,13 @@
 | 
				
			|||||||
      "dev": true,
 | 
					      "dev": true,
 | 
				
			||||||
      "license": "MIT"
 | 
					      "license": "MIT"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/@types/methods": {
 | 
				
			||||||
 | 
					      "version": "1.1.4",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/@types/methods/-/methods-1.1.4.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-ymXWVrDiCxTBE3+RIrrP533E70eA+9qu7zdWoHuOmGujkYtzf4HQF96b8nwHLqhuf4ykX61IGRIB38CC6/sImQ==",
 | 
				
			||||||
 | 
					      "dev": true,
 | 
				
			||||||
 | 
					      "license": "MIT"
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    "node_modules/@types/mime": {
 | 
					    "node_modules/@types/mime": {
 | 
				
			||||||
      "version": "1.3.5",
 | 
					      "version": "1.3.5",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz",
 | 
				
			||||||
@ -4797,6 +4813,30 @@
 | 
				
			|||||||
        "@types/node": "*"
 | 
					        "@types/node": "*"
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/@types/superagent": {
 | 
				
			||||||
 | 
					      "version": "8.1.9",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/@types/superagent/-/superagent-8.1.9.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-pTVjI73witn+9ILmoJdajHGW2jkSaOzhiFYF1Rd3EQ94kymLqB9PjD9ISg7WaALC7+dCHT0FGe9T2LktLq/3GQ==",
 | 
				
			||||||
 | 
					      "dev": true,
 | 
				
			||||||
 | 
					      "license": "MIT",
 | 
				
			||||||
 | 
					      "dependencies": {
 | 
				
			||||||
 | 
					        "@types/cookiejar": "^2.1.5",
 | 
				
			||||||
 | 
					        "@types/methods": "^1.1.4",
 | 
				
			||||||
 | 
					        "@types/node": "*",
 | 
				
			||||||
 | 
					        "form-data": "^4.0.0"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/@types/supertest": {
 | 
				
			||||||
 | 
					      "version": "6.0.2",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/@types/supertest/-/supertest-6.0.2.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-137ypx2lk/wTQbW6An6safu9hXmajAifU/s7szAHLN/FeIm5w7yR0Wkl9fdJMRSHwOn4HLAI0DaB2TOORuhPDg==",
 | 
				
			||||||
 | 
					      "dev": true,
 | 
				
			||||||
 | 
					      "license": "MIT",
 | 
				
			||||||
 | 
					      "dependencies": {
 | 
				
			||||||
 | 
					        "@types/methods": "^1.1.4",
 | 
				
			||||||
 | 
					        "@types/superagent": "^8.1.0"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    "node_modules/@types/swagger-ui-express": {
 | 
					    "node_modules/@types/swagger-ui-express": {
 | 
				
			||||||
      "version": "4.1.8",
 | 
					      "version": "4.1.8",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/@types/swagger-ui-express/-/swagger-ui-express-4.1.8.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/@types/swagger-ui-express/-/swagger-ui-express-4.1.8.tgz",
 | 
				
			||||||
@ -5631,6 +5671,13 @@
 | 
				
			|||||||
      "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==",
 | 
					      "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==",
 | 
				
			||||||
      "license": "MIT"
 | 
					      "license": "MIT"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/asap": {
 | 
				
			||||||
 | 
					      "version": "2.0.6",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==",
 | 
				
			||||||
 | 
					      "dev": true,
 | 
				
			||||||
 | 
					      "license": "MIT"
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    "node_modules/asar": {
 | 
					    "node_modules/asar": {
 | 
				
			||||||
      "version": "3.2.0",
 | 
					      "version": "3.2.0",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/asar/-/asar-3.2.0.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/asar/-/asar-3.2.0.tgz",
 | 
				
			||||||
@ -7017,6 +7064,16 @@
 | 
				
			|||||||
        "node": ">=0.10.0"
 | 
					        "node": ">=0.10.0"
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/component-emitter": {
 | 
				
			||||||
 | 
					      "version": "1.3.1",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==",
 | 
				
			||||||
 | 
					      "dev": true,
 | 
				
			||||||
 | 
					      "license": "MIT",
 | 
				
			||||||
 | 
					      "funding": {
 | 
				
			||||||
 | 
					        "url": "https://github.com/sponsors/sindresorhus"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    "node_modules/compress-commons": {
 | 
					    "node_modules/compress-commons": {
 | 
				
			||||||
      "version": "6.0.2",
 | 
					      "version": "6.0.2",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-6.0.2.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-6.0.2.tgz",
 | 
				
			||||||
@ -7184,6 +7241,13 @@
 | 
				
			|||||||
      "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==",
 | 
					      "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==",
 | 
				
			||||||
      "license": "MIT"
 | 
					      "license": "MIT"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/cookiejar": {
 | 
				
			||||||
 | 
					      "version": "2.1.4",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==",
 | 
				
			||||||
 | 
					      "dev": true,
 | 
				
			||||||
 | 
					      "license": "MIT"
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    "node_modules/core-util-is": {
 | 
					    "node_modules/core-util-is": {
 | 
				
			||||||
      "version": "1.0.2",
 | 
					      "version": "1.0.2",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
 | 
				
			||||||
@ -8320,6 +8384,17 @@
 | 
				
			|||||||
      "integrity": "sha512-g8GWBkJLiIDRJfRXEdrd1wMXpNyGId2DkbfuwFahSb4OCvn717hyRJtAcEDISfp3zkwEhZ4Y4woHPA6DeyB3Fw==",
 | 
					      "integrity": "sha512-g8GWBkJLiIDRJfRXEdrd1wMXpNyGId2DkbfuwFahSb4OCvn717hyRJtAcEDISfp3zkwEhZ4Y4woHPA6DeyB3Fw==",
 | 
				
			||||||
      "license": "MIT"
 | 
					      "license": "MIT"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/dezalgo": {
 | 
				
			||||||
 | 
					      "version": "1.0.4",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==",
 | 
				
			||||||
 | 
					      "dev": true,
 | 
				
			||||||
 | 
					      "license": "ISC",
 | 
				
			||||||
 | 
					      "dependencies": {
 | 
				
			||||||
 | 
					        "asap": "^2.0.0",
 | 
				
			||||||
 | 
					        "wrappy": "1"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    "node_modules/dir-compare": {
 | 
					    "node_modules/dir-compare": {
 | 
				
			||||||
      "version": "4.2.0",
 | 
					      "version": "4.2.0",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/dir-compare/-/dir-compare-4.2.0.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/dir-compare/-/dir-compare-4.2.0.tgz",
 | 
				
			||||||
@ -10043,6 +10118,13 @@
 | 
				
			|||||||
        "node": ">= 6"
 | 
					        "node": ">= 6"
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/fast-safe-stringify": {
 | 
				
			||||||
 | 
					      "version": "2.1.1",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==",
 | 
				
			||||||
 | 
					      "dev": true,
 | 
				
			||||||
 | 
					      "license": "MIT"
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    "node_modules/fast-uri": {
 | 
					    "node_modules/fast-uri": {
 | 
				
			||||||
      "version": "3.0.3",
 | 
					      "version": "3.0.3",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.3.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.3.tgz",
 | 
				
			||||||
@ -10408,6 +10490,21 @@
 | 
				
			|||||||
        "node": ">= 6"
 | 
					        "node": ">= 6"
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/formidable": {
 | 
				
			||||||
 | 
					      "version": "3.5.2",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/formidable/-/formidable-3.5.2.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-Jqc1btCy3QzRbJaICGwKcBfGWuLADRerLzDqi2NwSt/UkXLsHJw2TVResiaoBufHVHy9aSgClOHCeJsSsFLTbg==",
 | 
				
			||||||
 | 
					      "dev": true,
 | 
				
			||||||
 | 
					      "license": "MIT",
 | 
				
			||||||
 | 
					      "dependencies": {
 | 
				
			||||||
 | 
					        "dezalgo": "^1.0.4",
 | 
				
			||||||
 | 
					        "hexoid": "^2.0.0",
 | 
				
			||||||
 | 
					        "once": "^1.4.0"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "funding": {
 | 
				
			||||||
 | 
					        "url": "https://ko-fi.com/tunnckoCore/commissions"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    "node_modules/forwarded": {
 | 
					    "node_modules/forwarded": {
 | 
				
			||||||
      "version": "0.2.0",
 | 
					      "version": "0.2.0",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
 | 
				
			||||||
@ -10970,6 +11067,16 @@
 | 
				
			|||||||
        "node": ">=18.0.0"
 | 
					        "node": ">=18.0.0"
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/hexoid": {
 | 
				
			||||||
 | 
					      "version": "2.0.0",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/hexoid/-/hexoid-2.0.0.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-qlspKUK7IlSQv2o+5I7yhUd7TxlOG2Vr5LTa3ve2XSNVKAL/n/u/7KLvKmFNimomDIKvZFXWHv0T12mv7rT8Aw==",
 | 
				
			||||||
 | 
					      "dev": true,
 | 
				
			||||||
 | 
					      "license": "MIT",
 | 
				
			||||||
 | 
					      "engines": {
 | 
				
			||||||
 | 
					        "node": ">=8"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    "node_modules/history": {
 | 
					    "node_modules/history": {
 | 
				
			||||||
      "version": "4.10.1",
 | 
					      "version": "4.10.1",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz",
 | 
				
			||||||
@ -16888,6 +16995,54 @@
 | 
				
			|||||||
        "node": ">= 8.0"
 | 
					        "node": ">= 8.0"
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/superagent": {
 | 
				
			||||||
 | 
					      "version": "9.0.2",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/superagent/-/superagent-9.0.2.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-xuW7dzkUpcJq7QnhOsnNUgtYp3xRwpt2F7abdRYIpCsAt0hhUqia0EdxyXZQQpNmGtsCzYHryaKSV3q3GJnq7w==",
 | 
				
			||||||
 | 
					      "dev": true,
 | 
				
			||||||
 | 
					      "license": "MIT",
 | 
				
			||||||
 | 
					      "dependencies": {
 | 
				
			||||||
 | 
					        "component-emitter": "^1.3.0",
 | 
				
			||||||
 | 
					        "cookiejar": "^2.1.4",
 | 
				
			||||||
 | 
					        "debug": "^4.3.4",
 | 
				
			||||||
 | 
					        "fast-safe-stringify": "^2.1.1",
 | 
				
			||||||
 | 
					        "form-data": "^4.0.0",
 | 
				
			||||||
 | 
					        "formidable": "^3.5.1",
 | 
				
			||||||
 | 
					        "methods": "^1.1.2",
 | 
				
			||||||
 | 
					        "mime": "2.6.0",
 | 
				
			||||||
 | 
					        "qs": "^6.11.0"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "engines": {
 | 
				
			||||||
 | 
					        "node": ">=14.18.0"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/superagent/node_modules/mime": {
 | 
				
			||||||
 | 
					      "version": "2.6.0",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==",
 | 
				
			||||||
 | 
					      "dev": true,
 | 
				
			||||||
 | 
					      "license": "MIT",
 | 
				
			||||||
 | 
					      "bin": {
 | 
				
			||||||
 | 
					        "mime": "cli.js"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "engines": {
 | 
				
			||||||
 | 
					        "node": ">=4.0.0"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/supertest": {
 | 
				
			||||||
 | 
					      "version": "7.0.0",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/supertest/-/supertest-7.0.0.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-qlsr7fIC0lSddmA3tzojvzubYxvlGtzumcdHgPwbFWMISQwL22MhM2Y3LNt+6w9Yyx7559VW5ab70dgphm8qQA==",
 | 
				
			||||||
 | 
					      "dev": true,
 | 
				
			||||||
 | 
					      "license": "MIT",
 | 
				
			||||||
 | 
					      "dependencies": {
 | 
				
			||||||
 | 
					        "methods": "^1.1.2",
 | 
				
			||||||
 | 
					        "superagent": "^9.0.1"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "engines": {
 | 
				
			||||||
 | 
					        "node": ">=14.18.0"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    "node_modules/supports-color": {
 | 
					    "node_modules/supports-color": {
 | 
				
			||||||
      "version": "7.2.0",
 | 
					      "version": "7.2.0",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										11
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								package.json
									
									
									
									
									
								
							@ -44,10 +44,11 @@
 | 
				
			|||||||
    "docs:build": "npm run docs:build-backend && npm run docs:build-frontend",
 | 
					    "docs:build": "npm run docs:build-backend && npm run docs:build-frontend",
 | 
				
			||||||
    "build:webpack": "tsx node_modules/webpack/bin/webpack.js -c webpack.config.ts",
 | 
					    "build:webpack": "tsx node_modules/webpack/bin/webpack.js -c webpack.config.ts",
 | 
				
			||||||
    "build:prepare-dist": "npm run build:webpack && rimraf ./dist && tsc && tsx ./bin/copy-dist.ts",
 | 
					    "build:prepare-dist": "npm run build:webpack && rimraf ./dist && tsc && tsx ./bin/copy-dist.ts",
 | 
				
			||||||
    "test": "npm run test:server && npm run test:client",
 | 
					    "test": "npm run client:test && npm run server:test",
 | 
				
			||||||
    "test:server": "cross-env TRILIUM_DATA_DIR=./integration-tests/db TRILIUM_INTEGRATION_TEST=memory vitest",
 | 
					    "server:test": "cross-env TRILIUM_ENV=dev TRILIUM_DATA_DIR=./integration-tests/db TRILIUM_INTEGRATION_TEST=memory vitest",
 | 
				
			||||||
    "test:client": "cross-env TRILIUM_DATA_DIR=./integration-tests/db TRILIUM_INTEGRATION_TEST=memory vitest --root src/public/app",
 | 
					    "server:coverage": "cross-env TRILIUM_ENV=dev TRILIUM_DATA_DIR=./integration-tests/db TRILIUM_INTEGRATION_TEST=memory vitest --coverage",
 | 
				
			||||||
    "test:coverage": "cross-env TRILIUM_DATA_DIR=./integration-tests/db vitest --coverage",
 | 
					    "client:test": "cross-env TRILIUM_ENV=dev TRILIUM_DATA_DIR=./integration-tests/db TRILIUM_INTEGRATION_TEST=memory vitest --root src/public/app",
 | 
				
			||||||
 | 
					    "client:coverage": "cross-env TRILIUM_ENV=dev TRILIUM_DATA_DIR=./integration-tests/db TRILIUM_INTEGRATION_TEST=memory vitest --root src/public/app --coverage",
 | 
				
			||||||
    "test:playwright": "playwright test",
 | 
					    "test:playwright": "playwright test",
 | 
				
			||||||
    "test:integration-edit-db": "cross-env TRILIUM_INTEGRATION_TEST=edit TRILIUM_PORT=8081 TRILIUM_ENV=dev TRILIUM_DATA_DIR=./integration-tests/db nodemon src/main.ts",
 | 
					    "test:integration-edit-db": "cross-env TRILIUM_INTEGRATION_TEST=edit TRILIUM_PORT=8081 TRILIUM_ENV=dev TRILIUM_DATA_DIR=./integration-tests/db nodemon src/main.ts",
 | 
				
			||||||
    "test:integration-mem-db": "cross-env TRILIUM_INTEGRATION_TEST=memory TRILIUM_PORT=8082 TRILIUM_DATA_DIR=./integration-tests/db nodemon src/main.ts",
 | 
					    "test:integration-mem-db": "cross-env TRILIUM_INTEGRATION_TEST=memory TRILIUM_PORT=8082 TRILIUM_DATA_DIR=./integration-tests/db nodemon src/main.ts",
 | 
				
			||||||
@ -203,6 +204,7 @@
 | 
				
			|||||||
    "@types/session-file-store": "1.2.5",
 | 
					    "@types/session-file-store": "1.2.5",
 | 
				
			||||||
    "@types/source-map-support": "0.5.10",
 | 
					    "@types/source-map-support": "0.5.10",
 | 
				
			||||||
    "@types/stream-throttle": "0.1.4",
 | 
					    "@types/stream-throttle": "0.1.4",
 | 
				
			||||||
 | 
					    "@types/supertest": "6.0.2",
 | 
				
			||||||
    "@types/swagger-ui-express": "4.1.8",
 | 
					    "@types/swagger-ui-express": "4.1.8",
 | 
				
			||||||
    "@types/tmp": "0.2.6",
 | 
					    "@types/tmp": "0.2.6",
 | 
				
			||||||
    "@types/turndown": "5.0.5",
 | 
					    "@types/turndown": "5.0.5",
 | 
				
			||||||
@ -226,6 +228,7 @@
 | 
				
			|||||||
    "rimraf": "6.0.1",
 | 
					    "rimraf": "6.0.1",
 | 
				
			||||||
    "sass": "1.85.1",
 | 
					    "sass": "1.85.1",
 | 
				
			||||||
    "sass-loader": "16.0.5",
 | 
					    "sass-loader": "16.0.5",
 | 
				
			||||||
 | 
					    "supertest": "7.0.0",
 | 
				
			||||||
    "swagger-jsdoc": "6.2.8",
 | 
					    "swagger-jsdoc": "6.2.8",
 | 
				
			||||||
    "tslib": "2.8.1",
 | 
					    "tslib": "2.8.1",
 | 
				
			||||||
    "tsx": "4.19.3",
 | 
					    "tsx": "4.19.3",
 | 
				
			||||||
 | 
				
			|||||||
@ -203,7 +203,7 @@ function renderFile(entity: FNote | FAttachment, type: string, $renderedContent:
 | 
				
			|||||||
        // open doesn't work for protected notes since it works through a browser which isn't in protected session
 | 
					        // open doesn't work for protected notes since it works through a browser which isn't in protected session
 | 
				
			||||||
        $openButton.toggle(!entity.isProtected);
 | 
					        $openButton.toggle(!entity.isProtected);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $content.append($('<div style="display: flex; justify-content: space-evenly; margin-top: 5px;">').append($downloadButton).append($openButton));
 | 
					        $content.append($('<footer class="file-footer">').append($downloadButton).append($openButton));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    $renderedContent.append($content);
 | 
					    $renderedContent.append($content);
 | 
				
			||||||
 | 
				
			|||||||
@ -9,7 +9,7 @@ interface CreateNewTasksOpts {
 | 
				
			|||||||
export async function createNewTask({ parentNoteId, title }: CreateNewTasksOpts) {
 | 
					export async function createNewTask({ parentNoteId, title }: CreateNewTasksOpts) {
 | 
				
			||||||
    await server.post(`tasks`, {
 | 
					    await server.post(`tasks`, {
 | 
				
			||||||
        parentNoteId,
 | 
					        parentNoteId,
 | 
				
			||||||
        title
 | 
					        title: title.trim()
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -2,6 +2,9 @@ import { defineConfig } from "vitest/config";
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
export default defineConfig({
 | 
					export default defineConfig({
 | 
				
			||||||
    test: {
 | 
					    test: {
 | 
				
			||||||
        environment: "happy-dom"
 | 
					        environment: "happy-dom",
 | 
				
			||||||
 | 
					        coverage: {
 | 
				
			||||||
 | 
					            reporter: [ "text", "html" ]
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
				
			|||||||
@ -20,6 +20,10 @@ const TPL = `
 | 
				
			|||||||
    .note-list-widget.full-height .note-list-widget-content {
 | 
					    .note-list-widget.full-height .note-list-widget-content {
 | 
				
			||||||
        height: 100%;
 | 
					        height: 100%;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .note-list-widget video {
 | 
				
			||||||
 | 
					        height: 100%;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    </style>
 | 
					    </style>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <div class="note-list-widget-content">
 | 
					    <div class="note-list-widget-content">
 | 
				
			||||||
 | 
				
			|||||||
@ -63,7 +63,7 @@ export default class NoteWrapperWidget extends FlexContainer<BasicWidget> {
 | 
				
			|||||||
            return true;
 | 
					            return true;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (note.type === "file" && note.mime === "application/pdf") {
 | 
					        if (note.type === "file" && (note.mime === "application/pdf" || note.mime.startsWith("video/"))) {
 | 
				
			||||||
            return true;
 | 
					            return true;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -22,6 +22,10 @@ const TPL = `
 | 
				
			|||||||
            padding: 0;
 | 
					            padding: 0;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        .note-split.full-content-width .note-detail-file[data-preview-type="video"] {
 | 
				
			||||||
 | 
					            overflow: hidden;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        .file-preview-content {
 | 
					        .file-preview-content {
 | 
				
			||||||
            background-color: var(--accented-background-color);
 | 
					            background-color: var(--accented-background-color);
 | 
				
			||||||
            padding: 15px;
 | 
					            padding: 15px;
 | 
				
			||||||
@ -29,6 +33,11 @@ const TPL = `
 | 
				
			|||||||
            overflow: auto;
 | 
					            overflow: auto;
 | 
				
			||||||
            margin: 10px;
 | 
					            margin: 10px;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        .note-detail-file > .video-preview {
 | 
				
			||||||
 | 
					            width: 100%;
 | 
				
			||||||
 | 
					            height: 100%;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    </style>
 | 
					    </style>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <div class="file-preview-too-big alert alert-info hidden-ext">
 | 
					    <div class="file-preview-too-big alert alert-info hidden-ext">
 | 
				
			||||||
@ -85,6 +94,8 @@ export default class FileTypeWidget extends TypeWidget {
 | 
				
			|||||||
        this.$videoPreview.hide();
 | 
					        this.$videoPreview.hide();
 | 
				
			||||||
        this.$audioPreview.hide();
 | 
					        this.$audioPreview.hide();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let previewType: string;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (blob?.content) {
 | 
					        if (blob?.content) {
 | 
				
			||||||
            this.$previewContent.show().scrollTop(0);
 | 
					            this.$previewContent.show().scrollTop(0);
 | 
				
			||||||
            const trimmedContent = blob.content.substring(0, TEXT_MAX_NUM_CHARS);
 | 
					            const trimmedContent = blob.content.substring(0, TEXT_MAX_NUM_CHARS);
 | 
				
			||||||
@ -92,23 +103,30 @@ export default class FileTypeWidget extends TypeWidget {
 | 
				
			|||||||
                this.$previewTooBig.removeClass("hidden-ext");
 | 
					                this.$previewTooBig.removeClass("hidden-ext");
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            this.$previewContent.text(trimmedContent);
 | 
					            this.$previewContent.text(trimmedContent);
 | 
				
			||||||
 | 
					            previewType = "text";
 | 
				
			||||||
        } else if (note.mime === "application/pdf") {
 | 
					        } else if (note.mime === "application/pdf") {
 | 
				
			||||||
            this.$pdfPreview.show().attr("src", openService.getUrlForDownload(`api/notes/${this.noteId}/open`));
 | 
					            this.$pdfPreview.show().attr("src", openService.getUrlForDownload(`api/notes/${this.noteId}/open`));
 | 
				
			||||||
 | 
					            previewType = "pdf";
 | 
				
			||||||
        } else if (note.mime.startsWith("video/")) {
 | 
					        } else if (note.mime.startsWith("video/")) {
 | 
				
			||||||
            this.$videoPreview
 | 
					            this.$videoPreview
 | 
				
			||||||
                .show()
 | 
					                .show()
 | 
				
			||||||
                .attr("src", openService.getUrlForDownload(`api/notes/${this.noteId}/open-partial`))
 | 
					                .attr("src", openService.getUrlForDownload(`api/notes/${this.noteId}/open-partial`))
 | 
				
			||||||
                .attr("type", this.note?.mime ?? "")
 | 
					                .attr("type", this.note?.mime ?? "")
 | 
				
			||||||
                .css("width", this.$widget.width() ?? 0);
 | 
					                .css("width", this.$widget.width() ?? 0);
 | 
				
			||||||
 | 
					            previewType = "video";
 | 
				
			||||||
        } else if (note.mime.startsWith("audio/")) {
 | 
					        } else if (note.mime.startsWith("audio/")) {
 | 
				
			||||||
            this.$audioPreview
 | 
					            this.$audioPreview
 | 
				
			||||||
                .show()
 | 
					                .show()
 | 
				
			||||||
                .attr("src", openService.getUrlForDownload(`api/notes/${this.noteId}/open-partial`))
 | 
					                .attr("src", openService.getUrlForDownload(`api/notes/${this.noteId}/open-partial`))
 | 
				
			||||||
                .attr("type", this.note?.mime ?? "")
 | 
					                .attr("type", this.note?.mime ?? "")
 | 
				
			||||||
                .css("width", this.$widget.width() ?? 0);
 | 
					                .css("width", this.$widget.width() ?? 0);
 | 
				
			||||||
 | 
					            previewType = "audio";
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            this.$previewNotAvailable.show();
 | 
					            this.$previewNotAvailable.show();
 | 
				
			||||||
 | 
					            previewType = "not-available";
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        this.$widget.attr("data-preview-type", previewType ?? "");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async entitiesReloadedEvent({ loadResults }: EventData<"entitiesReloaded">) {
 | 
					    async entitiesReloadedEvent({ loadResults }: EventData<"entitiesReloaded">) {
 | 
				
			||||||
 | 
				
			|||||||
@ -6,6 +6,7 @@ import * as taskService from "../../services/tasks.js";
 | 
				
			|||||||
import type { EventData } from "../../components/app_context.js";
 | 
					import type { EventData } from "../../components/app_context.js";
 | 
				
			||||||
import dayjs from "dayjs";
 | 
					import dayjs from "dayjs";
 | 
				
			||||||
import calendarTime from "dayjs/plugin/calendar.js";
 | 
					import calendarTime from "dayjs/plugin/calendar.js";
 | 
				
			||||||
 | 
					import { t } from "../../services/i18n.js";
 | 
				
			||||||
dayjs.extend(calendarTime);
 | 
					dayjs.extend(calendarTime);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const TPL = `
 | 
					const TPL = `
 | 
				
			||||||
@ -25,7 +26,7 @@ const TPL = `
 | 
				
			|||||||
            padding: 10px;
 | 
					            padding: 10px;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        .note-detail-task-list header {
 | 
					        .note-detail-task-list > header {
 | 
				
			||||||
            position: sticky;
 | 
					            position: sticky;
 | 
				
			||||||
            top: 0;
 | 
					            top: 0;
 | 
				
			||||||
            z-index: 100;
 | 
					            z-index: 100;
 | 
				
			||||||
@ -59,15 +60,23 @@ const TPL = `
 | 
				
			|||||||
            transition: background 250ms ease-in-out;
 | 
					            transition: background 250ms ease-in-out;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        .note-detail-task-list .task-container li > header {
 | 
				
			||||||
 | 
					            display: flex;
 | 
				
			||||||
 | 
					            flex-wrap: wrap;
 | 
				
			||||||
 | 
					            justify-content: flex-end;
 | 
				
			||||||
 | 
					            align-items: center;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        .note-detail-task-list .task-container li .check {
 | 
					        .note-detail-task-list .task-container li .check {
 | 
				
			||||||
            margin-right: 0.5em;
 | 
					            margin-right: 0.5em;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        .note-detail-task-list .task-container li .title {
 | 
				
			||||||
 | 
					            flex-grow: 1;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        .note-detail-task-list .task-container li .due-date {
 | 
					        .note-detail-task-list .task-container li .due-date {
 | 
				
			||||||
            float: right;
 | 
					 | 
				
			||||||
            font-size: 0.9rem;
 | 
					            font-size: 0.9rem;
 | 
				
			||||||
            margin-top: 0.1rem;
 | 
					 | 
				
			||||||
            vertical-align: middle;
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        .note-detail-task-list .task-container li.overdue .due-date {
 | 
					        .note-detail-task-list .task-container li.overdue .due-date {
 | 
				
			||||||
@ -81,6 +90,7 @@ function buildTasks(tasks: FTask[]) {
 | 
				
			|||||||
    let html = '';
 | 
					    let html = '';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const now = dayjs();
 | 
					    const now = dayjs();
 | 
				
			||||||
 | 
					    const dateFormat = "DD-MM-YYYY";
 | 
				
			||||||
    for (const task of tasks) {
 | 
					    for (const task of tasks) {
 | 
				
			||||||
        const classes = ["task"];
 | 
					        const classes = ["task"];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -89,14 +99,25 @@ function buildTasks(tasks: FTask[]) {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        html += `<li class="${classes.join(" ")}" data-task-id="${task.taskId}">`;
 | 
					        html += `<li class="${classes.join(" ")}" data-task-id="${task.taskId}">`;
 | 
				
			||||||
 | 
					        html += "<header>";
 | 
				
			||||||
 | 
					        html += '<span class="title">';
 | 
				
			||||||
        html += `<input type="checkbox" class="check" ${task.isDone ? "checked" : ""} />`;
 | 
					        html += `<input type="checkbox" class="check" ${task.isDone ? "checked" : ""} />`;
 | 
				
			||||||
        html += task.title;
 | 
					        html += `${task.title}</span>`;
 | 
				
			||||||
 | 
					        html += '</span>';
 | 
				
			||||||
        if (task.dueDate) {
 | 
					        if (task.dueDate) {
 | 
				
			||||||
            html += `<span class="due-date">`;
 | 
					            html += `<span class="due-date">`;
 | 
				
			||||||
            html += `<span class="bx bx-calendar"></span> `;
 | 
					            html += `<span class="bx bx-calendar"></span> `;
 | 
				
			||||||
            html += dayjs(task.dueDate).calendar();
 | 
					            html += dayjs(task.dueDate).calendar(null, {
 | 
				
			||||||
 | 
					                sameDay: `[${t("tasks.due.today")}]`,
 | 
				
			||||||
 | 
					                nextDay: `[${t("tasks.due.tomorrow")}]`,
 | 
				
			||||||
 | 
					                nextWeek: "dddd",
 | 
				
			||||||
 | 
					                lastDay: `[${t("tasks.due.yesterday")}]`,
 | 
				
			||||||
 | 
					                lastWeek: dateFormat,
 | 
				
			||||||
 | 
					                sameElse: dateFormat
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
            html += "</span>";
 | 
					            html += "</span>";
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        html += "</header>";
 | 
				
			||||||
        html += `<div class="edit-container"></div>`;
 | 
					        html += `<div class="edit-container"></div>`;
 | 
				
			||||||
        html += `</li>`;
 | 
					        html += `</li>`;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -142,20 +163,19 @@ export default class TaskListWidget extends TypeWidget {
 | 
				
			|||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        this.$taskContainer.on("click", "li", (e) => {
 | 
					        this.$taskContainer.on("click", "li", (e) => {
 | 
				
			||||||
            const $target = $(e.target);
 | 
					            if ((e.target as HTMLElement).tagName === "INPUT") {
 | 
				
			||||||
 | 
					 | 
				
			||||||
            // Don't collapse when clicking on an inside element such as the due date dropdown.
 | 
					 | 
				
			||||||
            if (e.currentTarget !== e.target) {
 | 
					 | 
				
			||||||
                return;
 | 
					                return;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            const $target = $(e.target);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Clear existing edit containers.
 | 
					            // Clear existing edit containers.
 | 
				
			||||||
            const $existingContainers = this.$taskContainer.find(".edit-container");
 | 
					            const $existingContainers = this.$taskContainer.find(".edit-container");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            $existingContainers.html("");
 | 
					            $existingContainers.html("");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Add the new edit container.
 | 
					            // Add the new edit container.
 | 
				
			||||||
            const $editContainer = $target.find(".edit-container");
 | 
					            const $editContainer = $target.closest("li").find(".edit-container");
 | 
				
			||||||
            const task = this.#getCorrespondingTask($target);
 | 
					            const task = this.#getCorrespondingTask($target);
 | 
				
			||||||
            if (task) {
 | 
					            if (task) {
 | 
				
			||||||
                $editContainer.html(buildEditContainer(task));
 | 
					                $editContainer.html(buildEditContainer(task));
 | 
				
			||||||
@ -183,7 +203,11 @@ export default class TaskListWidget extends TypeWidget {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #getCorrespondingTask($target: JQuery<HTMLElement>) {
 | 
					    #getCorrespondingTask($target: JQuery<HTMLElement>) {
 | 
				
			||||||
        const taskId = $target.closest("li")[0].dataset.taskId;
 | 
					        const $parentEl = $target.closest("li");
 | 
				
			||||||
 | 
					        if (!$parentEl.length) {
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        const taskId = $parentEl[0].dataset.taskId;
 | 
				
			||||||
        if (!taskId) {
 | 
					        if (!taskId) {
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
				
			|||||||
@ -1685,3 +1685,14 @@ body.zen .note-title-widget input {
 | 
				
			|||||||
    font-size: 1rem !important;
 | 
					    font-size: 1rem !important;
 | 
				
			||||||
    background: transparent !important;
 | 
					    background: transparent !important;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Content renderer */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					footer.file-footer {
 | 
				
			||||||
 | 
					    display: flex;
 | 
				
			||||||
 | 
					    justify-content: center;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					footer.file-footer button {
 | 
				
			||||||
 | 
					    margin: 5px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -1560,6 +1560,10 @@ div.bookmark-folder-widget .note-link .bx {
 | 
				
			|||||||
    border-bottom-color: var(--card-border-color);
 | 
					    border-bottom-color: var(--card-border-color);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.note-list-wrapper .note-book-card footer.file-footer {
 | 
				
			||||||
 | 
					    border: 1px solid var(--card-border-color);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.note-list-wrapper .note-book-card .note-book-header .note-icon {
 | 
					.note-list-wrapper .note-book-card .note-book-header .note-icon {
 | 
				
			||||||
    font-size: 17px;
 | 
					    font-size: 17px;
 | 
				
			||||||
    vertical-align: text-bottom;
 | 
					    vertical-align: text-bottom;
 | 
				
			||||||
@ -1610,7 +1614,8 @@ div.bookmark-folder-widget .note-link .bx {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
.note-list-wrapper .note-book-card .note-book-content.type-canvas .rendered-content,
 | 
					.note-list-wrapper .note-book-card .note-book-content.type-canvas .rendered-content,
 | 
				
			||||||
.note-list-wrapper .note-book-card .note-book-content.type-mindMap .rendered-content,
 | 
					.note-list-wrapper .note-book-card .note-book-content.type-mindMap .rendered-content,
 | 
				
			||||||
.note-list-wrapper .note-book-card .note-book-content.type-code .rendered-content {
 | 
					.note-list-wrapper .note-book-card .note-book-content.type-code .rendered-content,
 | 
				
			||||||
 | 
					.note-list-wrapper .note-book-card .note-book-content.type-video .rendered-content {
 | 
				
			||||||
    padding: 0;
 | 
					    padding: 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1675,5 +1675,12 @@
 | 
				
			|||||||
  "time_selector": {
 | 
					  "time_selector": {
 | 
				
			||||||
    "invalid_input": "The entered time value is not a valid number.",
 | 
					    "invalid_input": "The entered time value is not a valid number.",
 | 
				
			||||||
    "minimum_input": "The entered time value needs to be at least {{minimumSeconds}} seconds."
 | 
					    "minimum_input": "The entered time value needs to be at least {{minimumSeconds}} seconds."
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "tasks": {
 | 
				
			||||||
 | 
					    "due": {
 | 
				
			||||||
 | 
					      "today": "Today",
 | 
				
			||||||
 | 
					      "tomorrow": "Tomorrow",
 | 
				
			||||||
 | 
					      "yesterday": "Yesterday"
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1678,5 +1678,12 @@
 | 
				
			|||||||
    "redirect_bare_domain_description": "Redirecționează utilizatorii anonimi către pagina de partajare în locul paginii de autentificare",
 | 
					    "redirect_bare_domain_description": "Redirecționează utilizatorii anonimi către pagina de partajare în locul paginii de autentificare",
 | 
				
			||||||
    "redirect_bare_domain": "Redirecționează domeniul principal la pagina de partajare",
 | 
					    "redirect_bare_domain": "Redirecționează domeniul principal la pagina de partajare",
 | 
				
			||||||
    "check_share_root": "Verificare stare pagină partajată principală"
 | 
					    "check_share_root": "Verificare stare pagină partajată principală"
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "tasks": {
 | 
				
			||||||
 | 
					    "due": {
 | 
				
			||||||
 | 
					      "today": "Azi",
 | 
				
			||||||
 | 
					      "tomorrow": "Mâine",
 | 
				
			||||||
 | 
					      "yesterday": "Ieri"
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										34
									
								
								src/share/routes.spec.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								src/share/routes.spec.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,34 @@
 | 
				
			|||||||
 | 
					import { beforeAll, beforeEach, describe, expect, it } from "vitest";
 | 
				
			||||||
 | 
					import supertest from "supertest";
 | 
				
			||||||
 | 
					import { initializeTranslations } from "../services/i18n.js";
 | 
				
			||||||
 | 
					import type { Application, Request, Response, NextFunction } from "express";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let app: Application;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					describe("Share API test", () => {
 | 
				
			||||||
 | 
					    let cannotSetHeadersCount = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    beforeAll(async () => {
 | 
				
			||||||
 | 
					        initializeTranslations();
 | 
				
			||||||
 | 
					        app = (await import("../app.js")).default;
 | 
				
			||||||
 | 
					        app.use((err: any, req: Request, res: Response, next: NextFunction) => {
 | 
				
			||||||
 | 
					            if (err.message.includes("Cannot set headers after they are sent to the client")) {
 | 
				
			||||||
 | 
					                cannotSetHeadersCount++;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            next();
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    beforeEach(() => {
 | 
				
			||||||
 | 
					        cannotSetHeadersCount = 0;
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it("requests password for password-protected share", async () => {
 | 
				
			||||||
 | 
					        await supertest(app)
 | 
				
			||||||
 | 
					            .get("/share/YjlPRj2E9fOV")
 | 
				
			||||||
 | 
					            .expect("WWW-Authenticate", 'Basic realm="User Visible Realm", charset="UTF-8"');
 | 
				
			||||||
 | 
					        expect(cannotSetHeadersCount).toBe(0);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
@ -87,7 +87,6 @@ function checkNoteAccess(noteId: string, req: Request, res: Response) {
 | 
				
			|||||||
    const header = req.header("Authorization");
 | 
					    const header = req.header("Authorization");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!header?.startsWith("Basic ")) {
 | 
					    if (!header?.startsWith("Basic ")) {
 | 
				
			||||||
        requestCredentials(res);
 | 
					 | 
				
			||||||
        return false;
 | 
					        return false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -19,7 +19,9 @@ export default defineConfig({
 | 
				
			|||||||
    test: {
 | 
					    test: {
 | 
				
			||||||
        exclude: [...configDefaults.exclude, ...customExcludes],
 | 
					        exclude: [...configDefaults.exclude, ...customExcludes],
 | 
				
			||||||
        coverage: {
 | 
					        coverage: {
 | 
				
			||||||
            exclude: [...coverageConfigDefaults.exclude, ...customExcludes]
 | 
					            reporter: [ "text", "html" ],
 | 
				
			||||||
 | 
					            include: ["src/**"],
 | 
				
			||||||
 | 
					            exclude: ["src/public/**"]
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user