diff --git a/Pipfile.lock b/Pipfile.lock index 3637bbe50..39805737f 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -569,11 +569,11 @@ }, "filelock": { "hashes": [ - "sha256:75997740323c5f12e18f10b494bc11c03e42843129f980f17c04352cc7b09d40", - "sha256:eb8f0f2d37ed68223ea63e3bddf2fac99667e4362c88b3f762e434d160190d18" + "sha256:ad98852315c2ab702aeb628412cbf7e95b7ce8c3bf9565670b4eaecf1db370a9", + "sha256:fc03ae43288c013d2ea83c8597001b1129db351aad9c57fe2409327916b8e718" ], "index": "pypi", - "version": "==3.10.2" + "version": "==3.12.0" }, "flower": { "hashes": [ diff --git a/docker/env-from-file.sh b/docker/env-from-file.sh index 37535c220..b67a82c86 100644 --- a/docker/env-from-file.sh +++ b/docker/env-from-file.sh @@ -15,6 +15,10 @@ do env_name=${line%%=*} # Check if it starts with "PAPERLESS_" and ends in "_FILE" if [[ ${env_name} == PAPERLESS_*_FILE ]]; then + # This should have been named different.. + if [[ ${env_name} == "PAPERLESS_OCR_SKIP_ARCHIVE_FILE" ]]; then + continue + fi # Extract the value of the environment env_value=${line#*=} diff --git a/docs/configuration.md b/docs/configuration.md index bde170e5c..cb5af9d86 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -322,8 +322,7 @@ You can read more about this in [the Django project's documentation](https://doc Can also be set using PAPERLESS_URL (see above). - If manually set, please remember to include "localhost". Otherwise - docker healthcheck will fail. + "localhost" is always allowed for docker healthcheck Defaults to "\*", which is all hosts. diff --git a/src-ui/package-lock.json b/src-ui/package-lock.json index 473f6c565..8c15f45af 100644 --- a/src-ui/package-lock.json +++ b/src-ui/package-lock.json @@ -8,14 +8,14 @@ "name": "paperless-ui", "version": "0.0.0", "dependencies": { - "@angular/common": "~15.2.7", - "@angular/compiler": "~15.2.7", - "@angular/core": "~15.2.7", - "@angular/forms": "~15.2.7", - "@angular/localize": "~15.2.7", - "@angular/platform-browser": "~15.2.7", - "@angular/platform-browser-dynamic": "~15.2.7", - "@angular/router": "~15.2.7", + "@angular/common": "~15.2.8", + "@angular/compiler": "~15.2.8", + "@angular/core": "~15.2.8", + "@angular/forms": "~15.2.8", + "@angular/localize": "~15.2.8", + "@angular/platform-browser": "~15.2.8", + "@angular/platform-browser-dynamic": "~15.2.8", + "@angular/router": "~15.2.8", "@ng-bootstrap/ng-bootstrap": "^14.1.0", "@ng-select/ng-select": "^10.0.4", "@ngneat/dirty-check-forms": "^3.0.3", @@ -28,7 +28,7 @@ "ngx-cookie-service": "^15.0.0", "ngx-file-drop": "^15.0.0", "ngx-ui-tour-ng-bootstrap": "^12.6.0", - "rxjs": "^7.8.0", + "rxjs": "^7.8.1", "tslib": "^2.4.1", "uuid": "^9.0.0", "zone.js": "^0.13.0" @@ -41,14 +41,14 @@ "@angular-eslint/eslint-plugin-template": "15.2.1", "@angular-eslint/schematics": "15.2.1", "@angular-eslint/template-parser": "15.2.1", - "@angular/cli": "~15.2.6", - "@angular/compiler-cli": "~15.2.7", + "@angular/cli": "~15.2.7", + "@angular/compiler-cli": "~15.2.8", "@types/jest": "^29.5.0", - "@types/node": "^18.15.11", - "@typescript-eslint/eslint-plugin": "^5.58.0", - "@typescript-eslint/parser": "^5.58.0", + "@types/node": "^18.16.3", + "@typescript-eslint/eslint-plugin": "^5.59.2", + "@typescript-eslint/parser": "^5.59.2", "concurrently": "^8.0.1", - "eslint": "^8.38.0", + "eslint": "^8.39.0", "jest": "28.1.3", "jest-environment-jsdom": "^29.5.0", "jest-preset-angular": "^12.2.6", @@ -58,7 +58,7 @@ }, "optionalDependencies": { "@cypress/schematic": "^2.1.1", - "cypress": "^12.9.0" + "cypress": "^12.11.0" } }, "node_modules/@ampproject/remapping": { @@ -306,12 +306,12 @@ } }, "node_modules/@angular-devkit/architect": { - "version": "0.1502.6", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1502.6.tgz", - "integrity": "sha512-n4oJ9vzFWwabf+AfgqqevVzdJhNKNCav7ytefjD/Y01vkNwlXqWnHcvyyHCLkVibJ6WR8J9lK4t77j/HFlDvWQ==", + "version": "0.1502.7", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1502.7.tgz", + "integrity": "sha512-MzB6D/yUo6cBJfQ31zNDHJ3C3iKmBtxP3i9WIRnnkZwS1VUfO8OX3TZ6lycYbREF1oL/AQ/r9GK+KA5DNEBSAw==", "devOptional": true, "dependencies": { - "@angular-devkit/core": "15.2.6", + "@angular-devkit/core": "15.2.7", "rxjs": "6.6.7" }, "engines": { @@ -339,15 +339,15 @@ "devOptional": true }, "node_modules/@angular-devkit/build-angular": { - "version": "15.2.6", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-15.2.6.tgz", - "integrity": "sha512-OmMcdXXUrAdZNxwxDE8SUx1FMcq9FyMnrSv1PmP9sHPBoxAdBVc/qNdGA9V7C5yHvWHGgzsx7ZK5TDuvifzS5g==", + "version": "15.2.7", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-15.2.7.tgz", + "integrity": "sha512-zZ+tlt5aNGY9APUdjQHeVFJpVLeixlZRNHmfdXD+rN4WR2q9E0pTvLUThrkOmO8YrVyGbdvcw1O7XNdL+3b02w==", "dev": true, "dependencies": { "@ampproject/remapping": "2.2.0", - "@angular-devkit/architect": "0.1502.6", - "@angular-devkit/build-webpack": "0.1502.6", - "@angular-devkit/core": "15.2.6", + "@angular-devkit/architect": "0.1502.7", + "@angular-devkit/build-webpack": "0.1502.7", + "@angular-devkit/core": "15.2.7", "@babel/core": "7.20.12", "@babel/generator": "7.20.14", "@babel/helper-annotate-as-pure": "7.18.6", @@ -359,7 +359,7 @@ "@babel/runtime": "7.20.13", "@babel/template": "7.20.7", "@discoveryjs/json-ext": "0.5.7", - "@ngtools/webpack": "15.2.6", + "@ngtools/webpack": "15.2.7", "ansi-colors": "4.1.3", "autoprefixer": "10.4.13", "babel-loader": "9.1.2", @@ -479,12 +479,12 @@ "dev": true }, "node_modules/@angular-devkit/build-webpack": { - "version": "0.1502.6", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1502.6.tgz", - "integrity": "sha512-X7XQ11QDz2Bs5qpJ3a5glIytvI+S74ORQxdzvT6a6KB8ayW0SgZEhTwD+GF7pa5My8draIaXBGzzQR1qmpWK5Q==", + "version": "0.1502.7", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1502.7.tgz", + "integrity": "sha512-sNE4t4shSwxagqm+jdojbkYfuo/CHNMi4faItDWTTsCOf9wQxCxV4Waxee4akAkv3K6fzrnZy3ad/oQQMUl0Iw==", "dev": true, "dependencies": { - "@angular-devkit/architect": "0.1502.6", + "@angular-devkit/architect": "0.1502.7", "rxjs": "6.6.7" }, "engines": { @@ -516,9 +516,9 @@ "dev": true }, "node_modules/@angular-devkit/core": { - "version": "15.2.6", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-15.2.6.tgz", - "integrity": "sha512-YVTWZ+M+xNKdFX4EnY9QX49PZraawiaA0iTd2CUW8ZoTUvU7yOGMKZLSdz6aokTMRVfm0449wt6YL994ibOo1g==", + "version": "15.2.7", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-15.2.7.tgz", + "integrity": "sha512-k2MKUm4ygTD9+89neqMmBphDr0o8Tp9RtgfzbS8VHgGkGYlbu0KPsxHyHB3Mvzl1EkSz6EHyrU3t89m+Rcj1lw==", "devOptional": true, "dependencies": { "ajv": "8.12.0", @@ -560,12 +560,12 @@ "devOptional": true }, "node_modules/@angular-devkit/schematics": { - "version": "15.2.6", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-15.2.6.tgz", - "integrity": "sha512-f7VgnAcok7AwR/DhX0ZWskB0rFBo/KsvtIUA2qZSrpKMf8eFiwu03dv/b2mI0vnf+1FBfIQzJvO0ww45zRp6dA==", + "version": "15.2.7", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-15.2.7.tgz", + "integrity": "sha512-umQ+SgEMjqPHimHOBVhDn5NNGVoMLKQkI2fwbENXV72BqQqdh1K3D4QSNlUXitTaH0NEZZaAawE1vZHzzeAoNA==", "devOptional": true, "dependencies": { - "@angular-devkit/core": "15.2.6", + "@angular-devkit/core": "15.2.7", "jsonc-parser": "3.2.0", "magic-string": "0.29.0", "ora": "5.4.1", @@ -700,15 +700,15 @@ } }, "node_modules/@angular/cli": { - "version": "15.2.6", - "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-15.2.6.tgz", - "integrity": "sha512-wNkQ/qCVbd4pERaGVagKJPifEvjRNY5otwsd4iRVubY/XOcIHcYChUThZwgQdVfNAImfJPMZNrhbGxejuWLA9w==", + "version": "15.2.7", + "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-15.2.7.tgz", + "integrity": "sha512-gGUIjaVN//bO72zRK3GNcCRVeism56BCRfkXSywKedCWFK4IZsatIL1IXT6OiJC22NsUCMaAFPD0wygSUCZaig==", "devOptional": true, "dependencies": { - "@angular-devkit/architect": "0.1502.6", - "@angular-devkit/core": "15.2.6", - "@angular-devkit/schematics": "15.2.6", - "@schematics/angular": "15.2.6", + "@angular-devkit/architect": "0.1502.7", + "@angular-devkit/core": "15.2.7", + "@angular-devkit/schematics": "15.2.7", + "@schematics/angular": "15.2.7", "@yarnpkg/lockfile": "1.1.0", "ansi-colors": "4.1.3", "ini": "3.0.1", @@ -734,9 +734,9 @@ } }, "node_modules/@angular/common": { - "version": "15.2.7", - "resolved": "https://registry.npmjs.org/@angular/common/-/common-15.2.7.tgz", - "integrity": "sha512-CbmrQeZ0yChQrF/ab3v+gv6x2uLbv/s1wZNUBSO/p1STz6BZzHRJqObVlfPlQvyBx5btBBy/+I1sUh1yumARDA==", + "version": "15.2.8", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-15.2.8.tgz", + "integrity": "sha512-yLDQihiRcVl38HrWMPbqgzOaSUw85AQH5BsGdjbS6BpoBQj3EXOpccCMFsuxOKxPG4toatgawNqrEnK0Jpv9Mw==", "dependencies": { "tslib": "^2.3.0" }, @@ -744,14 +744,14 @@ "node": "^14.20.0 || ^16.13.0 || >=18.10.0" }, "peerDependencies": { - "@angular/core": "15.2.7", + "@angular/core": "15.2.8", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/compiler": { - "version": "15.2.7", - "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-15.2.7.tgz", - "integrity": "sha512-SesyYI2ExUa13XukXgIsmfg3ar90HbWeWDJTgmzsIfph0M9t6+SaPGpf3FCtdBgNADIpUFp3cieCOJgLESzxYQ==", + "version": "15.2.8", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-15.2.8.tgz", + "integrity": "sha512-+dvspIDvuGoYqdL7r/3o9ojkR3fH1zevgC0ISJivcIrMi+WcJ0FV2JmJdnm8V52oNsHy+sMF9eEZGEbCbACE/A==", "dependencies": { "tslib": "^2.3.0" }, @@ -759,7 +759,7 @@ "node": "^14.20.0 || ^16.13.0 || >=18.10.0" }, "peerDependencies": { - "@angular/core": "15.2.7" + "@angular/core": "15.2.8" }, "peerDependenciesMeta": { "@angular/core": { @@ -768,9 +768,9 @@ } }, "node_modules/@angular/compiler-cli": { - "version": "15.2.7", - "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-15.2.7.tgz", - "integrity": "sha512-4v51dOaT8GDUzRh6+mCLZOaYuU9FYX6vOHaLod9np3tVWPhcpoF2ZklRSiQDeFqrhr5B4vuCp/Lh9N2wzc22XQ==", + "version": "15.2.8", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-15.2.8.tgz", + "integrity": "sha512-fFxaDlbILo0t2t662qA0cjgn+kWItGlc1tFYKU6X7bvYb3t2e0cd9FzrFPLXUQVboGis83ULcJ2zkDxScnuPuQ==", "dependencies": { "@babel/core": "7.19.3", "@jridgewell/sourcemap-codec": "^1.4.14", @@ -792,7 +792,7 @@ "node": "^14.20.0 || ^16.13.0 || >=18.10.0" }, "peerDependencies": { - "@angular/compiler": "15.2.7", + "@angular/compiler": "15.2.8", "typescript": ">=4.8.2 <5.0" } }, @@ -834,9 +834,9 @@ } }, "node_modules/@angular/core": { - "version": "15.2.7", - "resolved": "https://registry.npmjs.org/@angular/core/-/core-15.2.7.tgz", - "integrity": "sha512-iS7JCJubRFqdndoUdAnvNkQRT3tY5tNFupBQS/sytkwxVrdBg+Is5jpdgk741n824vTMsE+CnuY0SETar8rN6g==", + "version": "15.2.8", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-15.2.8.tgz", + "integrity": "sha512-NDs+g4uM4EhyCvluf8a0YBCFXsDAEfCMHOD5cS00Bl+liTQ7JwtmepkWXMyjLB92irC9JaR79kdy4BoIKOh8WA==", "dependencies": { "tslib": "^2.3.0" }, @@ -849,9 +849,9 @@ } }, "node_modules/@angular/forms": { - "version": "15.2.7", - "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-15.2.7.tgz", - "integrity": "sha512-rzrebDIrtxxOeMcBzRBxqaOBZ+T1DJrysG/6YWZy428W/Z3MfPxUarPxgfx/oZI+x5uUsDaZmyoRdhVPJ2KhZg==", + "version": "15.2.8", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-15.2.8.tgz", + "integrity": "sha512-VyevVj20DdQWjAQUyiFTe+DAzqG9GqfAOWn376Y/lhPcwxAojXePTGNgtQud566/urDrNrP5haaLD6O36/3n+w==", "dependencies": { "tslib": "^2.3.0" }, @@ -859,16 +859,16 @@ "node": "^14.20.0 || ^16.13.0 || >=18.10.0" }, "peerDependencies": { - "@angular/common": "15.2.7", - "@angular/core": "15.2.7", - "@angular/platform-browser": "15.2.7", + "@angular/common": "15.2.8", + "@angular/core": "15.2.8", + "@angular/platform-browser": "15.2.8", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/localize": { - "version": "15.2.7", - "resolved": "https://registry.npmjs.org/@angular/localize/-/localize-15.2.7.tgz", - "integrity": "sha512-ySuy35QKApWH9sW3PfnAAnZjLl3NT+SacvlEWigrTeCqfBEuDPUG57ugvc1/Lzuo09UOh3HQkrQBbdWAILd8JA==", + "version": "15.2.8", + "resolved": "https://registry.npmjs.org/@angular/localize/-/localize-15.2.8.tgz", + "integrity": "sha512-wJLBp0MUnET9kHzBtqIlZ3RQ56JFItXSgmBXagQq+MU+uJZmGvuw6fez0i5wkgv9Rgnr25oCULVtpTF+T5RGYA==", "dependencies": { "@babel/core": "7.19.3", "glob": "8.1.0", @@ -883,8 +883,8 @@ "node": "^14.20.0 || ^16.13.0 || >=18.10.0" }, "peerDependencies": { - "@angular/compiler": "15.2.7", - "@angular/compiler-cli": "15.2.7" + "@angular/compiler": "15.2.8", + "@angular/compiler-cli": "15.2.8" } }, "node_modules/@angular/localize/node_modules/@babel/core": { @@ -925,9 +925,9 @@ } }, "node_modules/@angular/platform-browser": { - "version": "15.2.7", - "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-15.2.7.tgz", - "integrity": "sha512-aCbd7xyuP7c2eDITkOTDO2mqP550WHCBN8U6VnjysqtB5ocbJtR6z/MIRItN/Zx+xj3piiaKei//XIkb3Q5fXQ==", + "version": "15.2.8", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-15.2.8.tgz", + "integrity": "sha512-8sKFUld54inj0FnQ1ydhFxnDgsbbf43W9FALye/5uEtLgwwE/ZvkNYMaQ7hq1JPuQRMDj3gJkFqaLeFjplpHDA==", "dependencies": { "tslib": "^2.3.0" }, @@ -935,9 +935,9 @@ "node": "^14.20.0 || ^16.13.0 || >=18.10.0" }, "peerDependencies": { - "@angular/animations": "15.2.7", - "@angular/common": "15.2.7", - "@angular/core": "15.2.7" + "@angular/animations": "15.2.8", + "@angular/common": "15.2.8", + "@angular/core": "15.2.8" }, "peerDependenciesMeta": { "@angular/animations": { @@ -946,9 +946,9 @@ } }, "node_modules/@angular/platform-browser-dynamic": { - "version": "15.2.7", - "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-15.2.7.tgz", - "integrity": "sha512-t1Nf7hgbcYvhmxuzgUtsV47jrI5CXUBqrtz5I0ilWG92zZTig5qvfd1/2Ub8NHz87uHNrnggyZpL2+4MJ26nyQ==", + "version": "15.2.8", + "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-15.2.8.tgz", + "integrity": "sha512-75HyoZNibA3u/FvdK4Aw5KMzUmS/nDk5N8s7gfM09fe1resSPgFiW8JJEkr1xiUdA2WtSRbHs34y5rHLDe7n1Q==", "dependencies": { "tslib": "^2.3.0" }, @@ -956,16 +956,16 @@ "node": "^14.20.0 || ^16.13.0 || >=18.10.0" }, "peerDependencies": { - "@angular/common": "15.2.7", - "@angular/compiler": "15.2.7", - "@angular/core": "15.2.7", - "@angular/platform-browser": "15.2.7" + "@angular/common": "15.2.8", + "@angular/compiler": "15.2.8", + "@angular/core": "15.2.8", + "@angular/platform-browser": "15.2.8" } }, "node_modules/@angular/router": { - "version": "15.2.7", - "resolved": "https://registry.npmjs.org/@angular/router/-/router-15.2.7.tgz", - "integrity": "sha512-Wkk+oJSUrVafJjmv9uE1SoY4wDE9bjX7ald+UXePz+QyM/PFoLkm/CzLYjFBkJnsOkOVxw1VmvacoUjWN6BCTQ==", + "version": "15.2.8", + "resolved": "https://registry.npmjs.org/@angular/router/-/router-15.2.8.tgz", + "integrity": "sha512-C62QBEeJSBTNTrQHZiklPrxwJwuENoZzWX22MMJ7dxl+7VjRgnmj8J7mcX9fLjHlL+mC3RvesMlX7sGZRQV1cg==", "dependencies": { "tslib": "^2.3.0" }, @@ -973,9 +973,9 @@ "node": "^14.20.0 || ^16.13.0 || >=18.10.0" }, "peerDependencies": { - "@angular/common": "15.2.7", - "@angular/core": "15.2.7", - "@angular/platform-browser": "15.2.7", + "@angular/common": "15.2.8", + "@angular/core": "15.2.8", + "@angular/platform-browser": "15.2.8", "rxjs": "^6.5.3 || ^7.4.0" } }, @@ -3262,9 +3262,9 @@ } }, "node_modules/@eslint/js": { - "version": "8.38.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.38.0.tgz", - "integrity": "sha512-IoD2MfUnOV58ghIHCiil01PcohxjbYR/qCxsoC+xNgUwh1EY8jOOrYmu3d3a71+tJJ23uscEV4X2HJWMsPJu4g==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.39.0.tgz", + "integrity": "sha512-kf9RB0Fg7NZfap83B3QOqOGg9QmD9yBudqQXzzOtn3i4y7ZUXe5ONeW34Gwi+TxhH4mvj72R1Zc300KUMa9Bng==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -4119,9 +4119,9 @@ } }, "node_modules/@ngtools/webpack": { - "version": "15.2.6", - "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-15.2.6.tgz", - "integrity": "sha512-I+kekKItfsCLdX+ZjjmsWqd0AyoYGTQPjlbQAiPtmdH73/rfPOF4Q/3AU4tzTdn0n0GXqZWv6VOs91w99ydi0A==", + "version": "15.2.7", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-15.2.7.tgz", + "integrity": "sha512-iUCSR03PzGSpwwZ5soioTIWsTPBayzkZfhKMkfz1RqtkbcxC4I07NRoQ1djofhsYyW2I1n7XS8w3K7NILtN3gQ==", "dev": true, "engines": { "node": "^14.20.0 || ^16.13.0 || >=18.10.0", @@ -4332,13 +4332,13 @@ } }, "node_modules/@schematics/angular": { - "version": "15.2.6", - "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-15.2.6.tgz", - "integrity": "sha512-OcBUvVAxZEMBX+fi0ytybeAdmStra+GwtlvipS70yOxcAgJ84ZrnZGN7a072cCVQcq7AgqUfssnyqCx1wu+yCg==", + "version": "15.2.7", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-15.2.7.tgz", + "integrity": "sha512-5fC6Es6HWpvmCnpPwTxHQq6KQuxtPaheFgoElHJM6uBgJDTr993MIw/3FsZvqLkO9hv/yWbr4gilqjEoesJSWg==", "devOptional": true, "dependencies": { - "@angular-devkit/core": "15.2.6", - "@angular-devkit/schematics": "15.2.6", + "@angular-devkit/core": "15.2.7", + "@angular-devkit/schematics": "15.2.7", "jsonc-parser": "3.2.0" }, "engines": { @@ -4495,9 +4495,9 @@ } }, "node_modules/@types/connect-history-api-fallback": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.5.tgz", - "integrity": "sha512-h8QJa8xSb1WD4fpKBDcATDNGXghFj6/3GRWG6dhmRcu0RX1Ubasur2Uvx5aeEwlf0MwblEC2bMzzMQntxnw/Cw==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.0.tgz", + "integrity": "sha512-4x5FkPpLipqwthjPsF7ZRbOv3uoLUFkTA9G9v583qi4pACvq0uTELrB8OLUzPWUI4IJIyvM85vzkV1nyiI2Lig==", "dev": true, "dependencies": { "@types/express-serve-static-core": "*", @@ -4543,14 +4543,15 @@ } }, "node_modules/@types/express-serve-static-core": { - "version": "4.17.33", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.33.tgz", - "integrity": "sha512-TPBqmR/HRYI3eC2E5hmiivIzv+bidAfXofM+sbonAGvyDhySGw9/PQZFt2BLOrjUUR++4eJVpx6KnLQK1Fk9tA==", + "version": "4.17.34", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.34.tgz", + "integrity": "sha512-fvr49XlCGoUj2Pp730AItckfjat4WNb0lb3kfrLWffd+RLeoGAMsq7UOy04PAPtoL01uKwcp6u8nhzpgpDYr3w==", "dev": true, "dependencies": { "@types/node": "*", "@types/qs": "*", - "@types/range-parser": "*" + "@types/range-parser": "*", + "@types/send": "*" } }, "node_modules/@types/graceful-fs": { @@ -4563,9 +4564,9 @@ } }, "node_modules/@types/http-proxy": { - "version": "1.17.10", - "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.10.tgz", - "integrity": "sha512-Qs5aULi+zV1bwKAg5z1PWnDXWmsn+LxIvUGv6E2+OOMYhclZMO+OXd9pYVf2gLykf2I7IV2u7oTHwChPNsvJ7g==", + "version": "1.17.11", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.11.tgz", + "integrity": "sha512-HC8G7c1WmaF2ekqpnFq626xd3Zz0uvaqFmBJNRZCGEZCXkvSdJoNFn/8Ygbd9fKNQj8UzLdCETaI0UWPAjK7IA==", "dev": true, "dependencies": { "@types/node": "*" @@ -4891,15 +4892,15 @@ "dev": true }, "node_modules/@types/mime": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz", - "integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", + "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==", "dev": true }, "node_modules/@types/node": { - "version": "18.15.11", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.11.tgz", - "integrity": "sha512-E5Kwq2n4SbMzQOn6wnmBjuK9ouqlURrcZDVfbo9ftDDTFt3nk7ZKK4GMOzoYgnpQJKcxwQw+lGaBvvlMo0qN/Q==", + "version": "18.16.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.16.3.tgz", + "integrity": "sha512-OPs5WnnT1xkCBiuQrZA4+YAV4HEJejmHneyraIaxsbev5yCEr6KMwINNFP9wQeFIw8FWcoTqF3vQsa5CDaI+8Q==", "devOptional": true }, "node_modules/@types/parse-json": { @@ -4944,6 +4945,16 @@ "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==", "dev": true }, + "node_modules/@types/send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.1.tgz", + "integrity": "sha512-Cwo8LE/0rnvX7kIIa3QHCkcuF21c05Ayb0ZfxPiv0W8VRiZiNW/WuRupHKpqqGVGf7SUA44QSOUKaEd9lIrd/Q==", + "dev": true, + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, "node_modules/@types/serve-index": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.1.tgz", @@ -5030,15 +5041,15 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.58.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.58.0.tgz", - "integrity": "sha512-vxHvLhH0qgBd3/tW6/VccptSfc8FxPQIkmNTVLWcCOVqSBvqpnKkBTYrhcGlXfSnd78azwe+PsjYFj0X34/njA==", + "version": "5.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.2.tgz", + "integrity": "sha512-yVrXupeHjRxLDcPKL10sGQ/QlVrA8J5IYOEWVqk0lJaSZP7X5DfnP7Ns3cc74/blmbipQ1htFNVGsHX6wsYm0A==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.58.0", - "@typescript-eslint/type-utils": "5.58.0", - "@typescript-eslint/utils": "5.58.0", + "@typescript-eslint/scope-manager": "5.59.2", + "@typescript-eslint/type-utils": "5.59.2", + "@typescript-eslint/utils": "5.59.2", "debug": "^4.3.4", "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", @@ -5064,13 +5075,13 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/type-utils": { - "version": "5.58.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.58.0.tgz", - "integrity": "sha512-FF5vP/SKAFJ+LmR9PENql7fQVVgGDOS+dq3j+cKl9iW/9VuZC/8CFmzIP0DLKXfWKpRHawJiG70rVH+xZZbp8w==", + "version": "5.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.2.tgz", + "integrity": "sha512-b1LS2phBOsEy/T381bxkkywfQXkV1dWda/z0PhnIy3bC5+rQWQDS7fk9CSpcXBccPY27Z6vBEuaPBCKCgYezyQ==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "5.58.0", - "@typescript-eslint/utils": "5.58.0", + "@typescript-eslint/typescript-estree": "5.59.2", + "@typescript-eslint/utils": "5.59.2", "debug": "^4.3.4", "tsutils": "^3.21.0" }, @@ -5091,17 +5102,17 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/utils": { - "version": "5.58.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.58.0.tgz", - "integrity": "sha512-gAmLOTFXMXOC+zP1fsqm3VceKSBQJNzV385Ok3+yzlavNHZoedajjS4UyS21gabJYcobuigQPs/z71A9MdJFqQ==", + "version": "5.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.2.tgz", + "integrity": "sha512-kSuF6/77TZzyGPhGO4uVp+f0SBoYxCDf+lW3GKhtKru/L8k/Hd7NFQxyWUeY7Z/KGB2C6Fe3yf2vVi4V9TsCSQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.58.0", - "@typescript-eslint/types": "5.58.0", - "@typescript-eslint/typescript-estree": "5.58.0", + "@typescript-eslint/scope-manager": "5.59.2", + "@typescript-eslint/types": "5.59.2", + "@typescript-eslint/typescript-estree": "5.59.2", "eslint-scope": "^5.1.1", "semver": "^7.3.7" }, @@ -5139,14 +5150,14 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "5.58.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.58.0.tgz", - "integrity": "sha512-ixaM3gRtlfrKzP8N6lRhBbjTow1t6ztfBvQNGuRM8qH1bjFFXIJ35XY+FC0RRBKn3C6cT+7VW1y8tNm7DwPHDQ==", + "version": "5.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.2.tgz", + "integrity": "sha512-uq0sKyw6ao1iFOZZGk9F8Nro/8+gfB5ezl1cA06SrqbgJAt0SRoFhb9pXaHvkrxUpZaoLxt8KlovHNk8Gp6/HQ==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.58.0", - "@typescript-eslint/types": "5.58.0", - "@typescript-eslint/typescript-estree": "5.58.0", + "@typescript-eslint/scope-manager": "5.59.2", + "@typescript-eslint/types": "5.59.2", + "@typescript-eslint/typescript-estree": "5.59.2", "debug": "^4.3.4" }, "engines": { @@ -5166,13 +5177,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.58.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.58.0.tgz", - "integrity": "sha512-b+w8ypN5CFvrXWQb9Ow9T4/6LC2MikNf1viLkYTiTbkQl46CnR69w7lajz1icW0TBsYmlpg+mRzFJ4LEJ8X9NA==", + "version": "5.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.2.tgz", + "integrity": "sha512-dB1v7ROySwQWKqQ8rEWcdbTsFjh2G0vn8KUyvTXdPoyzSL6lLGkiXEV5CvpJsEe9xIdKV+8Zqb7wif2issoOFA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.58.0", - "@typescript-eslint/visitor-keys": "5.58.0" + "@typescript-eslint/types": "5.59.2", + "@typescript-eslint/visitor-keys": "5.59.2" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -5267,9 +5278,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "5.58.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.58.0.tgz", - "integrity": "sha512-JYV4eITHPzVQMnHZcYJXl2ZloC7thuUHrcUmxtzvItyKPvQ50kb9QXBkgNAt90OYMqwaodQh2kHutWZl1fc+1g==", + "version": "5.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.2.tgz", + "integrity": "sha512-LbJ/HqoVs2XTGq5shkiKaNTuVv5tTejdHgfdjqRUGdYhjW1crm/M7og2jhVskMt8/4wS3T1+PfFvL1K3wqYj4w==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -5280,13 +5291,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.58.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.58.0.tgz", - "integrity": "sha512-cRACvGTodA+UxnYM2uwA2KCwRL7VAzo45syNysqlMyNyjw0Z35Icc9ihPJZjIYuA5bXJYiJ2YGUB59BqlOZT1Q==", + "version": "5.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.2.tgz", + "integrity": "sha512-+j4SmbwVmZsQ9jEyBMgpuBD0rKwi9RxRpjX71Brr73RsYnEr3Lt5QZ624Bxphp8HUkSKfqGnPJp1kA5nl0Sh7Q==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.58.0", - "@typescript-eslint/visitor-keys": "5.58.0", + "@typescript-eslint/types": "5.59.2", + "@typescript-eslint/visitor-keys": "5.59.2", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -5429,12 +5440,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.58.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.58.0.tgz", - "integrity": "sha512-/fBraTlPj0jwdyTwLyrRTxv/3lnU2H96pNTVM6z3esTWLtA5MZ9ghSMJ7Rb+TtUAdtEw9EyJzJ0EydIMKxQ9gA==", + "version": "5.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.2.tgz", + "integrity": "sha512-EEpsO8m3RASrKAHI9jpavNv9NlEUebV4qmF1OWxSTtKSFBpC1NCmWazDQHFivRf0O1DV11BA645yrLEVQ0/Lig==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.58.0", + "@typescript-eslint/types": "5.59.2", "eslint-visitor-keys": "^3.3.0" }, "engines": { @@ -6988,9 +6999,9 @@ } }, "node_modules/commander": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", - "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", + "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", "optional": true, "engines": { "node": ">= 6" @@ -7563,9 +7574,9 @@ "dev": true }, "node_modules/cypress": { - "version": "12.9.0", - "resolved": "https://registry.npmjs.org/cypress/-/cypress-12.9.0.tgz", - "integrity": "sha512-Ofe09LbHKgSqX89Iy1xen2WvpgbvNxDzsWx3mgU1mfILouELeXYGwIib3ItCwoRrRifoQwcBFmY54Vs0zw7QCg==", + "version": "12.11.0", + "resolved": "https://registry.npmjs.org/cypress/-/cypress-12.11.0.tgz", + "integrity": "sha512-TJE+CCWI26Hwr5Msb9GpQhFLubdYooW0fmlPwTsfiyxmngqc7+SZGLPeIkj2dTSSZSEtpQVzOzvcnzH0o8G7Vw==", "hasInstallScript": true, "optional": true, "dependencies": { @@ -7583,7 +7594,7 @@ "check-more-types": "^2.24.0", "cli-cursor": "^3.1.0", "cli-table3": "~0.6.1", - "commander": "^5.1.0", + "commander": "^6.2.1", "common-tags": "^1.8.0", "dayjs": "^1.10.4", "debug": "^4.3.4", @@ -7601,7 +7612,7 @@ "listr2": "^3.8.3", "lodash": "^4.17.21", "log-symbols": "^4.0.0", - "minimist": "^1.2.6", + "minimist": "^1.2.8", "ospath": "^1.2.2", "pretty-bytes": "^5.6.0", "proxy-from-env": "1.0.0", @@ -8013,9 +8024,9 @@ "dev": true }, "node_modules/dns-packet": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.5.0.tgz", - "integrity": "sha512-USawdAUzRkV6xrqTjiAEp6M9YagZEzWcSUaZTcIFAiyQWW1SoI6KyId8y2+/71wbgHKQAKd+iupLv4YvEwYWvA==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.0.tgz", + "integrity": "sha512-rza3UH1LwdHh9qyPXp8lkwpjSNk/AMD3dPytUoRoqnypDUhY0xvbdmVhWOfxO68frEfV9BU8V12Ez7ZsHGZpCQ==", "dev": true, "dependencies": { "@leichtgewicht/ip-codec": "^2.0.1" @@ -8447,15 +8458,15 @@ } }, "node_modules/eslint": { - "version": "8.38.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.38.0.tgz", - "integrity": "sha512-pIdsD2jwlUGf/U38Jv97t8lq6HpaU/G9NKbYmpWpZGw3LdTNhZLbJePqxOXGB5+JEKfOPU/XLxYxFh03nr1KTg==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.39.0.tgz", + "integrity": "sha512-mwiok6cy7KTW7rBpo05k6+p4YVZByLNjAZ/ACB9DRCu4YDRwjXI01tWHp6KAUWelsBetTxKK/2sHB0vdS8Z2Og==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.4.0", "@eslint/eslintrc": "^2.0.2", - "@eslint/js": "8.38.0", + "@eslint/js": "8.39.0", "@humanwhocodes/config-array": "^0.11.8", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", @@ -8465,7 +8476,7 @@ "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.1", + "eslint-scope": "^7.2.0", "eslint-visitor-keys": "^3.4.0", "espree": "^9.5.1", "esquery": "^1.4.2", @@ -8504,9 +8515,9 @@ } }, "node_modules/eslint-scope": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", - "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz", + "integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==", "dev": true, "dependencies": { "esrecurse": "^4.3.0", @@ -8514,6 +8525,9 @@ }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/eslint-utils": { @@ -14071,9 +14085,9 @@ } }, "node_modules/minimist": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", - "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "devOptional": true, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -16249,9 +16263,9 @@ } }, "node_modules/rxjs": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.0.tgz", - "integrity": "sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg==", + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", "dependencies": { "tslib": "^2.1.0" } diff --git a/src-ui/package.json b/src-ui/package.json index a156d63a3..e02b98d50 100644 --- a/src-ui/package.json +++ b/src-ui/package.json @@ -13,14 +13,14 @@ }, "private": true, "dependencies": { - "@angular/common": "~15.2.7", - "@angular/compiler": "~15.2.7", - "@angular/core": "~15.2.7", - "@angular/forms": "~15.2.7", - "@angular/localize": "~15.2.7", - "@angular/platform-browser": "~15.2.7", - "@angular/platform-browser-dynamic": "~15.2.7", - "@angular/router": "~15.2.7", + "@angular/common": "~15.2.8", + "@angular/compiler": "~15.2.8", + "@angular/core": "~15.2.8", + "@angular/forms": "~15.2.8", + "@angular/localize": "~15.2.8", + "@angular/platform-browser": "~15.2.8", + "@angular/platform-browser-dynamic": "~15.2.8", + "@angular/router": "~15.2.8", "@ng-bootstrap/ng-bootstrap": "^14.1.0", "@ng-select/ng-select": "^10.0.4", "@ngneat/dirty-check-forms": "^3.0.3", @@ -33,7 +33,7 @@ "ngx-cookie-service": "^15.0.0", "ngx-file-drop": "^15.0.0", "ngx-ui-tour-ng-bootstrap": "^12.6.0", - "rxjs": "^7.8.0", + "rxjs": "^7.8.1", "tslib": "^2.4.1", "uuid": "^9.0.0", "zone.js": "^0.13.0" @@ -46,14 +46,14 @@ "@angular-eslint/eslint-plugin-template": "15.2.1", "@angular-eslint/schematics": "15.2.1", "@angular-eslint/template-parser": "15.2.1", - "@angular/cli": "~15.2.6", - "@angular/compiler-cli": "~15.2.7", + "@angular/cli": "~15.2.7", + "@angular/compiler-cli": "~15.2.8", "@types/jest": "^29.5.0", - "@types/node": "^18.15.11", - "@typescript-eslint/eslint-plugin": "^5.58.0", - "@typescript-eslint/parser": "^5.58.0", + "@types/node": "^18.16.3", + "@typescript-eslint/eslint-plugin": "^5.59.2", + "@typescript-eslint/parser": "^5.59.2", "concurrently": "^8.0.1", - "eslint": "^8.38.0", + "eslint": "^8.39.0", "jest": "28.1.3", "jest-environment-jsdom": "^29.5.0", "jest-preset-angular": "^12.2.6", @@ -63,6 +63,6 @@ }, "optionalDependencies": { "@cypress/schematic": "^2.1.1", - "cypress": "^12.9.0" + "cypress": "^12.11.0" } } diff --git a/src-ui/src/app/components/app-frame/app-frame.component.html b/src-ui/src/app/components/app-frame/app-frame.component.html index 90e75be58..be0240eb5 100644 --- a/src-ui/src/app/components/app-frame/app-frame.component.html +++ b/src-ui/src/app/components/app-frame/app-frame.component.html @@ -44,7 +44,7 @@ Settings - + Logout diff --git a/src-ui/src/app/components/app-frame/app-frame.component.ts b/src-ui/src/app/components/app-frame/app-frame.component.ts index 24b7e8f23..cff4366da 100644 --- a/src-ui/src/app/components/app-frame/app-frame.component.ts +++ b/src-ui/src/app/components/app-frame/app-frame.component.ts @@ -243,4 +243,8 @@ export class AppFrameComponent this.checkForUpdates() } } + + onLogout() { + this.openDocumentsService.closeAll() + } } diff --git a/src-ui/src/app/components/common/filterable-dropdown/filterable-dropdown.component.html b/src-ui/src/app/components/common/filterable-dropdown/filterable-dropdown.component.html index 5bf75d62d..57197d1ea 100644 --- a/src-ui/src/app/components/common/filterable-dropdown/filterable-dropdown.component.html +++ b/src-ui/src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -1,4 +1,4 @@ - + 0 ? 'btn-primary' : 'btn-outline-primary'" [disabled]="disabled"> @@ -31,9 +31,11 @@ - - - + + + + diff --git a/src-ui/src/app/components/common/filterable-dropdown/filterable-dropdown.component.ts b/src-ui/src/app/components/common/filterable-dropdown/filterable-dropdown.component.ts index 12de82693..b324ac6a0 100644 --- a/src-ui/src/app/components/common/filterable-dropdown/filterable-dropdown.component.ts +++ b/src-ui/src/app/components/common/filterable-dropdown/filterable-dropdown.component.ts @@ -324,6 +324,7 @@ export class FilterableDropdownSelectionModel { export class FilterableDropdownComponent { @ViewChild('listFilterTextInput') listFilterTextInput: ElementRef @ViewChild('dropdown') dropdown: NgbDropdown + @ViewChild('buttonItems') buttonItems: ElementRef filterText: string @@ -416,14 +417,10 @@ export class FilterableDropdownComponent { return this.title ? this.title.replace(/\s/g, '_').toLowerCase() : null } - getUpdatedDocumentCount(id: number) { - if (this.documentCounts) { - return this.documentCounts.find((c) => c.id === id)?.document_count - } - } - modelIsDirty: boolean = false + private keyboardIndex: number + constructor(private filterPipe: FilterPipe) { this.selectionModelChange.subscribe((updatedModel) => { this.modelIsDirty = updatedModel.isDirty() @@ -461,11 +458,13 @@ export class FilterableDropdownComponent { let filtered = this.filterPipe.transform(this.items, this.filterText) if (filtered.length == 1) { this.selectionModel.toggle(filtered[0].id) - if (this.editing) { - this.applyClicked() - } else { - this.dropdown.close() - } + setTimeout(() => { + if (this.editing) { + this.applyClicked() + } else { + this.dropdown.close() + } + }, 200) } } @@ -481,4 +480,76 @@ export class FilterableDropdownComponent { this.selectionModel.reset(true) this.selectionModelChange.emit(this.selectionModel) } + + getUpdatedDocumentCount(id: number) { + if (this.documentCounts) { + return this.documentCounts.find((c) => c.id === id)?.document_count + } + } + + listKeyDown(event: KeyboardEvent) { + switch (event.key) { + case 'ArrowDown': + if (event.target instanceof HTMLInputElement) { + if ( + !this.filterText || + event.target.selectionStart === this.filterText.length + ) { + this.keyboardIndex = -1 + this.focusNextButtonItem() + event.preventDefault() + } + } else if (event.target instanceof HTMLButtonElement) { + this.focusNextButtonItem() + event.preventDefault() + } + break + case 'ArrowUp': + if (event.target instanceof HTMLButtonElement) { + if (this.keyboardIndex === 0) { + this.listFilterTextInput.nativeElement.focus() + } else { + this.focusPreviousButtonItem() + } + event.preventDefault() + } + break + case 'Tab': + // just track the index in case user uses arrows + if (event.target instanceof HTMLInputElement) { + this.keyboardIndex = 0 + } else if (event.target instanceof HTMLButtonElement) { + if (event.shiftKey) { + if (this.keyboardIndex > 0) { + this.focusPreviousButtonItem(false) + } + } else { + this.focusNextButtonItem(false) + } + } + default: + break + } + } + + focusNextButtonItem(setFocus: boolean = true) { + this.keyboardIndex = Math.min(this.items.length - 1, this.keyboardIndex + 1) + if (setFocus) this.setButtonItemFocus() + } + + focusPreviousButtonItem(setFocus: boolean = true) { + this.keyboardIndex = Math.max(0, this.keyboardIndex - 1) + if (setFocus) this.setButtonItemFocus() + } + + setButtonItemFocus() { + this.buttonItems.nativeElement.children[ + this.keyboardIndex + ]?.children[0].focus() + } + + setButtonItemIndex(index: number) { + // just track the index in case user uses arrows + this.keyboardIndex = index + } } diff --git a/src-ui/src/app/components/document-detail/document-detail.component.html b/src-ui/src/app/components/document-detail/document-detail.component.html index 71092fe72..7b21d4b50 100644 --- a/src-ui/src/app/components/document-detail/document-detail.component.html +++ b/src-ui/src/app/components/document-detail/document-detail.component.html @@ -100,7 +100,7 @@ Metadata - + Date modified diff --git a/src-ui/src/app/components/document-detail/document-detail.component.ts b/src-ui/src/app/components/document-detail/document-detail.component.ts index 6d03ec024..bcce59441 100644 --- a/src-ui/src/app/components/document-detail/document-detail.component.ts +++ b/src-ui/src/app/components/document-detail/document-detail.component.ts @@ -236,10 +236,21 @@ export class DocumentDetailComponent true ) this.suggestions = null - if (this.openDocumentService.getOpenDocument(this.documentId)) { - this.updateComponent( - this.openDocumentService.getOpenDocument(this.documentId) - ) + const openDocument = this.openDocumentService.getOpenDocument( + this.documentId + ) + if (openDocument) { + if (this.documentForm.dirty) { + Object.assign(openDocument, this.documentForm.value) + openDocument['owner'] = + this.documentForm.get('permissions_form').value['owner'] + openDocument['permissions'] = + this.documentForm.get('permissions_form').value[ + 'set_permissions' + ] + delete openDocument['permissions_form'] + } + this.updateComponent(openDocument) } else { this.openDocumentService.openDocument(doc) this.updateComponent(doc) @@ -317,6 +328,10 @@ export class DocumentDetailComponent if (navIDKey) { this.activeNavID = DocumentDetailNavIDs[navIDKey] } + } else if (paramMap.get('id')) { + this.router.navigate(['documents', +paramMap.get('id'), 'details'], { + replaceUrl: true, + }) } }) } diff --git a/src-ui/src/app/components/document-notes/document-notes.component.ts b/src-ui/src/app/components/document-notes/document-notes.component.ts index c8bb3cc2b..c005b917c 100644 --- a/src-ui/src/app/components/document-notes/document-notes.component.ts +++ b/src-ui/src/app/components/document-notes/document-notes.component.ts @@ -86,7 +86,7 @@ export class DocumentNotesComponent extends ComponentWithPermissions { displayName(note: PaperlessDocumentNote): string { if (!note.user) return '' - const user = this.users.find((u) => u.id === note.user) + const user = this.users?.find((u) => u.id === note.user) if (!user) return '' const nameComponents = [] if (user.first_name) nameComponents.unshift(user.first_name) diff --git a/src-ui/src/environments/environment.prod.ts b/src-ui/src/environments/environment.prod.ts index db7622932..fb2153883 100644 --- a/src-ui/src/environments/environment.prod.ts +++ b/src-ui/src/environments/environment.prod.ts @@ -5,7 +5,7 @@ export const environment = { apiBaseUrl: document.baseURI + 'api/', apiVersion: '2', appTitle: 'Paperless-ngx', - version: '1.14.2', + version: '1.14.2-dev', webSocketHost: window.location.host, webSocketProtocol: window.location.protocol == 'https:' ? 'wss:' : 'ws:', webSocketBaseUrl: base_url.pathname + 'ws/', diff --git a/src-ui/src/locale/messages.ar_AR.xlf b/src-ui/src/locale/messages.ar_AR.xlf index 5009e06dc..820ee2a3d 100644 --- a/src-ui/src/locale/messages.ar_AR.xlf +++ b/src-ui/src/locale/messages.ar_AR.xlf @@ -5671,7 +5671,7 @@ src/app/services/settings.service.ts 177 - Catalan + اللغة الكتالونية Czech @@ -5719,7 +5719,7 @@ src/app/services/settings.service.ts 213 - Finnish + الفنلندية French diff --git a/src-ui/src/locale/messages.ca_ES.xlf b/src-ui/src/locale/messages.ca_ES.xlf index 238af11a3..abf1025f1 100644 --- a/src-ui/src/locale/messages.ca_ES.xlf +++ b/src-ui/src/locale/messages.ca_ES.xlf @@ -5719,7 +5719,7 @@ src/app/services/settings.service.ts 213 - Finnish + Finès French diff --git a/src-ui/src/locale/messages.de_DE.xlf b/src-ui/src/locale/messages.de_DE.xlf index 2056b8e74..5b91dbd44 100644 --- a/src-ui/src/locale/messages.de_DE.xlf +++ b/src-ui/src/locale/messages.de_DE.xlf @@ -5719,7 +5719,7 @@ src/app/services/settings.service.ts 213 - Finnish + Finnisch French diff --git a/src-ui/src/locale/messages.id_ID.xlf b/src-ui/src/locale/messages.id_ID.xlf index 97d67f959..ee6981b7b 100644 --- a/src-ui/src/locale/messages.id_ID.xlf +++ b/src-ui/src/locale/messages.id_ID.xlf @@ -170,7 +170,7 @@ node_modules/src/ngb-config.ts 13 - Increment hours + Penambahan jam First @@ -194,7 +194,7 @@ node_modules/src/ngb-config.ts 13 - Decrement hours + Pengurangan jam Next @@ -210,7 +210,7 @@ node_modules/src/ngb-config.ts 13 - Increment minutes + Penambahan menit Last @@ -226,7 +226,7 @@ node_modules/src/ngb-config.ts 13 - Decrement minutes + Pengurangan menit SS @@ -250,7 +250,7 @@ node_modules/src/ngb-config.ts 13 - Increment seconds + Penambahan detik Decrement seconds @@ -258,7 +258,7 @@ node_modules/src/ngb-config.ts 13 - Decrement seconds + Pengurangan detik @@ -284,7 +284,7 @@ src/app/app.component.html 7 - Drop files to begin upload + Jatuhkan file untuk mulai mengunggah Document added @@ -308,7 +308,7 @@ src/app/app.component.ts 102 - Document was added to paperless. + Dokumen telah ditambahkan ke paperless. Open document @@ -380,7 +380,7 @@ src/app/app.component.ts 145 - The dashboard can be used to show saved views, such as an 'Inbox'. Those settings are found under Settings > Saved Views once you have created some. + Dasbor dapat digunakan untuk menampilkan tampilan tersimpan, seperti sebagai 'Kotak Masuk'. Pengaturan tersebut ditemukan di bawah Pengaturan > Tampilan tersimpan setelah Anda membuatnya. Drag-and-drop documents here to start uploading or place them in the consume folder. You can also drag-and-drop documents anywhere on all other pages of the web app. Once you do, Paperless-ngx will start training its machine learning algorithms. @@ -460,7 +460,7 @@ src/app/app.component.ts 233 - Lastly, on behalf of every contributor to this community-supported project, thank you for using Paperless-ngx! + Terakhir, atas nama setiap kontributor untuk proyek yang didukung komunitas ini, terima kasih telah menggunakan Paperless-ngx! Initiating upload... @@ -493,7 +493,7 @@ src/app/components/app-frame/app-frame.component.html 39 - Logged in as + Masuk sebagai Settings @@ -517,7 +517,7 @@ src/app/components/manage/settings/settings.component.html 192 - Settings + Pengaturan Logout @@ -585,7 +585,7 @@ src/app/components/manage/settings/settings.component.html 189 - Saved views + Tampilan disimpan Open documents @@ -613,7 +613,7 @@ src/app/components/app-frame/app-frame.component.html 127 - Manage + Kelola Correspondents @@ -673,7 +673,7 @@ src/app/components/app-frame/app-frame.component.html 155 - Storage paths + Lokasi penyimpanan File Tasks @@ -685,7 +685,7 @@ src/app/components/manage/tasks/tasks.component.html 1 - File Tasks + Tugas File File Tasks @@ -693,7 +693,7 @@ src/app/components/app-frame/app-frame.component.html 163 - File Tasks + Tugas File Logs @@ -709,7 +709,7 @@ src/app/components/manage/logs/logs.component.html 1 - Logs + Log Info @@ -781,7 +781,7 @@ src/app/components/app-frame/app-frame.component.html 217 - Paperless-ngx can automatically check for updates + Paperless-ngx dapat secara otomatis memeriksa pembaruan How does this work? @@ -809,7 +809,7 @@ src/app/components/manage/settings/settings.component.ts 593 - An error occurred while saving settings. + Terjadi kesalahan saat menyimpan setelan. An error occurred while saving update checking settings. @@ -817,7 +817,7 @@ src/app/components/app-frame/app-frame.component.ts 222 - An error occurred while saving update checking settings. + Terjadi kesalahan saat menyimpan setelan pemeriksaan pembaruan. Clear @@ -833,7 +833,7 @@ src/app/components/common/date-dropdown/date-dropdown.component.html 47 - Clear + Bersihkan Cancel @@ -877,7 +877,7 @@ src/app/components/document-list/bulk-editor/bulk-editor.component.ts 440 - Confirm + Konfirmasi After @@ -1017,7 +1017,7 @@ src/app/components/manage/tasks/tasks.component.html 40 - Name + Nama Matching algorithm @@ -1037,7 +1037,7 @@ src/app/components/common/edit-dialog/tag-edit-dialog/tag-edit-dialog.component.html 13 - Matching algorithm + Mencocokkan algoritma Matching pattern @@ -1193,7 +1193,7 @@ src/app/components/common/edit-dialog/correspondent-edit-dialog/correspondent-edit-dialog.component.ts 29 - Edit correspondent + Ubah koresponden Create new document type @@ -1201,7 +1201,7 @@ src/app/components/common/edit-dialog/document-type-edit-dialog/document-type-edit-dialog.component.ts 25 - Create new document type + Buat jenis dokumen baru Edit document type @@ -1217,7 +1217,7 @@ src/app/components/common/edit-dialog/edit-dialog.component.ts 71 - Create new item + Buat barang baru Edit item @@ -1225,7 +1225,7 @@ src/app/components/common/edit-dialog/edit-dialog.component.ts 75 - Edit item + Sunting barang Could not save element: @@ -1257,7 +1257,7 @@ src/app/components/document-list/bulk-editor/bulk-editor.component.html 81 - Permissions + Akses Create new user group @@ -1265,7 +1265,7 @@ src/app/components/common/edit-dialog/group-edit-dialog/group-edit-dialog.component.ts 24 - Create new user group + Membuat grup pengguna baru Edit user group @@ -1273,7 +1273,7 @@ src/app/components/common/edit-dialog/group-edit-dialog/group-edit-dialog.component.ts 28 - Edit user group + Ubah grup pengguna IMAP Server @@ -1281,7 +1281,7 @@ src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.html 11 - IMAP Server + Server IMAP IMAP Port @@ -1289,7 +1289,7 @@ src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.html 12 - IMAP Port + Port IMAP IMAP Security @@ -1297,7 +1297,7 @@ src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.html 13 - IMAP Security + Keamanan IMAP Username @@ -1313,7 +1313,7 @@ src/app/components/manage/settings/settings.component.html 344 - Username + Nama pengguna Password @@ -1417,7 +1417,7 @@ src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.ts 14 - SSL + SSL STARTTLS @@ -1425,7 +1425,7 @@ src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.ts 15 - STARTTLS + STARTTLS Create new mail account @@ -1501,7 +1501,7 @@ src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html 14 - Attachment type + Jenis lampiran Consumption scope @@ -1565,7 +1565,7 @@ src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html 23 - Filter body + Saring badan Filter attachment filename @@ -1573,7 +1573,7 @@ src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html 24 - Filter attachment filename + Saring nama file lampiran Only consume documents which entirely match this filename if specified. Wildcards such as *.pdf or *invoice* are allowed. Case insensitive. @@ -1685,7 +1685,7 @@ src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts 45 - Process message as .eml and attachments separately + Proses pesan sebagai .eml dan lampiran terpisah Delete @@ -1909,7 +1909,7 @@ src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.ts 39 - Edit storage path + Ubah lokasi penyimpanan Color @@ -2069,7 +2069,7 @@ src/app/components/common/filterable-dropdown/filterable-dropdown.component.html 24 - Include + Sertakan Exclude @@ -2077,7 +2077,7 @@ src/app/components/common/filterable-dropdown/filterable-dropdown.component.html 26 - Exclude + Kecuali Apply @@ -2093,7 +2093,7 @@ src/app/components/common/filterable-dropdown/filterable-dropdown.component.html 46 - Click again to exclude items. + Klik lagi untuk mengecualikan barang. Not assigned @@ -2110,7 +2110,7 @@ src/app/components/common/input/date/date.component.html 13 - Invalid date. + Tanggal tidak valid. Suggestions: @@ -2126,7 +2126,7 @@ src/app/components/common/input/tags/tags.component.html 43 - Suggestions: + Saran: Edit Permissions @@ -2134,7 +2134,7 @@ src/app/components/common/input/permissions/permissions-form/permissions-form.component.html 7 - Edit Permissions + Ubah akses Owner: @@ -2166,7 +2166,7 @@ src/app/components/document-list/document-card-large/document-card-large.component.html 56 - View + Lihat Users: @@ -2271,7 +2271,7 @@ 12 Used for both types, correspondents, storage paths - Add item + Tambah barang Private @@ -2319,7 +2319,7 @@ src/app/components/common/permissions-select/permissions-select.component.html 5 - Type + Jenis Add @@ -2327,7 +2327,7 @@ src/app/components/common/permissions-select/permissions-select.component.html 7 - Add + Tambah Change @@ -2335,7 +2335,7 @@ src/app/components/common/permissions-select/permissions-select.component.html 8 - Change + Ubah @@ -2389,7 +2389,7 @@ src/app/components/dashboard/dashboard.component.ts 36 - Hello , welcome to Paperless-ngx + Halo , selamat datang ke Paperless-ngx Welcome to Paperless-ngx @@ -2397,7 +2397,7 @@ src/app/components/dashboard/dashboard.component.ts 38 - Welcome to Paperless-ngx + Selamat datang ke Paperless-ngx Show all @@ -2433,7 +2433,7 @@ src/app/services/rest/document.service.ts 22 - Created + Dibuat Title @@ -2473,7 +2473,7 @@ src/app/components/dashboard/widgets/statistics-widget/statistics-widget.component.html 4 - Go to inbox + Pergi ke kotak masuk Documents in inbox @@ -2481,7 +2481,7 @@ src/app/components/dashboard/widgets/statistics-widget/statistics-widget.component.html 5 - Documents in inbox + Dokumen dalam kotak masuk Go to documents @@ -2489,7 +2489,7 @@ src/app/components/dashboard/widgets/statistics-widget/statistics-widget.component.html 8 - Go to documents + Pergi ke dokumen Total documents @@ -2538,7 +2538,7 @@ src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.html 13 - Drop documents here or + Jatuhkan dokumen di sini atau Browse files @@ -2592,7 +2592,7 @@ 269 this string is used to separate processing, failed and added on the file upload widget - , + , Paperless-ngx is running! @@ -2608,7 +2608,7 @@ src/app/components/dashboard/widgets/welcome-widget/welcome-widget.component.html 4 - You're ready to start uploading documents! Explore the various features of this web app on your own, or start a quick tour using the button below. + Anda siap untuk mulai mengunggah dokumen! Jelajahi berbagai fitur aplikasi web ini, atau mulai tur singkat menggunakan tombol di bawah ini. More detail on how to use and configure Paperless-ngx is always available in the documentation. @@ -2616,7 +2616,7 @@ src/app/components/dashboard/widgets/welcome-widget/welcome-widget.component.html 5 - More detail on how to use and configure Paperless-ngx is always available in the documentation. + Detail lebih lanjut tentang cara menggunakan dan mengonfigurasi Paperless-ngx selalu tersedia di dokumentasi. Thanks for being a part of the Paperless-ngx community! @@ -2624,7 +2624,7 @@ src/app/components/dashboard/widgets/welcome-widget/welcome-widget.component.html 8 - Thanks for being a part of the Paperless-ngx community! + Terima kasih telah menjadi bagian dalam komunitas Paperless-ngx! Start the tour @@ -2640,7 +2640,7 @@ src/app/components/document-asn/document-asn.component.html 1 - Searching document with asn + Mencari dokumen dengan asn Page @@ -2660,7 +2660,7 @@ src/app/components/document-detail/document-detail.component.html 5,6 - of + dari Download @@ -2700,7 +2700,7 @@ src/app/components/document-list/bulk-editor/bulk-editor.component.html 92 - Redo OCR + Lakukan ulang pengenalan karakter More like this @@ -2712,7 +2712,7 @@ src/app/components/document-list/document-card-large/document-card-large.component.html 44 - More like this + Lebih seperti ini Close @@ -2748,7 +2748,7 @@ src/app/components/document-detail/document-detail.component.html 76 - Archive serial number + Nomor serial arsip Date created @@ -2780,7 +2780,7 @@ src/app/services/rest/document.service.ts 19 - Correspondent + Koresponden Document type @@ -2804,7 +2804,7 @@ src/app/services/rest/document.service.ts 21 - Document type + Jenis dokumen Storage path @@ -2824,7 +2824,7 @@ src/app/components/document-list/filter-editor/filter-editor.component.html 52 - Storage path + Lokasi penyimpanan Default @@ -2852,7 +2852,7 @@ src/app/components/document-detail/metadata-collapse/metadata-collapse.component.ts 17 - Metadata + Metadata Date modified @@ -2924,7 +2924,7 @@ src/app/components/document-detail/document-detail.component.html 138 - Archive file size + Ukuran file arsip Original document metadata @@ -2948,7 +2948,7 @@ src/app/components/document-detail/document-detail.component.html 151 - Preview + Pratinjau Enter Password @@ -2960,7 +2960,7 @@ src/app/components/document-detail/document-detail.component.html 215 - Enter Password + Masukan Kata Sandi Notes @@ -2976,7 +2976,7 @@ src/app/components/document-detail/document-detail.component.html 194 - Discard + Batalkan Save & next @@ -2984,7 +2984,7 @@ src/app/components/document-detail/document-detail.component.html 195 - Save & next + Simpan & lanjut An error occurred loading content: @@ -2992,7 +2992,7 @@ src/app/components/document-detail/document-detail.component.ts 226,228 - An error occurred loading content: + Terjadi masalah saat memuat konten: Error retrieving metadata @@ -3000,7 +3000,7 @@ src/app/components/document-detail/document-detail.component.ts 354 - Error retrieving metadata + Kesalahan saat mendapatkan metadata Error retrieving suggestions @@ -3032,7 +3032,7 @@ src/app/components/document-detail/document-detail.component.ts 542 - Error saving document + Kesalahan saat menyimpan dokumen Confirm delete @@ -3044,7 +3044,7 @@ src/app/components/manage/management-list/management-list.component.ts 210 - Confirm delete + Konfirmasi hapus Do you really want to delete document ""? @@ -3052,7 +3052,7 @@ src/app/components/document-detail/document-detail.component.ts 572 - Do you really want to delete document ""? + Apakah Anda yakin ingin menghapus dokumen ""? The files for this document will be deleted permanently. This operation cannot be undone. @@ -3060,7 +3060,7 @@ src/app/components/document-detail/document-detail.component.ts 573 - The files for this document will be deleted permanently. This operation cannot be undone. + File untuk dokumen akan dihapus secara permanen. Operasi ini tidak dapat diurungkan. Delete document @@ -3076,7 +3076,7 @@ src/app/components/document-detail/document-detail.component.ts 595,597 - Error deleting document: + Kesalahan saat menghapus dokumen: Redo OCR confirm @@ -3172,7 +3172,7 @@ src/app/components/document-detail/document-detail.component.ts 641,643 - Error executing operation: + Kesalahan menjalankan operasi: Select: @@ -4474,7 +4474,7 @@ src/app/components/manage/settings/settings.component.html 72 - Items per page + Barang per halaman Document editor diff --git a/src-ui/src/locale/messages.pl_PL.xlf b/src-ui/src/locale/messages.pl_PL.xlf index b7d5d313f..5ca06a9b2 100644 --- a/src-ui/src/locale/messages.pl_PL.xlf +++ b/src-ui/src/locale/messages.pl_PL.xlf @@ -1825,7 +1825,7 @@ src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts 90 - Use mail address + Użyj adresu e-mail Use name (or mail address if not available) diff --git a/src-ui/src/locale/messages.pt_BR.xlf b/src-ui/src/locale/messages.pt_BR.xlf index c580b90a7..fd3316800 100644 --- a/src-ui/src/locale/messages.pt_BR.xlf +++ b/src-ui/src/locale/messages.pt_BR.xlf @@ -789,7 +789,7 @@ src/app/components/app-frame/app-frame.component.html 224,226 - Como é que isso funciona? + Como isto funciona? Update available diff --git a/src-ui/src/locale/messages.sr_CS.xlf b/src-ui/src/locale/messages.sr_CS.xlf index e6df1b52d..bdee8da95 100644 --- a/src-ui/src/locale/messages.sr_CS.xlf +++ b/src-ui/src/locale/messages.sr_CS.xlf @@ -5719,7 +5719,7 @@ src/app/services/settings.service.ts 213 - Finnish + Finski French diff --git a/src/documents/index.py b/src/documents/index.py index 973c99f4d..6aef2c047 100644 --- a/src/documents/index.py +++ b/src/documents/index.py @@ -225,15 +225,19 @@ class DelayedQuery: user_criterias = [query.Term("has_owner", False)] if "user" in self.query_params: - user_criterias.append(query.Term("owner_id", self.query_params["user"])) - user_criterias.append( - query.Term("viewer_id", str(self.query_params["user"])), - ) + if self.query_params["is_superuser"]: # superusers see all docs + user_criterias = [] + else: + user_criterias.append(query.Term("owner_id", self.query_params["user"])) + user_criterias.append( + query.Term("viewer_id", str(self.query_params["user"])), + ) if len(criterias) > 0: - criterias.append(query.Or(user_criterias)) + if len(user_criterias) > 0: + criterias.append(query.Or(user_criterias)) return query.And(criterias) else: - return query.Or(user_criterias) + return query.Or(user_criterias) if len(user_criterias) > 0 else None def _get_query_sortedby(self): if "ordering" not in self.query_params: diff --git a/src/documents/management/commands/document_thumbnails.py b/src/documents/management/commands/document_thumbnails.py index 0f35dba42..982634c5e 100644 --- a/src/documents/management/commands/document_thumbnails.py +++ b/src/documents/management/commands/document_thumbnails.py @@ -10,8 +10,8 @@ from documents.models import Document from documents.parsers import get_parser_class_for_mime_type -def _process_document(doc_in): - document: Document = Document.objects.get(id=doc_in) +def _process_document(doc_id): + document: Document = Document.objects.get(id=doc_id) parser_class = get_parser_class_for_mime_type(document.mime_type) if parser_class: diff --git a/src/documents/signals/handlers.py b/src/documents/signals/handlers.py index b41712a6f..40765443b 100644 --- a/src/documents/signals/handlers.py +++ b/src/documents/signals/handlers.py @@ -429,12 +429,12 @@ def update_filename_and_move_files(sender, instance: Document, **kwargs): if move_original: validate_move(instance, old_source_path, instance.source_path) create_source_path_directory(instance.source_path) - os.rename(old_source_path, instance.source_path) + shutil.move(old_source_path, instance.source_path) if move_archive: validate_move(instance, old_archive_path, instance.archive_path) create_source_path_directory(instance.archive_path) - os.rename(old_archive_path, instance.archive_path) + shutil.move(old_archive_path, instance.archive_path) # Don't save() here to prevent infinite recursion. Document.objects.filter(pk=instance.pk).update( @@ -453,11 +453,11 @@ def update_filename_and_move_files(sender, instance: Document, **kwargs): try: if move_original and os.path.isfile(instance.source_path): logger.info("Restoring previous original path") - os.rename(instance.source_path, old_source_path) + shutil.move(instance.source_path, old_source_path) if move_archive and os.path.isfile(instance.archive_path): logger.info("Restoring previous archive path") - os.rename(instance.archive_path, old_archive_path) + shutil.move(instance.archive_path, old_archive_path) except Exception: # This is fine, since: diff --git a/src/documents/tests/test_api.py b/src/documents/tests/test_api.py index d6158cd7d..b9989ee86 100644 --- a/src/documents/tests/test_api.py +++ b/src/documents/tests/test_api.py @@ -27,6 +27,7 @@ from django.contrib.auth.models import Permission from django.contrib.auth.models import User from django.test import override_settings from django.utils import timezone +from guardian.shortcuts import assign_perm from rest_framework import status from rest_framework.test import APITestCase from whoosh.writing import AsyncWriter @@ -253,8 +254,6 @@ class TestDocumentApi(DirectoriesMixin, DocumentConsumeDelayMixin, APITestCase): response = self.client.get(f"/api/documents/{doc.pk}/thumb/") self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) - from guardian.shortcuts import assign_perm - assign_perm("view_document", user2, doc) response = self.client.get(f"/api/documents/{doc.pk}/download/") @@ -1064,6 +1063,92 @@ class TestDocumentApi(DirectoriesMixin, DocumentConsumeDelayMixin, APITestCase): ), ) + def test_search_filtering_respect_owner(self): + """ + GIVEN: + - Documents with owners set & without + WHEN: + - API reuqest for advanced query (search) is made by non-superuser + - API reuqest for advanced query (search) is made by superuser + THEN: + - Only owned docs are returned for regular users + - All docs are returned for superuser + """ + superuser = User.objects.create_superuser("superuser") + u1 = User.objects.create_user("user1") + u2 = User.objects.create_user("user2") + u1.user_permissions.add(*Permission.objects.filter(codename="view_document")) + u2.user_permissions.add(*Permission.objects.filter(codename="view_document")) + + Document.objects.create(checksum="1", content="test 1", owner=u1) + Document.objects.create(checksum="2", content="test 2", owner=u2) + Document.objects.create(checksum="3", content="test 3", owner=u2) + Document.objects.create(checksum="4", content="test 4") + + with AsyncWriter(index.open_index()) as writer: + for doc in Document.objects.all(): + index.update_document(writer, doc) + + self.client.force_authenticate(user=u1) + r = self.client.get("/api/documents/?query=test") + self.assertEqual(r.data["count"], 2) + r = self.client.get("/api/documents/?query=test&document_type__id__none=1") + self.assertEqual(r.data["count"], 2) + + self.client.force_authenticate(user=u2) + r = self.client.get("/api/documents/?query=test") + self.assertEqual(r.data["count"], 3) + r = self.client.get("/api/documents/?query=test&document_type__id__none=1") + self.assertEqual(r.data["count"], 3) + + self.client.force_authenticate(user=superuser) + r = self.client.get("/api/documents/?query=test") + self.assertEqual(r.data["count"], 4) + r = self.client.get("/api/documents/?query=test&document_type__id__none=1") + self.assertEqual(r.data["count"], 4) + + def test_search_filtering_with_object_perms(self): + """ + GIVEN: + - Documents with granted view permissions to others + WHEN: + - API reuqest for advanced query (search) is made by user + THEN: + - Only docs with granted view permissions are returned + """ + u1 = User.objects.create_user("user1") + u2 = User.objects.create_user("user2") + u1.user_permissions.add(*Permission.objects.filter(codename="view_document")) + u2.user_permissions.add(*Permission.objects.filter(codename="view_document")) + + Document.objects.create(checksum="1", content="test 1", owner=u1) + d2 = Document.objects.create(checksum="2", content="test 2", owner=u2) + d3 = Document.objects.create(checksum="3", content="test 3", owner=u2) + Document.objects.create(checksum="4", content="test 4") + + with AsyncWriter(index.open_index()) as writer: + for doc in Document.objects.all(): + index.update_document(writer, doc) + + self.client.force_authenticate(user=u1) + r = self.client.get("/api/documents/?query=test") + self.assertEqual(r.data["count"], 2) + r = self.client.get("/api/documents/?query=test&document_type__id__none=1") + self.assertEqual(r.data["count"], 2) + + assign_perm("view_document", u1, d2) + assign_perm("view_document", u1, d3) + + with AsyncWriter(index.open_index()) as writer: + for doc in [d2, d3]: + index.update_document(writer, doc) + + self.client.force_authenticate(user=u1) + r = self.client.get("/api/documents/?query=test") + self.assertEqual(r.data["count"], 4) + r = self.client.get("/api/documents/?query=test&document_type__id__none=1") + self.assertEqual(r.data["count"], 4) + def test_search_sorting(self): c1 = Correspondent.objects.create(name="corres Ax") c2 = Correspondent.objects.create(name="corres Cx") diff --git a/src/documents/tests/test_file_handling.py b/src/documents/tests/test_file_handling.py index e4d4d0673..b021f8aaf 100644 --- a/src/documents/tests/test_file_handling.py +++ b/src/documents/tests/test_file_handling.py @@ -697,7 +697,7 @@ class TestFileHandlingWithArchive(DirectoriesMixin, FileSystemAssertsMixin, Test self.assertIsFile(doc.archive_path) @override_settings(FILENAME_FORMAT="{correspondent}/{title}") - @mock.patch("documents.signals.handlers.os.rename") + @mock.patch("documents.signals.handlers.shutil.move") def test_move_archive_error(self, m): def fake_rename(src, dst): if "archive" in str(src): @@ -748,7 +748,7 @@ class TestFileHandlingWithArchive(DirectoriesMixin, FileSystemAssertsMixin, Test self.assertIsFile(doc.archive_path) @override_settings(FILENAME_FORMAT="{correspondent}/{title}") - @mock.patch("documents.signals.handlers.os.rename") + @mock.patch("documents.signals.handlers.shutil.move") def test_move_file_error(self, m): def fake_rename(src, dst): if "original" in str(src): diff --git a/src/documents/tests/test_management_thumbnails.py b/src/documents/tests/test_management_thumbnails.py index 6e4e18ea3..1b9d9f664 100644 --- a/src/documents/tests/test_management_thumbnails.py +++ b/src/documents/tests/test_management_thumbnails.py @@ -47,12 +47,16 @@ class TestMakeThumbnails(DirectoriesMixin, FileSystemAssertsMixin, TestCase): self.assertIsFile(self.d1.thumbnail_path) @mock.patch("documents.management.commands.document_thumbnails.shutil.move") - def test_process_document_invalid_mime_type(self, m): + def test_process_document_invalid_mime_type(self, m: mock.Mock): self.d1.mime_type = "asdasdasd" self.d1.save() + # .save() triggers filename handling + m.reset_mock() + _process_document(self.d1.id) + # Not called during processing of document m.assert_not_called() def test_command(self): diff --git a/src/documents/views.py b/src/documents/views.py index 234c4dda1..0b450c3b3 100644 --- a/src/documents/views.py +++ b/src/documents/views.py @@ -604,6 +604,9 @@ class UnifiedSearchViewSet(DocumentViewSet): # pass user to query for perms self.request.query_params._mutable = True self.request.query_params["user"] = self.request.user.id + self.request.query_params[ + "is_superuser" + ] = self.request.user.is_superuser self.request.query_params._mutable = False if "query" in self.request.query_params: diff --git a/src/locale/ar_AR/LC_MESSAGES/django.po b/src/locale/ar_AR/LC_MESSAGES/django.po index c9350a857..e3ba97f57 100644 --- a/src/locale/ar_AR/LC_MESSAGES/django.po +++ b/src/locale/ar_AR/LC_MESSAGES/django.po @@ -3,7 +3,7 @@ msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-03-03 19:15+0000\n" -"PO-Revision-Date: 2023-03-07 19:40\n" +"PO-Revision-Date: 2023-05-01 13:00\n" "Last-Translator: \n" "Language-Team: Arabic\n" "Language: ar_SA\n" @@ -420,7 +420,7 @@ msgstr "اسم ملف المهمة" #: documents/models.py:577 msgid "Name of the file which the Task was run for" -msgstr "اسم الملف الذي وكل بالمهمة" +msgstr "اسم المِلَفّ الذي وكل بالمهمة" #: documents/models.py:583 msgid "Task Name" @@ -670,7 +670,7 @@ msgstr "إجراءات" #: paperless_mail/admin.py:69 msgid "The action applied to the mail. This action is only performed when the mail body or attachments were consumed from the mail." -msgstr "الإجراء المطبق على البريد. يتم تنفيذ هذا الإجراء فقط عندما يتم إستهلاك البريد أو المرفقات من البريد." +msgstr "الإجراء المطبق على البريد. يتم تنفيذ هذا الإجراء فقط عندما يتم أستهلاك البريد أو المرفقات من البريد." #: paperless_mail/admin.py:77 msgid "Metadata" @@ -834,11 +834,11 @@ msgstr "تصفية الجسم" #: paperless_mail/models.py:130 msgid "filter attachment filename" -msgstr "تصفية اسم الملف المرفق" +msgstr "تصفية اسم المِلَفّ المرفق" #: paperless_mail/models.py:135 msgid "Only consume documents which entirely match this filename if specified. Wildcards such as *.pdf or *invoice* are allowed. Case insensitive." -msgstr "فقط المستندات التي تتطابق تماما مع اسم هذا الملف إذا تم تحديدها. المحارف البديلة مثل *.pdf أو *الفواتير* مسموح بها. لأنها غير حساسة." +msgstr "فقط المستندات التي تتطابق تماما مع اسم هذا المِلَفّ إذا تم تحديدها. المحارف البديلة مثل *.pdf أو *الفواتير* مسموح بها. لأنها غير حساسة." #: paperless_mail/models.py:142 msgid "maximum age" diff --git a/src/locale/id_ID/LC_MESSAGES/django.po b/src/locale/id_ID/LC_MESSAGES/django.po index d29cb50c5..3f41ba654 100644 --- a/src/locale/id_ID/LC_MESSAGES/django.po +++ b/src/locale/id_ID/LC_MESSAGES/django.po @@ -3,7 +3,7 @@ msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-03-03 19:15+0000\n" -"PO-Revision-Date: 2023-04-20 13:20\n" +"PO-Revision-Date: 2023-04-28 09:40\n" "Last-Translator: \n" "Language-Team: Indonesian\n" "Language: id_ID\n" @@ -212,7 +212,7 @@ msgstr "dokumen" #: documents/models.py:269 msgid "documents" -msgstr "" +msgstr "dokumen" #: documents/models.py:359 msgid "debug" @@ -224,7 +224,7 @@ msgstr "informasi" #: documents/models.py:361 msgid "warning" -msgstr "" +msgstr "peringatan" #: documents/models.py:362 paperless_mail/models.py:276 msgid "error" @@ -232,7 +232,7 @@ msgstr "kesalahan" #: documents/models.py:363 msgid "critical" -msgstr "" +msgstr "kritis" #: documents/models.py:366 msgid "group" @@ -244,7 +244,7 @@ msgstr "pesan" #: documents/models.py:371 msgid "level" -msgstr "" +msgstr "tingkat" #: documents/models.py:380 msgid "log" @@ -276,15 +276,15 @@ msgstr "" #: documents/models.py:409 msgid "sort reverse" -msgstr "" +msgstr "urutkan terbalik" #: documents/models.py:414 msgid "title contains" -msgstr "" +msgstr "judul memiliki" #: documents/models.py:415 msgid "content contains" -msgstr "" +msgstr "konten memiliki" #: documents/models.py:416 msgid "ASN is" @@ -300,7 +300,7 @@ msgstr "" #: documents/models.py:419 msgid "is in inbox" -msgstr "" +msgstr "di dalam kotak masuk" #: documents/models.py:420 msgid "has tag" @@ -380,11 +380,11 @@ msgstr "" #: documents/models.py:439 msgid "storage path is" -msgstr "" +msgstr "lokasi penyimpanan" #: documents/models.py:449 msgid "rule type" -msgstr "" +msgstr "jenis peraturan" #: documents/models.py:451 msgid "value" @@ -392,15 +392,15 @@ msgstr "nilai" #: documents/models.py:454 msgid "filter rule" -msgstr "" +msgstr "saring aturan" #: documents/models.py:455 msgid "filter rules" -msgstr "" +msgstr "saring aturan" #: documents/models.py:563 msgid "Task ID" -msgstr "" +msgstr "ID Tugas" #: documents/models.py:564 msgid "Celery ID for the Task that was run" @@ -432,11 +432,11 @@ msgstr "" #: documents/models.py:591 msgid "Task State" -msgstr "" +msgstr "Status Tugas" #: documents/models.py:592 msgid "Current state of the task being run" -msgstr "" +msgstr "Status tugas sekarang yang sedang dijalankan" #: documents/models.py:597 msgid "Created DateTime" @@ -464,53 +464,53 @@ msgstr "" #: documents/models.py:615 msgid "Result Data" -msgstr "" +msgstr "Data Hasil" #: documents/models.py:617 msgid "The data returned by the task" -msgstr "" +msgstr "Data yang dikembalikan dari tugas" #: documents/models.py:626 msgid "Comment for the document" -msgstr "" +msgstr "Komentar pada dokumen" #: documents/models.py:650 msgid "user" -msgstr "" +msgstr "pengguna" #: documents/models.py:655 msgid "comment" -msgstr "" +msgstr "komentar" #: documents/models.py:656 msgid "comments" -msgstr "" +msgstr "komentar" #: documents/serialisers.py:80 #, python-format msgid "Invalid regular expression: %(error)s" -msgstr "" +msgstr "Ekspresi reguler tidak valid: %(error)s" #: documents/serialisers.py:320 msgid "Invalid color." -msgstr "" +msgstr "Warna tidak valid." #: documents/serialisers.py:700 #, python-format msgid "File type %(type)s not supported" -msgstr "" +msgstr "Jenis file %(type)s tidak didukung" #: documents/serialisers.py:794 msgid "Invalid variable detected." -msgstr "" +msgstr "Variabel ilegal terdeteksi." #: documents/templates/index.html:78 msgid "Paperless-ngx is loading..." -msgstr "" +msgstr "Paperless-ngx sedang memuat..." #: documents/templates/index.html:79 msgid "Still here?! Hmm, something might be wrong." -msgstr "" +msgstr "Masih disini?! Hmm, sepertinya ada yang salah." #: documents/templates/index.html:79 msgid "Here's a link to the docs." @@ -526,7 +526,7 @@ msgstr "" #: documents/templates/registration/logged_out.html:60 msgid "Sign in again" -msgstr "" +msgstr "Masuk lagi" #: documents/templates/registration/login.html:15 msgid "Paperless-ngx sign in" @@ -534,23 +534,23 @@ msgstr "" #: documents/templates/registration/login.html:61 msgid "Please sign in." -msgstr "" +msgstr "Mohon masuk." #: documents/templates/registration/login.html:64 msgid "Your username and password didn't match. Please try again." -msgstr "" +msgstr "Nama pengguna dan sandi tidak cocok. Silahkan coba kembali." #: documents/templates/registration/login.html:67 msgid "Username" -msgstr "" +msgstr "Nama pengguna" #: documents/templates/registration/login.html:68 msgid "Password" -msgstr "" +msgstr "Kata sandi" #: documents/templates/registration/login.html:73 msgid "Sign in" -msgstr "" +msgstr "Masuk" #: paperless/apps.py:9 msgid "Paperless" @@ -558,15 +558,15 @@ msgstr "" #: paperless/settings.py:521 msgid "English (US)" -msgstr "" +msgstr "Inggris (AS)" #: paperless/settings.py:522 msgid "Arabic" -msgstr "" +msgstr "Arab" #: paperless/settings.py:523 msgid "Belarusian" -msgstr "" +msgstr "Belarusia" #: paperless/settings.py:524 msgid "Czech" @@ -582,11 +582,11 @@ msgstr "" #: paperless/settings.py:527 msgid "English (GB)" -msgstr "" +msgstr "Inggris (GB)" #: paperless/settings.py:528 msgid "Spanish" -msgstr "" +msgstr "Spanyol" #: paperless/settings.py:529 msgid "French" @@ -602,71 +602,71 @@ msgstr "" #: paperless/settings.py:532 msgid "Dutch" -msgstr "" +msgstr "Belanda" #: paperless/settings.py:533 msgid "Polish" -msgstr "" +msgstr "Polandia" #: paperless/settings.py:534 msgid "Portuguese (Brazil)" -msgstr "" +msgstr "Portugis (Brasil)" #: paperless/settings.py:535 msgid "Portuguese" -msgstr "" +msgstr "Portugis" #: paperless/settings.py:536 msgid "Romanian" -msgstr "" +msgstr "Rumania" #: paperless/settings.py:537 msgid "Russian" -msgstr "" +msgstr "Rusia" #: paperless/settings.py:538 msgid "Slovenian" -msgstr "" +msgstr "Slovenia" #: paperless/settings.py:539 msgid "Serbian" -msgstr "" +msgstr "Serbia" #: paperless/settings.py:540 msgid "Swedish" -msgstr "" +msgstr "Swedia" #: paperless/settings.py:541 msgid "Turkish" -msgstr "" +msgstr "Turki" #: paperless/settings.py:542 msgid "Chinese Simplified" -msgstr "" +msgstr "Mandarin Sederhana" #: paperless/urls.py:169 msgid "Paperless-ngx administration" -msgstr "" +msgstr "Administrasi Paperless-ngx" #: paperless_mail/admin.py:30 msgid "Authentication" -msgstr "" +msgstr "Autentikasi" #: paperless_mail/admin.py:31 msgid "Advanced settings" -msgstr "" +msgstr "Pengaturan lanjutan" #: paperless_mail/admin.py:48 msgid "Filter" -msgstr "" +msgstr "Saring" #: paperless_mail/admin.py:51 msgid "Paperless will only process mails that match ALL of the filters given below." -msgstr "" +msgstr "Paperless hanya akan memproses SEMUA surat yang cocok dengan filter yang diberikan." #: paperless_mail/admin.py:66 msgid "Actions" -msgstr "" +msgstr "Aksi" #: paperless_mail/admin.py:69 msgid "The action applied to the mail. This action is only performed when the mail body or attachments were consumed from the mail." @@ -682,35 +682,35 @@ msgstr "" #: paperless_mail/apps.py:10 msgid "Paperless mail" -msgstr "" +msgstr "Surat Paperless" #: paperless_mail/models.py:9 msgid "mail account" -msgstr "" +msgstr "akun surat" #: paperless_mail/models.py:10 msgid "mail accounts" -msgstr "" +msgstr "akun surat" #: paperless_mail/models.py:13 msgid "No encryption" -msgstr "" +msgstr "Tanpa enkripsi" #: paperless_mail/models.py:14 msgid "Use SSL" -msgstr "" +msgstr "Gunakan SSL" #: paperless_mail/models.py:15 msgid "Use STARTTLS" -msgstr "" +msgstr "Gunakan STARTTLS" #: paperless_mail/models.py:19 msgid "IMAP server" -msgstr "" +msgstr "Server IMAP" #: paperless_mail/models.py:22 msgid "IMAP port" -msgstr "" +msgstr "Port IMAP" #: paperless_mail/models.py:26 msgid "This is usually 143 for unencrypted and STARTTLS connections, and 993 for SSL connections." @@ -722,11 +722,11 @@ msgstr "" #: paperless_mail/models.py:37 msgid "username" -msgstr "" +msgstr "nama pengguna" #: paperless_mail/models.py:39 msgid "password" -msgstr "" +msgstr "kata sandi" #: paperless_mail/models.py:42 msgid "character set" @@ -738,11 +738,11 @@ msgstr "" #: paperless_mail/models.py:57 msgid "mail rule" -msgstr "" +msgstr "peraturan surat" #: paperless_mail/models.py:58 msgid "mail rules" -msgstr "" +msgstr "peraturan surat" #: paperless_mail/models.py:61 paperless_mail/models.py:69 msgid "Only process attachments." @@ -762,7 +762,7 @@ msgstr "" #: paperless_mail/models.py:73 msgid "Delete" -msgstr "" +msgstr "Hapus" #: paperless_mail/models.py:74 msgid "Move to specified folder" @@ -794,11 +794,11 @@ msgstr "" #: paperless_mail/models.py:85 msgid "Use mail address" -msgstr "" +msgstr "Gunakan alamat surat" #: paperless_mail/models.py:86 msgid "Use name (or mail address if not available)" -msgstr "" +msgstr "Gunakan nama (atau alamat surat jika tidak tersedia)" #: paperless_mail/models.py:87 msgid "Use correspondent selected below" @@ -806,15 +806,15 @@ msgstr "" #: paperless_mail/models.py:91 msgid "order" -msgstr "" +msgstr "urut" #: paperless_mail/models.py:97 msgid "account" -msgstr "" +msgstr "akun" #: paperless_mail/models.py:101 paperless_mail/models.py:231 msgid "folder" -msgstr "" +msgstr "direktori" #: paperless_mail/models.py:105 msgid "Subfolders must be separated by a delimiter, often a dot ('.') or slash ('/'), but it varies by mail server." @@ -822,19 +822,19 @@ msgstr "" #: paperless_mail/models.py:111 msgid "filter from" -msgstr "" +msgstr "saring dari" #: paperless_mail/models.py:117 msgid "filter subject" -msgstr "" +msgstr "saring subjek" #: paperless_mail/models.py:123 msgid "filter body" -msgstr "" +msgstr "saring badan" #: paperless_mail/models.py:130 msgid "filter attachment filename" -msgstr "" +msgstr "saring nama file lampiran" #: paperless_mail/models.py:135 msgid "Only consume documents which entirely match this filename if specified. Wildcards such as *.pdf or *invoice* are allowed. Case insensitive." @@ -842,7 +842,7 @@ msgstr "" #: paperless_mail/models.py:142 msgid "maximum age" -msgstr "" +msgstr "umur maksimal" #: paperless_mail/models.py:144 msgid "Specified in days." @@ -850,7 +850,7 @@ msgstr "" #: paperless_mail/models.py:148 msgid "attachment type" -msgstr "" +msgstr "jenis lampiran" #: paperless_mail/models.py:152 msgid "Inline attachments include embedded images, so it's best to combine this option with a filename filter." @@ -862,11 +862,11 @@ msgstr "" #: paperless_mail/models.py:164 msgid "action" -msgstr "" +msgstr "aksi" #: paperless_mail/models.py:170 msgid "action parameter" -msgstr "" +msgstr "parameter aksi" #: paperless_mail/models.py:175 msgid "Additional parameter for the action selected above, i.e., the target folder of the move to folder action. Subfolders must be separated by dots." @@ -898,17 +898,17 @@ msgstr "" #: paperless_mail/models.py:247 msgid "subject" -msgstr "" +msgstr "subjek" #: paperless_mail/models.py:255 msgid "received" -msgstr "" +msgstr "diterima" #: paperless_mail/models.py:262 msgid "processed" -msgstr "" +msgstr "diproses" #: paperless_mail/models.py:268 msgid "status" -msgstr "" +msgstr "status" diff --git a/src/locale/pt_BR/LC_MESSAGES/django.po b/src/locale/pt_BR/LC_MESSAGES/django.po index bf025c510..267d1c5d3 100644 --- a/src/locale/pt_BR/LC_MESSAGES/django.po +++ b/src/locale/pt_BR/LC_MESSAGES/django.po @@ -3,7 +3,7 @@ msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-03-03 19:15+0000\n" -"PO-Revision-Date: 2023-03-04 19:07\n" +"PO-Revision-Date: 2023-05-02 19:20\n" "Last-Translator: \n" "Language-Team: Portuguese, Brazilian\n" "Language: pt_BR\n" @@ -368,15 +368,15 @@ msgstr "mais como este" #: documents/models.py:436 msgid "has tags in" -msgstr "contém etiqueta em" +msgstr "contém etiquetas em" #: documents/models.py:437 msgid "ASN greater than" -msgstr "" +msgstr "NSA maior que" #: documents/models.py:438 msgid "ASN less than" -msgstr "" +msgstr "NSA menor que" #: documents/models.py:439 msgid "storage path is" @@ -400,55 +400,55 @@ msgstr "regras de filtragem" #: documents/models.py:563 msgid "Task ID" -msgstr "" +msgstr "ID da tarefa" #: documents/models.py:564 msgid "Celery ID for the Task that was run" -msgstr "" +msgstr "ID da Celery para a tarefa que foi executada" #: documents/models.py:569 msgid "Acknowledged" -msgstr "" +msgstr "Confirmado" #: documents/models.py:570 msgid "If the task is acknowledged via the frontend or API" -msgstr "" +msgstr "Se a tarefa é reconhecida através do frontend ou API" #: documents/models.py:576 msgid "Task Filename" -msgstr "" +msgstr "Nome do arquivo da tarefa" #: documents/models.py:577 msgid "Name of the file which the Task was run for" -msgstr "" +msgstr "Nome do arquivo para o qual a tarefa foi executada" #: documents/models.py:583 msgid "Task Name" -msgstr "" +msgstr "Nome da tarefa" #: documents/models.py:584 msgid "Name of the Task which was run" -msgstr "" +msgstr "Nome da tarefa executada" #: documents/models.py:591 msgid "Task State" -msgstr "" +msgstr "Estado da tarefa" #: documents/models.py:592 msgid "Current state of the task being run" -msgstr "" +msgstr "Estado atual da tarefa sendo executada" #: documents/models.py:597 msgid "Created DateTime" -msgstr "" +msgstr "Data/Hora de criação" #: documents/models.py:598 msgid "Datetime field when the task result was created in UTC" -msgstr "" +msgstr "Campo Data/Hora quando o resultado da tarefa foi criado, em UTC" #: documents/models.py:603 msgid "Started DateTime" -msgstr "" +msgstr "Data/Hora de início" #: documents/models.py:604 msgid "Datetime field when the task was started in UTC" @@ -472,7 +472,7 @@ msgstr "" #: documents/models.py:626 msgid "Comment for the document" -msgstr "" +msgstr "Comentário para o documento" #: documents/models.py:650 msgid "user" @@ -562,11 +562,11 @@ msgstr "Inglês (EUA)" #: paperless/settings.py:522 msgid "Arabic" -msgstr "" +msgstr "Árabe" #: paperless/settings.py:523 msgid "Belarusian" -msgstr "" +msgstr "Bielorrusso" #: paperless/settings.py:524 msgid "Czech" @@ -626,11 +626,11 @@ msgstr "Russo" #: paperless/settings.py:538 msgid "Slovenian" -msgstr "" +msgstr "Esloveno" #: paperless/settings.py:539 msgid "Serbian" -msgstr "" +msgstr "Sérvio" #: paperless/settings.py:540 msgid "Swedish" @@ -638,11 +638,11 @@ msgstr "Sueco" #: paperless/settings.py:541 msgid "Turkish" -msgstr "" +msgstr "Turco" #: paperless/settings.py:542 msgid "Chinese Simplified" -msgstr "" +msgstr "Chinês Simplificado" #: paperless/urls.py:169 msgid "Paperless-ngx administration" @@ -670,7 +670,7 @@ msgstr "Ações" #: paperless_mail/admin.py:69 msgid "The action applied to the mail. This action is only performed when the mail body or attachments were consumed from the mail." -msgstr "" +msgstr "A ação aplicada ao e-mail. Essa ação só é executada quando o corpo do e-mail ou anexos forem consumidos." #: paperless_mail/admin.py:77 msgid "Metadata" @@ -750,11 +750,11 @@ msgstr "Processar somente anexos." #: paperless_mail/models.py:62 msgid "Process full Mail (with embedded attachments in file) as .eml" -msgstr "" +msgstr "Processar e-mail completo (com anexos incorporados no arquivo) como .eml" #: paperless_mail/models.py:64 msgid "Process full Mail (with embedded attachments in file) as .eml + process attachments as separate documents" -msgstr "" +msgstr "Processar e-mail completo (com anexos incorporados no arquivo) como .eml + processar anexos como documentos separados" #: paperless_mail/models.py:70 msgid "Process all files, including 'inline' attachments." @@ -778,7 +778,7 @@ msgstr "Sinalizar o e-mail, não processar e-mails sinalizados" #: paperless_mail/models.py:77 msgid "Tag the mail with specified tag, don't process tagged mails" -msgstr "" +msgstr "Marcar o e-mail com a etiqueta especificada, não processar e-mails marcados" #: paperless_mail/models.py:80 msgid "Use subject as title" @@ -818,7 +818,7 @@ msgstr "pasta" #: paperless_mail/models.py:105 msgid "Subfolders must be separated by a delimiter, often a dot ('.') or slash ('/'), but it varies by mail server." -msgstr "" +msgstr "Subpastas devem ser separadas por um delimitador, muitas vezes um ponto ('.') ou uma barra ('/'), mas varia de acordo com o servidor de e-mail." #: paperless_mail/models.py:111 msgid "filter from" @@ -859,7 +859,7 @@ msgstr "Anexos inline incluem imagens inseridas, por isso é melhor combinar ess #: paperless_mail/models.py:158 msgid "consumption scope" -msgstr "" +msgstr "escopo do consumo" #: paperless_mail/models.py:164 msgid "action" diff --git a/src/paperless/settings.py b/src/paperless/settings.py index 0301fffad..122806516 100644 --- a/src/paperless/settings.py +++ b/src/paperless/settings.py @@ -422,11 +422,12 @@ if _paperless_url: _paperless_uri = urlparse(_paperless_url) CSRF_TRUSTED_ORIGINS.append(_paperless_url) CORS_ALLOWED_ORIGINS.append(_paperless_url) - if ["*"] != ALLOWED_HOSTS: + +if ["*"] != ALLOWED_HOSTS: + # always allow localhost. Necessary e.g. for healthcheck in docker. + ALLOWED_HOSTS.append("localhost") + if _paperless_url: ALLOWED_HOSTS.append(_paperless_uri.hostname) - else: - # always allow localhost. Necessary e.g. for healthcheck in docker. - ALLOWED_HOSTS = [_paperless_uri.hostname] + ["localhost"] # For use with trusted proxies TRUSTED_PROXIES = __get_list("PAPERLESS_TRUSTED_PROXIES") diff --git a/src/paperless_mail/mail.py b/src/paperless_mail/mail.py index a40f7e0d1..3851cf590 100644 --- a/src/paperless_mail/mail.py +++ b/src/paperless_mail/mail.py @@ -2,7 +2,6 @@ import datetime import itertools import logging import os -import re import tempfile import traceback from datetime import date @@ -145,7 +144,7 @@ class TagMailAction(BaseMailAction): A mail action that tags mails after processing. """ - def __init__(self, parameter): + def __init__(self, parameter: str, supports_gmail_labels: bool): # The custom tag should look like "apple:" if "apple:" in parameter.lower(): _, self.color = parameter.split(":") @@ -159,18 +158,22 @@ class TagMailAction(BaseMailAction): else: self.keyword = parameter self.color = None + self.supports_gmail_labels = supports_gmail_labels def get_criteria(self): # AppleMail: We only need to check if mails are \Flagged if self.color: return {"flagged": False} elif self.keyword: - return AND(NOT(gmail_label=self.keyword), no_keyword=self.keyword) + if self.supports_gmail_labels: + return AND(NOT(gmail_label=self.keyword), no_keyword=self.keyword) + else: + return NOT(no_keyword=self.keyword) else: # pragma: nocover raise ValueError("This should never happen.") def post_consume(self, M: MailBox, message_uid: str, parameter: str): - if re.search(r"gmail\.com$|googlemail\.com$", M._host): + if self.supports_gmail_labels: M.client.uid("STORE", message_uid, "+X-GM-LABELS", self.keyword) # AppleMail @@ -248,15 +251,18 @@ def apply_mail_action( message_date = make_aware(message_date) try: - action = get_rule_action(rule) - with get_mailbox( server=account.imap_server, port=account.imap_port, security=account.imap_security, ) as M: + # Need to know the support for the possible tagging + supports_gmail_labels = "X-GM-EXT-1" in M.client.capabilities + mailbox_login(M, account) M.folder.set(rule.folder) + + action = get_rule_action(rule, supports_gmail_labels) action.post_consume(M, message_uid, rule.action_parameter) ProcessedMail.objects.create( @@ -337,7 +343,7 @@ def queue_consumption_tasks( ).delay() -def get_rule_action(rule) -> BaseMailAction: +def get_rule_action(rule: MailRule, supports_gmail_labels: bool) -> BaseMailAction: """ Returns a BaseMailAction instance for the given rule. """ @@ -351,12 +357,12 @@ def get_rule_action(rule) -> BaseMailAction: elif rule.action == MailRule.MailAction.MARK_READ: return MarkReadMailAction() elif rule.action == MailRule.MailAction.TAG: - return TagMailAction(rule.action_parameter) + return TagMailAction(rule.action_parameter, supports_gmail_labels) else: raise NotImplementedError("Unknown action.") # pragma: nocover -def make_criterias(rule): +def make_criterias(rule: MailRule, supports_gmail_labels: bool): """ Returns criteria to be applied to MailBox.fetch for the given rule. """ @@ -374,7 +380,7 @@ def make_criterias(rule): if rule.filter_body: criterias["body"] = rule.filter_body - rule_query = get_rule_action(rule).get_criteria() + rule_query = get_rule_action(rule, supports_gmail_labels).get_criteria() if isinstance(rule_query, dict): if len(rule_query) or len(criterias): return AND(**rule_query, **criterias) @@ -490,6 +496,7 @@ class MailAccountHandler(LoggingMixin): total_processed_files += self._handle_mail_rule( M, rule, + supports_gmail_labels, ) except Exception as e: self.log( @@ -512,6 +519,7 @@ class MailAccountHandler(LoggingMixin): self, M: MailBox, rule: MailRule, + supports_gmail_labels: bool, ): self.log("debug", f"Rule {rule}: Selecting folder {rule.folder}") @@ -537,7 +545,7 @@ class MailAccountHandler(LoggingMixin): f"does not exist in account {rule.account}", ) from err - criterias = make_criterias(rule) + criterias = make_criterias(rule, supports_gmail_labels) self.log( "debug", diff --git a/src/paperless_mail/tests/test_mail.py b/src/paperless_mail/tests/test_mail.py index 0a3cb5b2c..0ca32663a 100644 --- a/src/paperless_mail/tests/test_mail.py +++ b/src/paperless_mail/tests/test_mail.py @@ -737,6 +737,7 @@ class TestMail( MailError, TagMailAction, "apple:black", + False, ) def test_handle_mail_account_tag_applemail(self):