From f53accafcd2c4115872d528435c66d526ceab2a2 Mon Sep 17 00:00:00 2001 From: Yassine R Date: Tue, 5 Sep 2023 23:59:19 +0200 Subject: [PATCH] =?UTF-8?q?fix(docs):=20suppression=20de=20l'ancien=20syst?= =?UTF-8?q?=C3=A8me=20de=20gestion=20de=20fichiers?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dev/templates/backend.sealed-secret.yaml | 4 - .../templates/backend.sealed-secret.yaml | 4 - .../prod/templates/backend.sealed-secret.yaml | 3 - .../db/dumps/domifa_test.postgres.custom.gz | Bin 88278 -> 88411 bytes ...domifa_test.postgres.restore-data-only.sql | 6 +- ...st.postgres.truncate-restore-data-only.sql | 6 +- .../backend/.env.preset/local-dev.preset.env | 4 - packages/backend/package.json | 2 - ...222559-delete-corrupted-files-migration.ts | 19 ++ .../src/config/domifaConfig.service.spec.ts | 9 - .../src/config/domifaConfig.service.ts | 15 +- .../src/config/model/DomifaConfig.type.ts | 7 +- .../src/config/model/DomifaEnv.type.ts | 4 - packages/backend/src/run-migrate-files.ts | 21 -- .../controllers/usager-docs.controller.ts | 143 ++++--------- packages/backend/src/usagers/utils/index.ts | 2 - .../src/usagers/utils/migrate-files-utils.ts | 198 ------------------ .../src/util/file-manager/FileManager.ts | 18 +- ...profil-historique-courriers.component.html | 2 +- 19 files changed, 68 insertions(+), 399 deletions(-) create mode 100644 packages/backend/src/_migrations/1693919222559-delete-corrupted-files-migration.ts delete mode 100644 packages/backend/src/run-migrate-files.ts delete mode 100644 packages/backend/src/usagers/utils/index.ts delete mode 100644 packages/backend/src/usagers/utils/migrate-files-utils.ts diff --git a/.kontinuous/env/dev/templates/backend.sealed-secret.yaml b/.kontinuous/env/dev/templates/backend.sealed-secret.yaml index e936d9339d..254c50869f 100644 --- a/.kontinuous/env/dev/templates/backend.sealed-secret.yaml +++ b/.kontinuous/env/dev/templates/backend.sealed-secret.yaml @@ -8,10 +8,6 @@ spec: encryptedData: DOMIFA_SECURITY_JWT_SECRET: >- AgAS9+czzoJ8Srab21D6kq0rnv3fejKN5/UeSVhvSSvnwmsBpuHBACbRZS9mGVpChZDQsf4mLJBDWNsQ5o5p8KIkp8fZ6MNr9W8xoIesmpt4oYTK65dEHFU3nvvcsKQ7zB1y/JgL7SQDWh2HArOYlcPE/3XGuhmZgbMQzSUITsEDKHf4bralo0jSoaMNJCxuZgdxAqRN6f8qtdiLZgbjs1JjX1PvDC6Uf+G79l+85HeX7sjQLjmjtT10xwW6LzCh1oTMc8SxRG2nA564Je6GYxmJNs/O1FNLlcjKxbdOsH6ZISk7n91UMibckYHzzWR+8UvVbi/Vr5pgPxxx5rjhsIpR5ywLeSjfzDM7fntMfXv+ZEVWstZcIxJwoupBsxiPVnkCHIhmRivK+bvDvosrsVILPEF1wsbBJUt5BUYetCA7xeD9BS8c7PP9H5duc3Psb2s+VXX4LzxEI8KwdZsBnfe+Lv2pD1mXYO/+Mhp/1zwJs7SUEZFUS68xoPsd8gvEO8oFTn+82Qesitdg/UHuaDs3QYZvk2Tcr6mduSsFRc514VHpg2xh7VPUD09LVETvqIQs2Fbk1TnjTm8tURnDx6DGFFXwZ8HgdwWl1irtVIRzwjXT2bqLIK26q3Pf+Xz5JWF2vbfZZT9BUpzYEE3j6sxg5XFmFlym32MrDkBSprIB/B0QbiDDVH77LxBSuczKh5moNJTi+mdBDpmqkpEcZBL8pF/tfOtupsswJhqwb1yQeWh45iifdljvngEzWihfS5k87mVbIEryzflwJUJxZQTATyFi4kYJs6A/4LgKzYaF/K8lYV36vyS5K6rgExBQ5yvgT2VAgaHNV89+a4xorGCbCVT+wLEYR4nT6bGaReiddU2Wspz9OQETHldHvQ0tQv1xxigpBKiYXeR67LnFYs4FWWAsKvqcQ/D7UIxfhxPzbEk7XfPhnG4vXk8= - DOMIFA_SECURITY_FILES_PRIVATE: >- - AgCX8fKNhEGDDjizFnXoiLXtMJ30HIc7svSc3H1i7WrVSM3GIGj0J3/lFdIK88QjP9vIG3AJSozbZ0Gp+JQVIvN9OmEZmM2gTVTc1Q0aq/51CYbphevlgacGdWJYSnmGWkdl+nfwqLEamX0zF12eLfW5wIBnm2RBzRT4wFU8aYX330MldF5qE/4MZOurQL48RTGXZ1GlX+1Dzsoa+bKPoJNuga4Cog1JspmKdf6nhob+HM4KvM8K/+gXh/PYZqG/wHoEa3kS8qOIQw0766u4nkCZ8Vu479pa24zQiUc4NAoqa2yT+aTRJKiNgPgiR1C7MiBWYK2SauO2J6FhqMyjbnvuhwZiDd7JGcA9rf9DAt9qpjPuCEe7crlrqFjRd1OfxuhOAp0GYd0bfihJtHXaJ+cHQ709zVjX2aU4wTItvH8UpC8OuqGHuGz7G+CSBuAYZANpFIMNZk7uq4CH2/E81GHt3JhKOXc9EMrUKyBKr+6nqOgJM5q9K7KW66lfup6hNnligDB+JAXNVFuWKK0QmGWInSxk9b7h3+0HSevtnHjIAH+mld8vr34+mLO6qLGZhjzrIzB+/1dOyQ7X1d7HiuG6cV60FPfKrTzEbwr+D+vay7DrOSJiS7dEX1YRAE6fH7lvP9VZZX8hur02mk/dG4D3rNFdu+DUp8k0N5ljnrKuNp4yTQMmk/xwQLC/Fu7Mi/Hjm3+y+ir8EvOwKnmjZwcUUt2hHpgauWwCxcy5UpiS5A== - DOMIFA_SECURITY_FILES_IV: >- - AgDTjOtxCkz8QFrP970VE2VZU3RnT2R4k4Tz+p88tVoFQ9Op/UkwK1QcSzd1E4Mlj6qaBErbyzlb6/Ij9DoIlmkbOl4nCycZzXu8mTdPY8ZJK8qotGiZuJhjy67DzTXp7ICC4l6Ox2jL3jr+YF3AeQypEn0qxWaNCl2tXoCjid4g5K/kct2qKkYZdnYgFDXlGqE3ULPTonc3QJ8Cy6kUEBuIumjc+xjbr6HEnWgAnaAK2HUIwQ3DRGzYSSSiNaiy0PmqHU0OJ4zF9i+BjYEYSReQEl5OSHDc+jpTph24m1AS8PcO+n4rag4fg0BiZ2vxRB4XgQcXQkNARSpYP42YJoouumkXXN8ltOQNkLxxOdT3wLJsOW20ZLDqK1R8gwmeXwEBQZ2KRSjMrTNjIVbzPLb3YTtgVI9kzWcZefjqpQXy6t/de2zP5C5Y7dElpSJ4C0d/yzCwQ7yGTa4tsFQGjgEiTeCSFpjT2h2osrz5bZFQRm2SkoRxhvY+daG8x/vIz9SxPzem2lSE5ORhVjsmg+iPHntR5x1/CZ2aZ5ElZBwFIkFSrhHBROjRyWkMeF+hDGQTgeKqpU87ZEfkrrE7GKF8fV5EoWoT1h4Dh71WisTxfffkXVW2JzdvQGRvc+xWh8b6VTCN42gUfZddcyC/Idf/pGiVT7wqHQXEjjHI3HZPf8PdAA8HsPm9Bg7gkjifeh6H37FYUmCkxqveKWnJZUhy DOMIFA_MAIL_SMTP_TIPIMAIL_HOST: >- AgAWtRKQjIGJzsEnpC025AtzBe/l7cHUnogzyg/BlZPTUFQhKKojvrg/ib++rf9jwVd68k89iPYq8DHMwgoA9c2N7UKfjDiidlMPghWDE1L4ZGNhY9qP4CPzqoBrDHPwhyb8oUUBS23mGsu9DKOx3WCxLsjGYP5FUZBgBn8Lw394OL+boRntDZRvBVb9U7tlm98OeJien46DFsT3zz1LZFh0pP1BeP6ZPNgeXTZz29GRPi5hq885KTAUkd4kL47DcM/wZtWnElcr2lKq0anqdnvTO4N/mvQHD98sPB64+m4G/PbY0DtSZfTi7qqFk9KaqERLIExaRBKs+EEpgVRs5htfq5Szqcp1LuWHVl5eqyA2Mcp7XJwQhD6j6zDmuaCLe+J1IhQldLdrjEX/r1aarDruKUqYK+T5AyrW6hPV5l58IESw5bDxfreKOxqK1sPXrpHADRo60fsbmaKDHfbRuLJqRa7wGSOn4rgHNxsA7/KKLoXFVAfmUH/0VwbxR0OjicLJnDDzc1nKVb1f6Y+R2jvlFgTnBsT+tKo5GJ3MhzW3Gyw/++RSfk/B1F78RhVwS2cPCPC9ehS2Ra88wezLRIWtCVKc2u1/Zq/eO4YHPmfSZUD547bIb003D2N2Ba2hMGgvX/f1wsAUpF3RiziZ/5LdKfQwXGdcWctrMGx2NXQOuecp9l/zMTEvkgelBVlZwjKHU1i9oDHlq9vknyJMkBDzdw== DOMIFA_MAIL_SMTP_TIPIMAIL_PORT: >- diff --git a/.kontinuous/env/preprod/templates/backend.sealed-secret.yaml b/.kontinuous/env/preprod/templates/backend.sealed-secret.yaml index f5f7927777..417fbc427e 100644 --- a/.kontinuous/env/preprod/templates/backend.sealed-secret.yaml +++ b/.kontinuous/env/preprod/templates/backend.sealed-secret.yaml @@ -9,10 +9,6 @@ spec: encryptedData: DOMIFA_SECURITY_JWT_SECRET: >- AgBU0tzOyTQxOJkVHwTP/PaB+6tRz8/IA74V+RarBeaT9nwDE7p6ZZfbrERIPaiLtDJ0w89DynXvlaN7Rgrt0YCCLfXAe1aSyq+RShFNH0vx6i8Lemu/b+eyijMTNfYc5y45NYUeeXf05Zzzcx+QqAP5ajqGT8gms0LKv2i9al9yfdX3BTqmdLUKv8uourIDQiE8GbDtGola801lzhYvHqHNg000op0jSZ1/ybcFXwY90GrYRbTyB6aWSjRdur0UhKyKWFAgOv/krnymkFVwoSkaQiWNmHj/4R8l/qEf+CGqbL3a8u0+WW3T+T9smNc71jNAKhA03UI5KuTNKtB4thYTKBAE3JYz9qMCZd67evpT9XWPUsb+W3xiT2nwt0LRMYBt/sYci3bs4hw3pm7ar0qOZrzIDEFRL7LmDBoQgcI079MUmyc0kahdKHAeWbhpdA8ry0z8jU+ffr1mua10ISdi4en3pUoQ/CW+vUBmMDfcEsvD9GjhdOapc3i5dzBtXAa3Fh0WOSLQr8VLhGx03a2od9uuDbndwCf/Y1LyC3ct6HavT66jUpMFGIZOLwNWdTaCOBm8CC1Hx0OpziiYm9uS7eM8YAC3i7yVEBCOEUrJBpuhEaocwSYjIr3tYN0uR90so3E8kT5ToKhCyo8B7k2Cbc1vT3WdtQgppwqlEsfupUSnMV/HeNo/hSmst1X3Q0oAcuO9ut4p0kmYjnG2JWvYvniPEBUgYD+z/02oinNV5PJvl73uaI5TWRLWYpqqA47r+M5K1tVOlCp+BphSaRSYNNDbYC7Cdux+hjqekCjgg8htwR1oAz1pZ2nr2gdOuSSJBw7scJaMSvHMw30RB40zOx0xqDhMKFuB8heS3Ni9G5UXCTOFy3EtkoJHRgLjYWiPZ29p63Kbw1gg+ShWcuBSBDZcKmdoqYzHWrCXmvTRIP8PtDPYguhKCMw= - DOMIFA_SECURITY_FILES_PRIVATE: >- - AgBjuf8/a3w4O9g0sBW6S6OtmazmqS4xILNMmQ2i9X8dHr/CZTnLQGGZ+u42uujlwB9vP5CHsxjw6Q//0UfGv5njEHprI4jmJ34bP7M3B8BxIcacaR9r9b7SjnsvXjE5VZi31bcu8uFdwcLXT+2wHtJXP7MrowOosjppANT5i9j9Lr+7EV4PE9it4oWyK9f3cZTI1q37+ljbtyuyRQnLp5M6ClVRcSvF9nW4GaIXm5HMIUY99bOk3Ue+7ouso0RHJeM4XfDeBnyLwy5dJn9zn6vQk0YSfOfCuwdB1oUgGrMxFgy1SLuL92CWrySlXPDI6N04fgMrznPqD69GXPHzl7qsJXl2TaVw7AgxE8BdmSPvb2UsQBhvHivp7S+R22EjDuh3d8Q/tQM+OdyopfT+CquCva3LEv4IhLSXuhp9OncOe+Jt43ZHhTDbqg5YZnsukfjMAc/IJodhJlZriRZ4oTm/7dmoIQ/Tvq6L6JI66pHpY3PcQTjuLMfoAdAVHg0f+nipM6hBS15+z4rhgbuCgR7CDe/AVZeJnGts3EVQb6Dne/wWTCMtCYufu0v2+6XJmfEJXRCUXVoIccP1j40WBCAJWhtJMYzeBogy1kgpY1jF4BGLfETExO/B+feqGT9ve1W4Mlbh+Q6QGk8lcm1yhtExHPCKiz/McWQgghKylh6/gyyBIp6yL7QTKrRX8rJXwUVzht6I0FwcbfexecZKwMmqCrJqa5vVK/KYyl7TWFbopA== - DOMIFA_SECURITY_FILES_IV: >- - AgCTyR/REzisCupRvUdVT08q/72dKX/Z4uqebEmO2ao7S+lN2ROGsi6runRnMU8nzM0SW7pV9WaLFh4emtGhhG6RSnbdcK/HJIMuDNlnp/NumCF8lwO9n86zqX9icz73WLIOGnOcXjctCPYdwp4hSpj8jQ5zZWaVaDipSw3czCfb/atIBE31pWBzDtYKeGc00D6TPlZgrdzZ6L8QBslS4y7B2afdbhkPCVcOd1vxQflgWpzVBMX/sVHOl1Hsg4I6t3xqP/eRBqahVz3ST19eLnPgGTbNxPu/0CdYjA676z3HwR+xZt0RVu1Xrc3WtmCEkUflt7/vUKvtmA9AQkQKdpVzSOX1XsouCz+gIspfr1eOmGwXDdR3qA9s9FbjjjvZZpa2SaLxxRRSEyd4LN4QgLWY84lKTbwQPMTJYEKb7dV2wtBfzFrmW5s1EnV/FUuOnEvCDpR714EwiyJDubqxUNSuinpFljYkUCWAuyWKE8wmuqxuXMwUes3IZMwGVbX+duPQy3i1u9Ek9Cp54nws/+tCHP7TlwfXoj471XHDc1r0mLni/bArTxIfP+KEHQ20Py2N5ytYgrmG8F8du0rydx1RajoISQljP2ag6tbcxp2hquy/MR0Rd5QLkl+elQUhCC6D5o0BrRkNffYU+s7jeoAsyPFmxfkxm0Mx+2c+RvkNgDGsl6OAwfOwzetR/qRkMC/xUuLU2GEE6xtsPU88G0ru DOMIFA_MAIL_SMTP_TIPIMAIL_HOST: >- AgCc3aP+NeiV7iqK4ieGWwAANtXRTaSKfXBXuhwUClC0Pshsdk8PwTXojqIcFAFIutNDBUVP/7rN8YAFrmNfL3go5LbizAsHFpjarc2kslUg/NEiz9vOUjWNzGzXTYrQKp0XXPaoSheQx86INhfnDbLO4Zmvo8p2qyJ0jKPR2SeCEate1mR4DGTg9kl9lly/qTxYRd12RDtVbsWq3iQC8gKGEeXMvoyvP4MKt0B3QLmgQ95zMbAC99EpTPGaxIdg010ilG8Bdqqp7QDp5HFoZYcYyHjMVLSxJH3I+Ra363jMAYsIq+bUgDQM6YjVXi105hHGg7fVpodz32gzk0HlRT3HhefAaCo5mgyUEQuH2Gf9SPrEjkqE2QaBmyYMWqkPdwJasELKuc6Aade3p2hiVopfsALj0k0yyOBUe4vwGHfwmNC+b0bmVULjvV7QlTG7sJYLuv1zhbsvU5WSg60ZG14hdyxS7RmyWxr7tGAM5dlDozNu+OFfSW7b38Ky1P6PaL63dpnYH+WTR7tsxJOb+I87dhWSorcLDtp3FnpV5Rwp6GUWkuhnFrZvYfphTYADgkBLCCY9Ech/MauN3woGeHtBO7NZgckmSLAj/KRkUoInbrMZcGUDBEG301aNhQtFuDlYXGTaLcFdK1rxAdZrsmEk5m1s+J7oAMs/Ykz7N4v381c/RMh4pC6/IOdEBGOjdWBtfGR3xJZjC+wp4f0EQaD4Vw== DOMIFA_MAIL_SMTP_TIPIMAIL_PORT: >- diff --git a/.kontinuous/env/prod/templates/backend.sealed-secret.yaml b/.kontinuous/env/prod/templates/backend.sealed-secret.yaml index 7db8fe77a7..cddf0071f7 100644 --- a/.kontinuous/env/prod/templates/backend.sealed-secret.yaml +++ b/.kontinuous/env/prod/templates/backend.sealed-secret.yaml @@ -13,9 +13,6 @@ spec: DOMIFA_MAIL_SMTP_TIPIMAIL_PASSWORD: AgBSQxl995jOV8UqEmdA2Hh4IP2f3Kfnw7yPXkWr6O6VCX1hcC6ZQwCAAt6ndhyqcq1qzmYcxy8Dg1g2BP3nllfB7ShVDl/fHHPh/tM2sbfhMw4hSMccERqrQmyNeqoONg1LWoQyb0A+uNFIJudsZJOBP1c1wdZJ7c4Ld+k2+XYK/NE1CynXMmPekY5K80rr6gNYdN7o6GHyTiPVuBrUkhkl/dKk+u4RjSP7zEhiqhgQ8Qi6+yfGQMkrRSYVtsUa2ghj7AnIsE6tCLo7LbNxN/gVgGXosNqnWUJ5aTjFlE7umsUrIUHBJ/g2tfYmNTbTvc/0S1Ha/i8EP226+ekhULILaIyQulfN/8kwa/xCJ+wEgQWCuH9NFACzITUXWMjwXHJSpzdu21owVPkpdR3X7PVx3AvYeutys4ufHPh7br1wg+hJKVYnwIFc+BYwv7iPsrcr0NonKNLpQH1IM3v2feZWwMo3umWyywZ/NwPx9+xgyXlgT+CcTH95ExrlmRqctUOalfkKoOxFA9+7FemjbbeVETg2NRhKHE7lS722xpwF6o1PsxucAxpqiUFehfMhzdmqJxhE8V7QMePWlUgH3QeIAXHmhYLIMmscoYR6EkuRj+gWEyJ90/OHGCir0u63yfOAA2nG/MrbdutrVEpCGpQTmbnPEYS8PPFjbaeFwAtuuBp3RomELa8ng1VR4q05pekhc+SWXyT4hTn8EkzWNi0Llg0vi8nTLuFlXZwfq5SVsg== DOMIFA_MAIL_SMTP_TIPIMAIL_PORT: AgA0IK6hbcUoKO1+H52wmYgrzoXIDLdi7ZYj4S38ypEcQqRUIUxKe4msrJFbLt0+xKjKJjfNzirlQIotIqkRtX0RWCNPmVJp4h2qMBLnQ2OB/Lt/y7lTNy6I34yFoKIsuHkyfWgEMVLRjr0dy31dtW2ycnoS3legC+FN/0RAXghAgbCGARHKzhRsWFE5k/qAlOxRnpgp1+FOAPDKAiBIa2HDOQWLF8g8lgewB8R50+e30t8l3QYpah6BfeBhsWsqnMmzdkuPxmEn1mirJGMwT2Qk0/yQRKSO3VW+GyexI+SkRg+TkIpkCKzTd5+ERvH2oNmkLGIxmon1NjwVCyQ/iyTh9088e8gUUcx0L6j0Psp8kiEwu8CsVQdpcI6Viidw9X7RvsgpWblG3iTNzfX1vM28v+uXZZf/obMP/FHUkJX9yc/Qx0dQjrEXGveSNslJL16dc9ar8Rea33zaRBhduZNQO2Ef9O1uWeUO9cCW16ZGJSVn//q7gS+gBA0wtYPzv9WHXgcLpTmfaMXHabLRm97nA7vmfeAQ5CVJIEjctTP6YHECtu3R3Zqt3r7b3CvSSDCJyXyw2Pv447jE9rhpKP8VDmCqF8ojMRX2QhOdZIRG09f8Yjz8XGn/9iqcKBe+4A0XJsX578ZmFRhJjXpnPrI3qfpPTDVnpy6+T3apxtlpqo3lclb+ETjokpDGwyHPo4IECLg= DOMIFA_MAIL_SMTP_TIPIMAIL_USER: AgAJ1VH26+QwSD6C/3RkrVqa1ZoSNyTnTIw1X1/JErOvpazT29OesnobDyEqttPP7vxBj9ZYqkXAr0wkhavkfqcbcQbOZjiNuc5fm3nepc9Jnuf3YwUVkrEBFmeJOhKSuEBpD6ofAF0NhFLTSs3uCoryyUj6/2Jf0G/aJhj3XzDPW5meWQohYSzAwOv0RtsM9CT1yCH+0WZotPicOCbJ2yWzNI5HOai3jwc/C66DTdohTqAjrmVdtkTWKd2gekm7vJNsCouSW2EwStUUMsyIaQB+hXkck2YNffRtYCnEueOjyzYzymP9neUQnJjYWbARLAkucwldFTQzzzUDhA+XcKvsjfZnNxMa8/MTjncMJoks5XrFigHmKrVZJWfHoRNV8IUxr0Mb0GhVX7Xc8A+TmGGJfsAXni3qcw4LnT37vesyM2r9Gs3nv3d7gIcMGk7+1LeYXnJEXdrN0ddW22CeAOqpmAM8QH4Y3YOrXCn0biLolyDNIYuFZY8pi59NyB63esEsXSv9MHt/1jdhkP3TgeqVKS/A8kQpXKPx1b0a1Lry8a1Bb6CANcz924/v59RmHFbI+pjyZXjnIcaYiP8IuHx2niEbj15Ouq6YBjYVCkLd1ZReKZD+fXc8r1Z3htG8iQr0gLxFQYcR4zreLkVyRucqowpncvAfQaFtDfLY5Ze9OmbhnFKEtNMGcMk7OBfEPT4zTRCj9OkbufYDxTkQdUsN8B59xvRpjQas4dDDJfRBTQ== - DOMIFA_SECURITY_FILES_IV: AgB9g8kxScl1CXyCtmEFjZYfLcmiUrlt+ablfB3rd4F2zl/5LC+EpJlLkDNrfF7TZEyMrbQ3Evsd5cXJ1ggRIg76FDn4lg1RyNk2PoazVnE6UZFjfRmeQ/bzuLgm5KaPOmcXSixEy+COeaGz72I7JmrqX8coNQ8emmcmoTYiiXOHV9Ewban71hJh+QnS5z86Zc5u3WdNer5R+JUNeSu9s7qQHxLHABr9W6nMLBza/Uo1GOMbETJPFRw76c96wCcIUsP+NAYmyUikMQstY5w3n7BOubBXaC0j4u7SI1zfgSX+tRrRoOF/lAAaDJmC/g0fxkkHBGSkfEAp/BPRVi1iRMODK8QH41wVCMDe/8mrJAlwFIdFTF1UwsOAIWlAcXa3CLdkPkOvxbrczB82cAi7CagwYFk6QEHlZDeKT3J4ienXE/Om9M+ZcC84sbxafMKzBbxC5I3L8xgQLqSFXpw9IoEVy6tyP9NJ5GP4M/NGbbcTyDhhPZpZPEl4aX9j3O/QrXcJgUSi9GstP/KFGJPjAXrHFrtlN9Hw3NemkeOIm8ELPKaHfOD1GnzZgjcfUOVB2BoAHcbJVTsz0g8xuqIzeegZbYkyoHQEm/lDuP2BOPij9UrqScTQt+U9lg9AhMkh4d1b7hD8NT1mutFa6c/pdQvUyqb592fSGSU44GWdEIlcOX0belNK5qrmwzoFi1tDO/dk7RxdwtFlDw7fDlvLuwgd - DOMIFA_SECURITY_FILES_IV_SECOURS: AgCBih1zhxILWB5SXkwliUgty7qsEadMHtfYILzZ27hbGZCmHQBsvV8mk87X9jTM3QsHL9G4iak/kh5MfKNI+2YCZGLLnUV2yYk09EjEqpDfur3RNqUaa0Tw9dmWcLGDgFipGhixKy+su/ngGloeIOWZx2eA6bOdi2HW2B2LdLTX0SU0kK6IFeAFfyMxK7rQJls0Wq/plkh0ueTxB0fXu5JAiY479W8GfyqYPd3LE29W+6Ldk5ojXNk24gEAW38hBCl+7Ozs4QzlPjzMt2+iOs5laA60v2D4zLBOhyPNHQRphUh19BoOGajOCIEN2Wud2WdLcDXJEkdhr3WlTcRtL1QSIghgEYFZB5qZSgpYv3tfTwMYNAbVkAC6WdMQ+D8H89jsNvxEgpz9dolkWgjkCzLzcvHWWak2cb/GGda/TSDBbm7CZLvD8+Xiw/izCHMX7OKbaVCZZz1r5CIBgbqYe7EBCJT+cGQmKBxy+uD+j6s/o/1zLfNnywHgtKI+WyBoCQbA+o4XFmtuupfCTzyW1q5SlFS3NowYmj45VfUxLln8oXFiSlt1XroWtSecv/Mo+krP8+8+9pDl98cUHldoyw+Ti5LyJ2oljnFCHrc90Tzs7yeS6sm5ZkJVpwllBXi5DsrfJIlKHX3wBGKqirbpGZN8T21CyyllnNOOzHlwz8gFioSvJ0CD928z95ilvRxgYfkdJowExzi7OapFleyJSPod - DOMIFA_SECURITY_FILES_PRIVATE: AgBYgfdfMe3M1M6DtI2FibsDDGebL9Z+EZafVEX7HCrkxTyxllTaxh7pbzIdc9O0aXCJ/tlCrB4fGsmdXnz2g2/sicOp8vdaH18kOeNgWLc/j3FFskbbH9hqplMT8lfaSW077TwVZee+MnJMKS1Dq+UUN6z1qMR/hPsLOS8AH+6bGMQ059yB0YBSopURfG/3p2FQD3l2lhc1shvHOzYw4haSS9swOUvjbkP/tj3AXe640nkFgqti4wQXWflYzplD7tGnuJCt+1lNFXs0BuPj2lBqeplGz8Jjb1M1qo3Z7aSTj2zthmGm+yfnEMA/MjXJrPYnNe7H4n1I32kOdxz7QwQmRKN95CBnC4NCMPlPYqjyMlVnY7ivJuCA/3zZjI2xCPa1YM4Ro9JeyD911xfHzbBMQD7sFbpi1yaFtlKIVdHjC5fEUp792gIdo7YxrEclpxFD396VxjahphgyJniEsP3u690Kbxn+zLBMwuP5uKnVzl6Ow3B3yQ9PB7A8b6sHtWjcKMmjX8ppIBZukgV482WIASuqtOJ4DbG7Ibmv8Z5pfgGa/WjDurMzXk34CQ2TTw/w0fPvEG+r3rjAwPH2FgsI3gfmCx4PVvEKuZ+ACmWYqiJEVeAp8x0ZMzZgpJME6gXHFS9mu5CSS75cHDdcPb5nABMEDKYlnqzqTWTXeMznnqyoL1g9iogmg3odphgxd7T15X7OUQRZWLzh/6W3naYBiIoCWWbBIC6Hq5OH4FA3Hw== DOMIFA_SECURITY_JWT_SECRET: AgBpRvftvZy8Celb3QJId2w1BhysbEyzbnE2qzcw5jDq2i3L+BvwFy+8UvniL2ZW95a5BYKYZTwa8ASSTtNUS30BpryQu5UkgOTE/Uqp6eurfevS6dfMKKMrY2WYBujD29QHBtXesANtm1Tf341of9pOYsk9L+Id6hWttvFmi3J6q35VQFKGvjtPG2NeRsf2Qvj3I040VZokeTpTYs2d4lc9B+/54/3dNxp9fGx62mIw12aO3pPwlMFRW8reU/MStz0EH/wU5arK82RhUNwBEmDnmcqlcy0dOMYQe1+TgXL7ntZtG8UrQtvMu05cmLby+KnEu+guFuOvLqIG+pNjHQy8m9JFDNidPJKtQkC1dvY3sZdwilwO9HI0tQjA2XnsmLtaRcKISaHn8bCoJdwY9QJGbA2LsFnVYJjJqqmfwnp8hHCTpWrcuG4vrXhwIJvAlKOZJuz7v7k/Klxd8bzqm+MtGBE1NlMpuAT0PgJjJXY6E7n9rGjLXnzZG4rphHAUMCOX2vOl6Wp35Sw4K4H7kExPpjNvE+MPy9QwCmtTPKxG68umFML1aLsbJi1vg8swO3FjOih4+5Gkh0l4gZB5g0iqsZZvPLAHiWAEskiQPwpJAOKc9mRdBq1FNxGYmJnkksVHrajSN6QnBJ4Kn+bSXnIy4SQVkLyDwWNszSD1NnFt6J+bmXI/fRxbj1IrMRuvJoCvB6X65QUTrBeLCm+AWlx96BbssCvon9k7Yw2PsEJLk2jn+6CGS/sIjhtj1PaewT33RbHLl9AjolJtqRpMP+HPyLEtzCQmf0ko8YcAld0wnimGZ0gSdvNexoEQC/glkr7PgcwuG46gMX9j+wGNpSu8581ghQm2VnxQ4CVdPeINfjtoucQTYWB6NAaMkeEo8gsfX1ZoLXlirauIMLLNI1o5w57PD44MgdIP0rWm6bqJBI+HjPHMekaqX1Q+Gnqgr1gpG8Jen90illkGvvc5Dh0hYK7c4nuoI360YO1PzJshj14ujIkOIFES7rKI6Y1yYlsNkbsNJiUrYF8XxdBFq7UA DOMIFA_SMS_API_KEY: AgBCd1+QFCvp3LYwbiuTRsU/jAkqSEkOdhuarS/0VDYVbkfIqMl5ZKMnz7j4gGw7tE9clUXMCtKLN8yQcMADj6s+RSNSQCJOlic2gwUyAxNB30In3hR5p5kcl3zVgEXW1w9KMBURNq46EFOYVxzrt6oxa83oWCamKc70BvnDGCLcGzExp5yk5ja+0/VLWA7k6+7ztoH8ndhEDMxmSUlwnLaf9o1Ts3X3Ts1d5e/H33nkmcj9oMckbOCy+xI/9PVlshHeucgJiDotzhvOIecHq9JCRGOqUQylQ8hZXVnuoG9do2wVD/0MjvTLLnmnw2V7VlfpPK4QaamXaOr3PjOLKC77uUndr3DmpBrNrl9vrN+d37+/WWe0BMSFCT2UdwXCOuFPeTKVUoHDb8PDIZTGxJtWL/H0rTZoc/QMXVqPrOCTwT+i/PNi6x989i2dFkGjXhACcLWBJPK0qi5qlPlwIZd3PE8UC/Z4gt0AQW7Rg5r6JhwRVzjCSCUvnvuzzZLu3Jz5CmG9plEexnzjRBGWhk4iX6OSUgjJ7XHhWeS7Sw4jP8+h3/qpKxmhczkVDANtf6AceLzC0F6bbWStMz7Sp8WxxK9PcQyjHl583UpdL+QTajlePBvyNG8l+pM1KWsKQzhfAq8iWorZl7TOZm0dLHl9QR0/FYc7XonQOG07yCWckwB+UmbGd/0He9N9JMOzIAkER3P82gCneBPyL+Xjp4Tt7SVFcoDU1VWAOzcmBCC8LlEUWATHKY7PsWRRnQ== DOMIFA_TIPIMAIL_FROM_EMAIL: AgB3LYXFxjfhxoTdaXG8Wu4DdHgmQuGNUkIvQP6vqkT9UKqqqECjlkMy1H9vk2A24ljE+t3T8+nZyptlvY7lb5xwLBhyBS4MsYL2/jERM4MEPOMPd9o90BhWjHaGNqZOR3QUDcyBKpo6xxFlhcQURtepgWKkXyTXJaS3jCG3NOtVP7QHrHIhWH0vvLy94E9C23gy572QXBiPvDw8iUOZC4uHrgddghnYxsOvhweO1D79qg0OEHLNAhKQyNEdDqrVnaup5oXpAa004HyTMrnKoJmc3ypptwVj+sVJAv4/Z0AZ54W46M10lx2rsNl16ZGto+fGjeK5jwjqoKDzBNOFycTzoL8BeH+qDmnwf4Lzs4tXMLP8QST/vAsa/bq2U9Ckn+0eYb4+nI5KEqCIh0qRhZwd7btmxxqUHnAymhO6FqGHBcXBb680+yCfLnpXuW4NaPZ4wnX1AHz2JSEdKMeWabU9ROItrqNpTzt4U0gJAKWDpw/ypaGkQaYP4LcAa1oTnrbBciOISUBmVKRzITX3gny/WzFsg/daQpMY+6h0pZ7UOuFGckv4qqt9Ann0hLjuC3cy/5EuFoMFOcI0rTOpVqKq6NI/GK0wg5IqaOcnDqSJE/4Nnf/dTe5OCrqfuxm3/qzZhF4IcuBJAFvoR29UErvcR5Cac87RJhFlrdfbMGqeDINSKPNyr6HoDVPS3tHn1eXLphf2+V1t4R1WxOYnJGzF9x786NEEzNWzCZ+AKMVUPfkMS08NrbI= diff --git a/_scripts/db/dumps/domifa_test.postgres.custom.gz b/_scripts/db/dumps/domifa_test.postgres.custom.gz index a8d8d318e391e66aaa589181f104dde256fa8db2..0202d3e816d462285327f15319f0dcae04b54e43 100644 GIT binary patch delta 5096 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 MZSJSd&?k}q0UJY(?*IS* delta 4916 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 DAAdfC diff --git a/_scripts/db/dumps/domifa_test.postgres.restore-data-only.sql b/_scripts/db/dumps/domifa_test.postgres.restore-data-only.sql index e7c64001a8..f47157e67e 100644 --- a/_scripts/db/dumps/domifa_test.postgres.restore-data-only.sql +++ b/_scripts/db/dumps/domifa_test.postgres.restore-data-only.sql @@ -147,8 +147,8 @@ COPY public.structure_doc (uuid, "createdAt", "updatedAt", version, id, label, " -- COPY public.usager_docs (uuid, "createdAt", "updatedAt", version, "usagerUUID", "structureId", "usagerRef", path, label, filetype, "createdBy", "encryptionContext", "encryptionVersion") FROM stdin; -2eb5e74d-4b25-4aa6-ad2a-7d963ae66072 2019-10-07 20:51:31.578+02 2022-06-28 22:52:59.282479+02 1 860ffa4c-88c4-4e1c-ad42-5a05cdf39830 1 1 373144a3d9d0b3f4c84bd527a5cff880.jpg CNI image/jpeg Patrick Roméro \N \N -a77729a9-1b28-4090-bda8-760590bff982 2019-10-07 20:53:32.922+02 2022-06-28 22:52:59.28757+02 1 4dcdcddc-fad2-4827-aac5-0acf1df7b5bc 1 5 8242ba1bc7f3c3971f761b6a347fc1c4.jpg Carte identité image/jpeg Patrick Roméro \N \N +2eb5e74d-4b25-4aa6-ad2a-7d963ae66072 2019-10-07 20:51:31.578+02 2022-06-28 22:52:59.282479+02 1 860ffa4c-88c4-4e1c-ad42-5a05cdf39830 1 1 373144a3d9d0b3f4c84bd527a5cff880.jpg CNI image/jpeg Patrick Roméro ffe17c48-7a1a-42c9-8494-0b72ca8b3686 0 +a77729a9-1b28-4090-bda8-760590bff982 2019-10-07 20:53:32.922+02 2022-06-28 22:52:59.28757+02 1 4dcdcddc-fad2-4827-aac5-0acf1df7b5bc 1 5 8242ba1bc7f3c3971f761b6a347fc1c4.jpg Carte identité image/jpeg Patrick Roméro ffe17c48-7a1a-42c9-8494-0b72ca8b3686 0 \. @@ -230,7 +230,7 @@ f6b20e00-77e7-46e6-b48d-8cca69161042 2020-11-17 14:32:22.193+01 2021-12-06 16:26 d19ece1f-d32b-498c-9427-eb12b1251163 2020-11-17 14:26:29.482634+01 2020-11-17 14:26:29.490297+01 2 s3-facteur@yopmail.com \N 4 \N Test $2a$10$3yXcVfWYOWsI/KzAwZ0BrOay1Dp/ZOF5RjhLL0QA2Pt7gQVg2U86u Facteur facteur 3 {"guide": false, "import": false} \N t \N b0140303-79e3-436c-9c41-1eaefeeaed6e 2020-11-17 14:23:20.248011+01 2022-03-09 00:20:21.36073+01 9 s1-gestionnaire@yopmail.com \N 3 2022-03-09 00:20:21.356+01 Smith $2a$10$3yXcVfWYOWsI/KzAwZ0BrOay1Dp/ZOF5RjhLL0QA2Pt7gQVg2U86u Peter responsable 1 {"guide": false, "import": false} \N t \N 343b62db-6c85-4896-b994-18c8c89b710f 2022-03-17 17:25:53.798318+01 2022-03-23 22:08:39.505536+01 36 s5-admin@yopmail.com \N 11 2022-03-23 22:08:39.502+01 Pali $2a$10$/Jn6nqdRG.f.OVDphuCbCeCDCy34sKBucgkLmqL2lSwzjSuexFgX. Mauricette admin 5 {"guide": false, "import": false} 2022-03-17 17:25:53.78+01 t \N -da01f451-9c4f-4f6c-98bb-c635277e33e7 2020-11-17 14:18:47.658346+01 2023-06-07 15:26:32.903173+02 389 s1-admin@yopmail.com \N 1 2023-06-07 15:26:32.894+02 Roméro $2a$10$3yXcVfWYOWsI/KzAwZ0BrOay1Dp/ZOF5RjhLL0QA2Pt7gQVg2U86u Patrick admin 1 {"guide": false, "import": false} \N t 2023-02-14 18:33:51.261+01 +da01f451-9c4f-4f6c-98bb-c635277e33e7 2020-11-17 14:18:47.658346+01 2023-09-05 23:50:23.454502+02 390 s1-admin@yopmail.com \N 1 2023-09-05 23:50:23.453+02 Roméro $2a$10$3yXcVfWYOWsI/KzAwZ0BrOay1Dp/ZOF5RjhLL0QA2Pt7gQVg2U86u Patrick admin 1 {"guide": false, "import": false} \N t 2023-02-14 18:33:51.261+01 \. diff --git a/_scripts/db/dumps/domifa_test.postgres.truncate-restore-data-only.sql b/_scripts/db/dumps/domifa_test.postgres.truncate-restore-data-only.sql index 148e023ea9..a16ad24f04 100644 --- a/_scripts/db/dumps/domifa_test.postgres.truncate-restore-data-only.sql +++ b/_scripts/db/dumps/domifa_test.postgres.truncate-restore-data-only.sql @@ -173,8 +173,8 @@ COPY public.structure_doc (uuid, "createdAt", "updatedAt", version, id, label, " -- COPY public.usager_docs (uuid, "createdAt", "updatedAt", version, "usagerUUID", "structureId", "usagerRef", path, label, filetype, "createdBy", "encryptionContext", "encryptionVersion") FROM stdin; -2eb5e74d-4b25-4aa6-ad2a-7d963ae66072 2019-10-07 20:51:31.578+02 2022-06-28 22:52:59.282479+02 1 860ffa4c-88c4-4e1c-ad42-5a05cdf39830 1 1 373144a3d9d0b3f4c84bd527a5cff880.jpg CNI image/jpeg Patrick Roméro \N \N -a77729a9-1b28-4090-bda8-760590bff982 2019-10-07 20:53:32.922+02 2022-06-28 22:52:59.28757+02 1 4dcdcddc-fad2-4827-aac5-0acf1df7b5bc 1 5 8242ba1bc7f3c3971f761b6a347fc1c4.jpg Carte identité image/jpeg Patrick Roméro \N \N +2eb5e74d-4b25-4aa6-ad2a-7d963ae66072 2019-10-07 20:51:31.578+02 2022-06-28 22:52:59.282479+02 1 860ffa4c-88c4-4e1c-ad42-5a05cdf39830 1 1 373144a3d9d0b3f4c84bd527a5cff880.jpg CNI image/jpeg Patrick Roméro ffe17c48-7a1a-42c9-8494-0b72ca8b3686 0 +a77729a9-1b28-4090-bda8-760590bff982 2019-10-07 20:53:32.922+02 2022-06-28 22:52:59.28757+02 1 4dcdcddc-fad2-4827-aac5-0acf1df7b5bc 1 5 8242ba1bc7f3c3971f761b6a347fc1c4.jpg Carte identité image/jpeg Patrick Roméro ffe17c48-7a1a-42c9-8494-0b72ca8b3686 0 \. @@ -256,7 +256,7 @@ f6b20e00-77e7-46e6-b48d-8cca69161042 2020-11-17 14:32:22.193+01 2021-12-06 16:26 d19ece1f-d32b-498c-9427-eb12b1251163 2020-11-17 14:26:29.482634+01 2020-11-17 14:26:29.490297+01 2 s3-facteur@yopmail.com \N 4 \N Test $2a$10$3yXcVfWYOWsI/KzAwZ0BrOay1Dp/ZOF5RjhLL0QA2Pt7gQVg2U86u Facteur facteur 3 {"guide": false, "import": false} \N t \N b0140303-79e3-436c-9c41-1eaefeeaed6e 2020-11-17 14:23:20.248011+01 2022-03-09 00:20:21.36073+01 9 s1-gestionnaire@yopmail.com \N 3 2022-03-09 00:20:21.356+01 Smith $2a$10$3yXcVfWYOWsI/KzAwZ0BrOay1Dp/ZOF5RjhLL0QA2Pt7gQVg2U86u Peter responsable 1 {"guide": false, "import": false} \N t \N 343b62db-6c85-4896-b994-18c8c89b710f 2022-03-17 17:25:53.798318+01 2022-03-23 22:08:39.505536+01 36 s5-admin@yopmail.com \N 11 2022-03-23 22:08:39.502+01 Pali $2a$10$/Jn6nqdRG.f.OVDphuCbCeCDCy34sKBucgkLmqL2lSwzjSuexFgX. Mauricette admin 5 {"guide": false, "import": false} 2022-03-17 17:25:53.78+01 t \N -da01f451-9c4f-4f6c-98bb-c635277e33e7 2020-11-17 14:18:47.658346+01 2023-06-07 15:26:32.903173+02 389 s1-admin@yopmail.com \N 1 2023-06-07 15:26:32.894+02 Roméro $2a$10$3yXcVfWYOWsI/KzAwZ0BrOay1Dp/ZOF5RjhLL0QA2Pt7gQVg2U86u Patrick admin 1 {"guide": false, "import": false} \N t 2023-02-14 18:33:51.261+01 +da01f451-9c4f-4f6c-98bb-c635277e33e7 2020-11-17 14:18:47.658346+01 2023-09-05 23:50:23.454502+02 390 s1-admin@yopmail.com \N 1 2023-09-05 23:50:23.453+02 Roméro $2a$10$3yXcVfWYOWsI/KzAwZ0BrOay1Dp/ZOF5RjhLL0QA2Pt7gQVg2U86u Patrick admin 1 {"guide": false, "import": false} \N t 2023-02-14 18:33:51.261+01 \. diff --git a/packages/backend/.env.preset/local-dev.preset.env b/packages/backend/.env.preset/local-dev.preset.env index d654c93d80..d5f5107966 100644 --- a/packages/backend/.env.preset/local-dev.preset.env +++ b/packages/backend/.env.preset/local-dev.preset.env @@ -20,10 +20,6 @@ DOMIFA_SMS_ENABLE=false DOMIFA_SWAGGER_ENABLE=true -# default file encryption keys (not critical locally) -DOMIFA_SECURITY_FILES_IV=gHSEyi222Nx5iwk7gF3vYxHX7aHki2XmuHqZq4pYF29xfBBuUE1rc2gv3wdU3DVW -DOMIFA_SECURITY_FILES_IV_SECOURS=gHSEyi222Nx5iwk7gF3vYxHX7aHki2XmuHqZq4pYF29xfBBuUE1rc2gv3wdU3DVW -DOMIFA_SECURITY_FILES_PRIVATE=sXsQ4eT75rt4QcgJpMDvlTUzgxqlJIPX7psHCKDSUbNvIE1K4ykqrUssJW5v2jwr # POSTGRES_HOST=postgres POSTGRES_HOST=localhost diff --git a/packages/backend/package.json b/packages/backend/package.json index efbecda86f..9e5d246dbd 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -12,12 +12,10 @@ "db:dev:migrate-down:last": "npx ts-node -r tsconfig-paths/register --transpile-only src/run-migrate-down-last.ts", "db:dev:migrate-redo": "npx ts-node -r tsconfig-paths/register --transpile-only src/run-migrate-up-redo.ts", "db:dev:migrate-up": "npx ts-node -r tsconfig-paths/register --transpile-only src/run-migrate-up.ts", - "db:dev:migrate-files": "npx ts-node -r tsconfig-paths/register --transpile-only src/run-migrate-files.ts | pino-pretty --singleLine", "db:dev:create": "typeorm-ts-node-commonjs migration:create ./src/_migrations/manual-migration", "db:prod:data-anonymize": "node dist/run-data-anonymization.js ", "db:prod:migrate-down:last": "node dist/run-migrate-down-last.js", "db:prod:migrate-up": "node dist/run-migrate-up.js", - "db:prod:migrate-files": "node dist/run-migrate-files.js", "db:test:migrate-down:last": "ENV_FILE=tests-local npx ts-node -r tsconfig-paths/register --transpile-only src/run-migrate-down-last.ts", "db:test:migrate-redo": "ENV_FILE=tests-local npx ts-node -r tsconfig-paths/register --transpile-only src/run-migrate-up-redo.ts", "db:test:migrate-up": "ENV_FILE=tests-local npx ts-node -r tsconfig-paths/register --transpile-only src/run-migrate-up.ts", diff --git a/packages/backend/src/_migrations/1693919222559-delete-corrupted-files-migration.ts b/packages/backend/src/_migrations/1693919222559-delete-corrupted-files-migration.ts new file mode 100644 index 0000000000..f925b5d076 --- /dev/null +++ b/packages/backend/src/_migrations/1693919222559-delete-corrupted-files-migration.ts @@ -0,0 +1,19 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class ManualMigration1693919222559 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + const docsToDelete = await queryRunner.query( + `SELECT COUNT(uuid) FROM "usager_docs" where "encryptionContext" IS NULL` + ); + + console.log(docsToDelete[0]?.count + " docs to delete"); + await queryRunner.query( + `DELETE FROM "usager_docs" where "encryptionContext" IS NULL` + ); + } + + // eslint-disable-next-line @typescript-eslint/no-unused-vars + public async down(_queryRunner: QueryRunner): Promise { + // Nothing + } +} diff --git a/packages/backend/src/config/domifaConfig.service.spec.ts b/packages/backend/src/config/domifaConfig.service.spec.ts index c97b34fea2..601b6d39cb 100644 --- a/packages/backend/src/config/domifaConfig.service.spec.ts +++ b/packages/backend/src/config/domifaConfig.service.spec.ts @@ -22,9 +22,6 @@ describe("loadConfig", () => { expect(config.apps.backendUrl).toBeDefined(); expect(config.apps.portailUsagersUrl).toBeDefined(); - expect(config.security.files.iv).toBeDefined(); - expect(config.security.files.private).toBeDefined(); - expect(config.postgres.host).toBeDefined(); expect(config.postgres.port).toBeDefined(); expect(config.postgres.logging).toEqual(["warn"]); @@ -58,9 +55,6 @@ describe("loadConfig", () => { expect(config.apps.backendUrl).toBeDefined(); expect(config.apps.portailUsagersUrl).toBeDefined(); - expect(config.security.files.iv).toBeDefined(); - expect(config.security.files.private).toBeDefined(); - expect(config.postgres.host).toBeDefined(); expect(config.postgres.port).toBeDefined(); expect(config.postgres.logging).toEqual(["warn", "migration"]); @@ -108,9 +102,6 @@ describe("loadConfig", () => { expect(config.envId).toEqual("prod"); - expect(config.security.files.iv).toBeDefined(); - expect(config.security.files.private).toBeDefined(); - expect(config.postgres.host).toBeDefined(); expect(config.postgres.port).toBeDefined(); expect(config.postgres.logging).toEqual(false); diff --git a/packages/backend/src/config/domifaConfig.service.ts b/packages/backend/src/config/domifaConfig.service.ts index e0baa43181..8aad16718e 100644 --- a/packages/backend/src/config/domifaConfig.service.ts +++ b/packages/backend/src/config/domifaConfig.service.ts @@ -332,18 +332,9 @@ export function loadConfig(x: Partial): DomifaConfig { function parseSecurityConfig(x: Partial): DomifaConfigSecurity { return { - files: { - iv: configParser.parseString(x, "DOMIFA_SECURITY_FILES_IV"), - ivSecours: configParser.parseString( - x, - "DOMIFA_SECURITY_FILES_IV_SECOURS", - { required: false } - ), - private: configParser.parseString(x, "DOMIFA_SECURITY_FILES_PRIVATE"), - mainSecret: decodeMainSecret( - configParser.parseString(x, "DOMIFA_SECURITY_FILES_MAIN_SECRET") - ), - }, + mainSecret: decodeMainSecret( + configParser.parseString(x, "DOMIFA_SECURITY_FILES_MAIN_SECRET") + ), jwtSecret: configParser.parseString(x, "DOMIFA_SECURITY_JWT_SECRET"), }; } diff --git a/packages/backend/src/config/model/DomifaConfig.type.ts b/packages/backend/src/config/model/DomifaConfig.type.ts index 6265c2d33f..9b0d2fe98b 100644 --- a/packages/backend/src/config/model/DomifaConfig.type.ts +++ b/packages/backend/src/config/model/DomifaConfig.type.ts @@ -4,12 +4,7 @@ import { DomifaConfigPostgres } from "./DomifaConfigPostgres.type"; import { DomifaEnvId } from "./DomifaEnvId.type"; export type DomifaConfigSecurity = { - files: { - mainSecret: Uint8Array; // DOMIFA_SECURITY_FILES_MAIN_SECRET - iv: string; // DOMIFA_SECURITY_FILES_IV - ivSecours: string; // DOMIFA_SECURITY_FILES_IV_SECOURS - private: string; // DOMIFA_SECURITY_FILES_PRIVATE - }; + mainSecret: Uint8Array; // DOMIFA_SECURITY_FILES_MAIN_SECRET jwtSecret: string; // DOMIFA_SECURITY_JWT_SECRET }; diff --git a/packages/backend/src/config/model/DomifaEnv.type.ts b/packages/backend/src/config/model/DomifaEnv.type.ts index 3ae6f210eb..a0d7442a93 100644 --- a/packages/backend/src/config/model/DomifaEnv.type.ts +++ b/packages/backend/src/config/model/DomifaEnv.type.ts @@ -1,11 +1,7 @@ export type DomifaEnv = { DOMIFA_ENV_PRESET: string; DOMIFA_ENV_PRIORITY: "files" | "process.env"; - - DOMIFA_SECURITY_FILES_IV: string; DOMIFA_SECURITY_FILES_MAIN_SECRET: string; - DOMIFA_SECURITY_FILES_IV_SECOURS: string; // TEMP VALUE : supprimer une fois la réencryption réalisée - DOMIFA_SECURITY_FILES_PRIVATE: string; DOMIFA_FRONTEND_URL: string; DOMIFA_PORTAIL_USAGERS_URL: string; DOMIFA_PORTAIL_ADMINS_URL: string; diff --git a/packages/backend/src/run-migrate-files.ts b/packages/backend/src/run-migrate-files.ts deleted file mode 100644 index b5eca444a7..0000000000 --- a/packages/backend/src/run-migrate-files.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { bootstrapApplication, tearDownApplication } from "./app.bootstrap"; -import { migrateOldFiles } from "./usagers/utils"; -import { appLogger } from "./util"; - -(async () => { - appLogger.warn(`[${__filename}] Starting app...`); - const { app, postgresTypeormConnection } = await bootstrapApplication(); - try { - appLogger.warn(`[${__filename}] Starting migration of old files ...`); - await migrateOldFiles(); - } catch (error) { - appLogger.error(`[${__filename}] Error running migration old files`, { - error, - sentry: true, - }); - } finally { - appLogger.warn(`[${__filename}] Closing app...`); - await tearDownApplication({ app, postgresTypeormConnection }); - process.exit(0); - } -})(); diff --git a/packages/backend/src/usagers/controllers/usager-docs.controller.ts b/packages/backend/src/usagers/controllers/usager-docs.controller.ts index cabcfd61d1..dbdaa57ec9 100644 --- a/packages/backend/src/usagers/controllers/usager-docs.controller.ts +++ b/packages/backend/src/usagers/controllers/usager-docs.controller.ts @@ -33,9 +33,8 @@ import { appLogger } from "../../util"; import { compressAndResizeImage, deleteFile, - getFileDir, - getFilePath, - getNewFileDir, + getUsagerFilePath, + getUsagerFilesDir, randomName, validateUpload, } from "../../util/file-manager/FileManager"; @@ -43,15 +42,9 @@ import { UsagerDoc, UserStructureAuthenticated } from "../../_common/model"; import { AppLogsService } from "../../modules/app-logs/app-logs.service"; import { UploadUsagerDocDto } from "../dto"; -import { - createReadStream, - createWriteStream, - pathExists, - stat, -} from "fs-extra"; -import { join } from "path"; +import { createReadStream, createWriteStream, pathExists } from "fs-extra"; -import crypto, { createDecipheriv } from "node:crypto"; +import crypto from "node:crypto"; import { ExpressRequest } from "../../util/express"; import { decryptFile, @@ -86,13 +79,17 @@ export class UsagerDocsController { callback(null, true); }, storage: diskStorage({ - destination: (req: any, _file: Express.Multer.File, cb: any) => { + destination: ( + req: any, + _file: Express.Multer.File, + callback: (error: Error | null, destination: string) => void + ) => { (async () => { - const dir = await getNewFileDir( + const dir = await getUsagerFilesDir( req.user.structure.uuid, req.usager.uuid ); - cb(null, dir); + callback(null, dir); })(); }, filename: ( @@ -167,18 +164,11 @@ export class UsagerDocsController { .json({ message: "DOC_NOT_FOUND" }); } - let filePath = ""; - - if (doc.encryptionContext) { - filePath = await getFilePath( - user.structure.uuid, - currentUsager.uuid, - doc.path + ".sfe" - ); - } else { - const sourceFileDir = getFileDir(doc.structureId, doc.usagerRef); - filePath = join(sourceFileDir, doc.path + ".encrypted"); - } + const filePath = await getUsagerFilePath( + user.structure.uuid, + currentUsager.uuid, + doc.path + ".sfe" + ); await deleteFile(filePath); @@ -228,94 +218,31 @@ export class UsagerDocsController { structureId: currentUsager.structureId, }); - if (!doc) { + if (!doc?.encryptionContext || doc?.encryptionVersion !== 0) { return res .status(HttpStatus.BAD_REQUEST) .json({ message: "DOC_NOT_FOUND" }); } - if (doc.encryptionContext) { - const mainSecret = domifaConfig().security.files.mainSecret; - - const encryptedFilePath = await getFilePath( - user.structure.uuid, - doc.usagerUUID, - doc.path + ".sfe" - ); - - if (doc.encryptionVersion !== 0) { - return res - .status(HttpStatus.INTERNAL_SERVER_ERROR) - .json({ message: "CANNOT_UPLOAD_FILE_MAIN" }); - } + const mainSecret = domifaConfig().security.mainSecret; - try { - return pipeline( - // note: encryptedFilePath should end with .sfe, not .encrypted, to prepare for phase 3. - createReadStream(encryptedFilePath), - decryptFile(mainSecret, doc.encryptionContext), - res - ); - } catch (e) { - return res - .status(HttpStatus.INTERNAL_SERVER_ERROR) - .json({ message: "CANNOT_UPLOAD_FILE" }); - } - } + const encryptedFilePath = await getUsagerFilePath( + user.structure.uuid, + doc.usagerUUID, + doc.path + ".sfe" + ); - // @deprecated - else { - // @deprecated: delete this after migration - const sourceFileDir = getFileDir( - currentUsager.structureId, - currentUsager.ref + try { + return pipeline( + // note: encryptedFilePath should end with .sfe, not .encrypted, to prepare for phase 3. + createReadStream(encryptedFilePath), + decryptFile(mainSecret, doc.encryptionContext), + res ); - // Encrypted file source - const encryptedFilePath = join(sourceFileDir, doc.path + ".encrypted"); - - // FIX : vieilles données pas encore encryptés - if (!(await pathExists(encryptedFilePath))) { - const oldFilePath = join(sourceFileDir, doc.path); - if (!(await pathExists(oldFilePath))) { - appLogger.error("Error reading usager document", { - sentry: true, - context: { - oldFilePath, - }, - }); - return res - .status(HttpStatus.BAD_REQUEST) - .json({ message: "DOC_NOT_FOUND" }); - } - - try { - await this.saveEncryptedFile(user, doc); - } catch (e) { - return res - .status(HttpStatus.INTERNAL_SERVER_ERROR) - .json({ message: "CANNOT_OPEN_FILE" }); - } - } - - // TEMP FIX : Utiliser la deuxième clé d'encryptage générée le 30 juin - // A supprimer une fois que les fichiers seront de nouveaux regénérés - const docInfos = await stat(encryptedFilePath); - - const iv = - docInfos.mtime < new Date("2021-06-30T23:01:01.113Z") - ? domifaConfig().security.files.ivSecours - : domifaConfig().security.files.iv; - - try { - const key = domifaConfig().security.files.private; - const decipher = createDecipheriv("aes-256-cfb", key, iv); - - return createReadStream(encryptedFilePath).pipe(decipher).pipe(res); - } catch (e) { - return res - .status(HttpStatus.INTERNAL_SERVER_ERROR) - .json({ message: "CANNOT_OPEN_FILE" }); - } + } catch (e) { + return res + .status(HttpStatus.INTERNAL_SERVER_ERROR) + .json({ message: "CANNOT_UPLOAD_FILE" }); } } @@ -324,7 +251,7 @@ export class UsagerDocsController { user: UserStructureAuthenticated, usagerDoc: UsagerDoc ): Promise { - const sourceFilePath = await getFilePath( + const sourceFilePath = await getUsagerFilePath( user.structure.uuid, usagerDoc.usagerUUID, usagerDoc.path @@ -337,7 +264,7 @@ export class UsagerDocsController { } try { - const mainSecret = domifaConfig().security.files.mainSecret; + const mainSecret = domifaConfig().security.mainSecret; if ( usagerDoc.filetype === "image/jpeg" || usagerDoc.filetype === "image/png" diff --git a/packages/backend/src/usagers/utils/index.ts b/packages/backend/src/usagers/utils/index.ts deleted file mode 100644 index 4a80152418..0000000000 --- a/packages/backend/src/usagers/utils/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -// @index('./*', f => `export * from '${f.path}'`) -export * from "./migrate-files-utils"; diff --git a/packages/backend/src/usagers/utils/migrate-files-utils.ts b/packages/backend/src/usagers/utils/migrate-files-utils.ts deleted file mode 100644 index 60928b869d..0000000000 --- a/packages/backend/src/usagers/utils/migrate-files-utils.ts +++ /dev/null @@ -1,198 +0,0 @@ -import { encryptFile } from "@socialgouv/streaming-file-encryption"; -import { createDecipheriv, randomUUID } from "crypto"; -import { - pathExists, - stat, - createReadStream, - createWriteStream, -} from "fs-extra"; -import { pipeline } from "node:stream/promises"; -import { join } from "path"; -import { domifaConfig } from "../../config"; -import { structureRepository, usagerDocsRepository } from "../../database"; -import { getFileDir, compressAndResizeImage, getFilePath } from "../../util"; -import { IsNull } from "typeorm"; -import { Structure, UsagerDoc } from "../../_common/model"; - -export const migrateOldFiles = async () => { - while ((await countMigratedStructures()) > 0) { - let totalCount = 0; - - const structure = await structureRepository.findOneBy({ - filesUpdated: false, - }); - - console.info( - "Start migration for structure N*" + structure.id + " - " + new Date() - ); - - const oldFiles: Pick< - UsagerDoc, - "structureId" | "uuid" | "usagerRef" | "path" | "usagerUUID" | "filetype" - >[] = await usagerDocsRepository.find({ - where: { - structureId: structure.id, - encryptionContext: IsNull(), - }, - select: { - structureId: true, - uuid: true, - usagerRef: true, - path: true, - usagerUUID: true, - filetype: true, - }, - }); - - totalCount = oldFiles.length; - let cpt = 1; - - for (const doc of oldFiles) { - console.info( - `>>> Migration structure N* ${structure.id} : ${cpt++} / ${totalCount}` - ); - await decryptOldFile(doc, structure); - } - - console.info( - "End of migration for structure N*" + structure.id + " - " + new Date() - ); - - await structureRepository.update( - { uuid: structure.uuid }, - { - filesUpdated: true, - } - ); - } -}; - -export const decryptOldFile = async ( - usagerDoc: Pick< - UsagerDoc, - "structureId" | "uuid" | "usagerRef" | "path" | "usagerUUID" | "filetype" - >, - structure: Structure -): Promise => { - const encryptionContext = randomUUID(); - const mainSecret = domifaConfig().security.files.mainSecret; - const key = domifaConfig().security.files.private; - - // Anciens dossiers et fichiers - const sourceFileDir = getFileDir(usagerDoc.structureId, usagerDoc.usagerRef); - let sourceFilePath = join(sourceFileDir, usagerDoc.path + ".encrypted"); - - // Le fichier de sortie ne sera pas au même endroit que la source - - const outputFilePathSfe = await getFilePath( - structure.uuid, - usagerDoc.usagerUUID, - usagerDoc.path + ".sfe" - ); - - if (await pathExists(outputFilePathSfe)) { - // fichier déjà chiffré, DB pas à jour ? - console.error(`Fichier ${outputFilePathSfe} déjà existant`); - } else if (await pathExists(sourceFilePath)) { - // fichier déjà chiffré avec ancienne methode - // TEMP FIX : Utiliser la deuxième clé d'encryptage générée le 30 juin - // A supprimer une fois que les fichiers seront de nouveaux regénérés - const docInfos = await stat(sourceFilePath); - - const iv = - docInfos.mtime < new Date("2021-06-30T23:01:01.113Z") - ? domifaConfig().security.files.ivSecours - : domifaConfig().security.files.iv; - - try { - const decipher = createDecipheriv("aes-256-cfb", key, iv); - if ( - usagerDoc.filetype === "image/jpeg" || - usagerDoc.filetype === "image/png" - ) { - await pipeline( - createReadStream(sourceFilePath), - decipher, - compressAndResizeImage(usagerDoc), - encryptFile(mainSecret, encryptionContext), - createWriteStream(outputFilePathSfe) - ); - } else { - await pipeline( - createReadStream(sourceFilePath), - decipher, - encryptFile(mainSecret, encryptionContext), - createWriteStream(outputFilePathSfe) - ); - } - - await usagerDocsRepository.update( - { uuid: usagerDoc.uuid }, - { encryptionContext, encryptionVersion: 0 } - ); - } catch (e) { - console.error("ENCRYPTED FILE"); - console.error(e); - console.error({ usagerDoc }); - } - } else { - // Dernier cas : fichier jamais chiffré - sourceFilePath = join(sourceFileDir, usagerDoc.path); - if (await pathExists(sourceFilePath)) { - { - try { - if ( - usagerDoc.filetype === "image/jpeg" || - usagerDoc.filetype === "image/png" - ) { - await pipeline( - createReadStream(sourceFilePath), - compressAndResizeImage(usagerDoc), - encryptFile(mainSecret, encryptionContext), - createWriteStream(outputFilePathSfe) - ); - } else { - await pipeline( - createReadStream(sourceFilePath), - encryptFile(mainSecret, encryptionContext), - createWriteStream(outputFilePathSfe) - ); - } - - // MAJ DB - await usagerDocsRepository.update( - { - uuid: usagerDoc.uuid, - }, - { - encryptionContext, - encryptionVersion: 0, - } - ); - } catch (e) { - console.error("UNENCRYPTED FILE"); - console.error(e); - console.error({ usagerDoc }); - } - } - } else { - // fichier source non trouvé - console.error( - "File not found for usager N*" + - usagerDoc.usagerRef + - " from structure n*" + - usagerDoc.structureId - ); - - console.error({ usagerDoc }); - } - } -}; - -function countMigratedStructures(): Promise { - return structureRepository.count({ - where: { - filesUpdated: false, - }, - }); -} diff --git a/packages/backend/src/util/file-manager/FileManager.ts b/packages/backend/src/util/file-manager/FileManager.ts index a1fb170bd9..3a03b21a76 100644 --- a/packages/backend/src/util/file-manager/FileManager.ts +++ b/packages/backend/src/util/file-manager/FileManager.ts @@ -64,12 +64,12 @@ export function validateUpload( return validFileMimeType && validFileExtension; } -export async function getFilePath( +export async function getUsagerFilePath( structureUUID: string, usagerUUID: string, fileName: string ): Promise { - const dir = await getNewFileDir(structureUUID, usagerUUID); + const dir = await getUsagerFilesDir(structureUUID, usagerUUID); return join(dir, fileName); } @@ -78,7 +78,7 @@ export function cleanPath(path: string): string { } // Les nouveaux fichiers seront stockés dans des dossiers reprenant les uuid et non les ID -export async function getNewFileDir( +export async function getUsagerFilesDir( structureUUID: string, usagerUUID: string ): Promise { @@ -91,15 +91,3 @@ export async function getNewFileDir( await ensureDir(dir); return dir; } - -// -// -// -// @deprecated: remove this function after migration -export function getFileDir(structureId: number, usagerRef: number): string { - return join( - domifaConfig().upload.basePath, - cleanPath(`${structureId}`), - cleanPath(`${usagerRef}`) - ); -} diff --git a/packages/frontend/src/app/modules/usager-profil/components/historiques/profil-historique-courriers/profil-historique-courriers.component.html b/packages/frontend/src/app/modules/usager-profil/components/historiques/profil-historique-courriers/profil-historique-courriers.component.html index 3df6b9f5a3..b2826cdabe 100644 --- a/packages/frontend/src/app/modules/usager-profil/components/historiques/profil-historique-courriers/profil-historique-courriers.component.html +++ b/packages/frontend/src/app/modules/usager-profil/components/historiques/profil-historique-courriers/profil-historique-courriers.component.html @@ -15,7 +15,7 @@

Historique des courriers

-
+

Aucune interaction enregistrée